mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			767 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			767 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* GtkToolkit.java -- Implements an AWT Toolkit using GTK for peers
 | |
|    Copyright (C) 1998, 1999, 2002, 2003, 2004, 2005, 2006, 2007
 | |
|    Free Software Foundation, Inc.
 | |
| 
 | |
| This file is part of GNU Classpath.
 | |
| 
 | |
| GNU Classpath is free software; you can redistribute it and/or modify
 | |
| it under the terms of the GNU General Public License as published by
 | |
| the Free Software Foundation; either version 2, or (at your option)
 | |
| any later version.
 | |
| 
 | |
| GNU Classpath is distributed in the hope that it will be useful, but
 | |
| WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| General Public License for more details.
 | |
| 
 | |
| You should have received a copy of the GNU General Public License
 | |
| along with GNU Classpath; see the file COPYING.  If not, write to the
 | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | |
| 02110-1301 USA.
 | |
| 
 | |
| Linking this library statically or dynamically with other modules is
 | |
| making a combined work based on this library.  Thus, the terms and
 | |
| conditions of the GNU General Public License cover the whole
 | |
| combination.
 | |
| 
 | |
| As a special exception, the copyright holders of this library give you
 | |
| permission to link this library with independent modules to produce an
 | |
| executable, regardless of the license terms of these independent
 | |
| modules, and to copy and distribute the resulting executable under
 | |
| terms of your choice, provided that you also meet, for each linked
 | |
| independent module, the terms and conditions of the license of that
 | |
| module.  An independent module is a module which is not derived from
 | |
| or based on this library.  If you modify this library, you may extend
 | |
| this exception to your version of the library, but you are not
 | |
| obligated to do so.  If you do not wish to do so, delete this
 | |
| exception statement from your version. */
 | |
| 
 | |
| 
 | |
| package gnu.java.awt.peer.gtk;
 | |
| 
 | |
| import gnu.classpath.Configuration;
 | |
| 
 | |
| import gnu.java.awt.AWTUtilities;
 | |
| import gnu.java.awt.EmbeddedWindow;
 | |
| import gnu.java.awt.dnd.GtkMouseDragGestureRecognizer;
 | |
| import gnu.java.awt.dnd.peer.gtk.GtkDragSourceContextPeer;
 | |
| import gnu.java.awt.peer.ClasspathFontPeer;
 | |
| import gnu.java.awt.peer.EmbeddedWindowPeer;
 | |
| 
 | |
| import java.awt.AWTException;
 | |
| import java.awt.Button;
 | |
| import java.awt.Canvas;
 | |
| import java.awt.Checkbox;
 | |
| import java.awt.CheckboxMenuItem;
 | |
| import java.awt.Choice;
 | |
| import java.awt.Component;
 | |
| import java.awt.Cursor;
 | |
| import java.awt.Dialog;
 | |
| import java.awt.Dimension;
 | |
| import java.awt.EventQueue;
 | |
| import java.awt.FileDialog;
 | |
| import java.awt.Font;
 | |
| import java.awt.FontMetrics;
 | |
| import java.awt.Frame;
 | |
| import java.awt.GraphicsDevice;
 | |
| import java.awt.GraphicsEnvironment;
 | |
| import java.awt.HeadlessException;
 | |
| import java.awt.Image;
 | |
| import java.awt.Label;
 | |
| import java.awt.List;
 | |
| import java.awt.Menu;
 | |
| import java.awt.MenuBar;
 | |
| import java.awt.MenuItem;
 | |
| import java.awt.Panel;
 | |
| import java.awt.Point;
 | |
| import java.awt.PopupMenu;
 | |
| import java.awt.PrintJob;
 | |
| import java.awt.Rectangle;
 | |
| import java.awt.ScrollPane;
 | |
| import java.awt.Scrollbar;
 | |
| import java.awt.TextArea;
 | |
| import java.awt.TextField;
 | |
| import java.awt.Window;
 | |
| import java.awt.datatransfer.Clipboard;
 | |
| import java.awt.dnd.DragGestureEvent;
 | |
| import java.awt.dnd.DragGestureListener;
 | |
| import java.awt.dnd.DragGestureRecognizer;
 | |
| import java.awt.dnd.DragSource;
 | |
| import java.awt.dnd.InvalidDnDOperationException;
 | |
| import java.awt.dnd.peer.DragSourceContextPeer;
 | |
| import java.awt.font.TextAttribute;
 | |
| import java.awt.im.InputMethodHighlight;
 | |
| import java.awt.image.ColorModel;
 | |
| import java.awt.image.DirectColorModel;
 | |
| import java.awt.image.ImageObserver;
 | |
| import java.awt.image.ImageProducer;
 | |
| import java.awt.peer.ButtonPeer;
 | |
| import java.awt.peer.CanvasPeer;
 | |
| import java.awt.peer.CheckboxMenuItemPeer;
 | |
| import java.awt.peer.CheckboxPeer;
 | |
| import java.awt.peer.ChoicePeer;
 | |
| import java.awt.peer.DialogPeer;
 | |
| import java.awt.peer.FileDialogPeer;
 | |
| import java.awt.peer.FontPeer;
 | |
| import java.awt.peer.FramePeer;
 | |
| import java.awt.peer.LabelPeer;
 | |
| import java.awt.peer.ListPeer;
 | |
| import java.awt.peer.MenuBarPeer;
 | |
| import java.awt.peer.MenuItemPeer;
 | |
| import java.awt.peer.MenuPeer;
 | |
| import java.awt.peer.MouseInfoPeer;
 | |
| import java.awt.peer.PanelPeer;
 | |
| import java.awt.peer.PopupMenuPeer;
 | |
| import java.awt.peer.RobotPeer;
 | |
| import java.awt.peer.ScrollPanePeer;
 | |
| import java.awt.peer.ScrollbarPeer;
 | |
| import java.awt.peer.TextAreaPeer;
 | |
| import java.awt.peer.TextFieldPeer;
 | |
| import java.awt.peer.WindowPeer;
 | |
| import java.io.InputStream;
 | |
| import java.net.URL;
 | |
| import java.util.HashMap;
 | |
| import java.util.LinkedHashMap;
 | |
| import java.util.Map;
 | |
| import java.util.Properties;
 | |
| 
 | |
| import javax.imageio.spi.IIORegistry;
 | |
| 
 | |
| /* This class uses a deprecated method java.awt.peer.ComponentPeer.getPeer().
 | |
|    This merits comment.  We are basically calling Sun's bluff on this one.
 | |
|    We think Sun has deprecated it simply to discourage its use as it is
 | |
|    bad programming style.  However, we need to get at a component's peer in
 | |
|    this class.  If getPeer() ever goes away, we can implement a hash table
 | |
|    that will keep up with every window's peer, but for now this is faster. */
 | |
| 
 | |
| public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
 | |
| {
 | |
|   static final Object GTK_LOCK;
 | |
| 
 | |
|   private static EventQueue q;
 | |
| 
 | |
|   static native void gtkInit(int portableNativeSync, Object lock);
 | |
| 
 | |
|   static native void gtkMain();
 | |
| 
 | |
|   static native void gtkQuit();
 | |
| 
 | |
|   /**
 | |
|    * Initializes field IDs that are used by native code.
 | |
|    */
 | |
|   private static native void initIDs();
 | |
| 
 | |
|   /**
 | |
|    * True when the field IDs are already initialized, false otherwise.
 | |
|    */
 | |
|   private static boolean initializedGlobalIDs = false;
 | |
| 
 | |
|   /**
 | |
|    * Initializes some global fieldIDs for use in the native code. This is
 | |
|    * called by a couple of classes in the GTK peers to ensure that
 | |
|    * some necessary stuff is loaded.
 | |
|    */
 | |
|   static synchronized void initializeGlobalIDs()
 | |
|   {
 | |
|     if (! initializedGlobalIDs)
 | |
|       {
 | |
|         initIDs();
 | |
|         initializedGlobalIDs = true;
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   static
 | |
|   {
 | |
|     if (true) // GCJ LOCAL
 | |
|       {
 | |
|         System.loadLibrary("gtkpeer");
 | |
|       }
 | |
| 
 | |
|     /**
 | |
|      * Gotta do that first.
 | |
|      */
 | |
|     initializeGlobalIDs();
 | |
| 
 | |
|     int portableNativeSync;
 | |
|     String portNatSyncProp =
 | |
|       System.getProperty("gnu.classpath.awt.gtk.portable.native.sync");
 | |
| 
 | |
|     if (portNatSyncProp == null)
 | |
|       portableNativeSync = -1;  // unset
 | |
|     else if (Boolean.valueOf(portNatSyncProp).booleanValue())
 | |
|       portableNativeSync = 1;   // true
 | |
|     else
 | |
|       portableNativeSync = 0;   // false
 | |
| 
 | |
|     GTK_LOCK = new String("GTK LOCK");
 | |
|     gtkInit(portableNativeSync, GTK_LOCK);
 | |
|   }
 | |
| 
 | |
|   public GtkToolkit ()
 | |
|   {
 | |
|   }
 | |
| 
 | |
|   public native void beep();
 | |
| 
 | |
|   private native void getScreenSizeDimensions(int[] xy);
 | |
| 
 | |
|   public int checkImage (Image image, int width, int height,
 | |
|                          ImageObserver observer)
 | |
|   {
 | |
|     int status = ImageObserver.ALLBITS
 | |
|       | ImageObserver.WIDTH
 | |
|       | ImageObserver.HEIGHT;
 | |
| 
 | |
|     if (image instanceof GtkImage)
 | |
|       return ((GtkImage) image).checkImage (observer);
 | |
| 
 | |
|     if (image instanceof AsyncImage)
 | |
|       return ((AsyncImage) image).checkImage(observer);
 | |
| 
 | |
|     if (observer != null)
 | |
|       observer.imageUpdate (image, status,
 | |
|                             -1, -1,
 | |
|                             image.getWidth (observer),
 | |
|                             image.getHeight (observer));
 | |
| 
 | |
|     return status;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Helper to return either a Image -- the argument -- or a
 | |
|    * GtkImage with the errorLoading flag set if the argument is null.
 | |
|    */
 | |
|   static Image imageOrError(Image b)
 | |
|   {
 | |
|     if (b == null)
 | |
|       return GtkImage.getErrorImage();
 | |
|     else
 | |
|       return b;
 | |
|   }
 | |
| 
 | |
|   public Image createImage (String filename)
 | |
|   {
 | |
|     if (filename.length() == 0)
 | |
|       return new GtkImage ();
 | |
| 
 | |
|     Image image;
 | |
|     try
 | |
|       {
 | |
|         image = CairoSurface.getBufferedImage( new GtkImage( filename ) );
 | |
|       }
 | |
|     catch (IllegalArgumentException iae)
 | |
|       {
 | |
|         image = null;
 | |
|       }
 | |
|     return imageOrError(image);
 | |
|   }
 | |
| 
 | |
|   public Image createImage (URL url)
 | |
|   {
 | |
|     return new AsyncImage(url);
 | |
|   }
 | |
| 
 | |
|   public Image createImage (ImageProducer producer)
 | |
|   {
 | |
|     if (producer == null)
 | |
|       return null;
 | |
| 
 | |
|     Image image;
 | |
|     try
 | |
|       {
 | |
|         image = CairoSurface.getBufferedImage( new GtkImage( producer ) );
 | |
|       }
 | |
|     catch (IllegalArgumentException iae)
 | |
|       {
 | |
|         image = null;
 | |
|       }
 | |
|     return imageOrError(image);
 | |
|   }
 | |
| 
 | |
|   public Image createImage (byte[] imagedata, int imageoffset,
 | |
|                             int imagelength)
 | |
|   {
 | |
|     Image image;
 | |
|     try
 | |
|       {
 | |
|         byte[] data = new byte[ imagelength ];
 | |
|         System.arraycopy(imagedata, imageoffset, data, 0, imagelength);
 | |
|         image = CairoSurface.getBufferedImage( new GtkImage( data ) );
 | |
|       }
 | |
|     catch (IllegalArgumentException iae)
 | |
|       {
 | |
|         image = null;
 | |
|       }
 | |
|     return imageOrError(image);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Creates an ImageProducer from the specified URL. The image is assumed
 | |
|    * to be in a recognised format.
 | |
|    *
 | |
|    * @param url URL to read image data from.
 | |
|    */
 | |
|   public ImageProducer createImageProducer(URL url)
 | |
|   {
 | |
|     return createImage( url ).getSource();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the native color model (which isn't the same as the default
 | |
|    * ARGB color model, but doesn't have to be).
 | |
|    */
 | |
|   public ColorModel getColorModel ()
 | |
|   {
 | |
|     /* Return the GDK-native ABGR format */
 | |
|     return new DirectColorModel(32,
 | |
|                                 0x000000FF,
 | |
|                                 0x0000FF00,
 | |
|                                 0x00FF0000,
 | |
|                                 0xFF000000);
 | |
|   }
 | |
| 
 | |
|   public String[] getFontList ()
 | |
|   {
 | |
|     return (new String[] { "Dialog",
 | |
|                            "DialogInput",
 | |
|                            "Monospaced",
 | |
|                            "Serif",
 | |
|                            "SansSerif" });
 | |
|   }
 | |
| 
 | |
|   static class LRUCache<K,V> extends LinkedHashMap<K,V>
 | |
|   {
 | |
|     int max_entries;
 | |
|     public LRUCache(int max)
 | |
|     {
 | |
|       super(max, 0.75f, true);
 | |
|       max_entries = max;
 | |
|     }
 | |
|     protected boolean removeEldestEntry(Map.Entry eldest)
 | |
|     {
 | |
|       return size() > max_entries;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   private LRUCache<Map,ClasspathFontPeer> fontCache =
 | |
|     new LRUCache<Map,ClasspathFontPeer>(50);
 | |
|   private LRUCache<Object,Image> imageCache = new LRUCache<Object,Image>(50);
 | |
| 
 | |
|   public FontMetrics getFontMetrics (Font font)
 | |
|   {
 | |
|     return ((GdkFontPeer) font.getPeer()).getFontMetrics(font);
 | |
|   }
 | |
| 
 | |
|   public Image getImage (String filename)
 | |
|   {
 | |
|     if (imageCache.containsKey(filename))
 | |
|       return imageCache.get(filename);
 | |
|     else
 | |
|       {
 | |
|         Image im = createImage(filename);
 | |
|         imageCache.put(filename, im);
 | |
|         return im;
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   public Image getImage (URL url)
 | |
|   {
 | |
|     if (imageCache.containsKey(url))
 | |
|       return imageCache.get(url);
 | |
|     else
 | |
|       {
 | |
|         Image im = createImage(url);
 | |
|         imageCache.put(url, im);
 | |
|         return im;
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   public PrintJob getPrintJob (Frame frame, String jobtitle, Properties props)
 | |
|   {
 | |
|     SecurityManager sm;
 | |
|     sm = System.getSecurityManager();
 | |
|     if (sm != null)
 | |
|       sm.checkPrintJobAccess();
 | |
| 
 | |
|     return null;
 | |
|   }
 | |
| 
 | |
|   public native int getScreenResolution();
 | |
| 
 | |
|   public Dimension getScreenSize ()
 | |
|   {
 | |
|     int dim[] = new int[2];
 | |
|     getScreenSizeDimensions(dim);
 | |
|     return new Dimension(dim[0], dim[1]);
 | |
|   }
 | |
| 
 | |
|   public Clipboard getSystemClipboard()
 | |
|   {
 | |
|     SecurityManager secman = System.getSecurityManager();
 | |
|     if (secman != null)
 | |
|       secman.checkSystemClipboardAccess();
 | |
| 
 | |
|     return GtkClipboard.getClipboardInstance();
 | |
|   }
 | |
| 
 | |
|   public Clipboard getSystemSelection()
 | |
|   {
 | |
|     SecurityManager secman = System.getSecurityManager();
 | |
|     if (secman != null)
 | |
|       secman.checkSystemClipboardAccess();
 | |
| 
 | |
|     return GtkClipboard.getSelectionInstance();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Prepares a GtkImage. For every other kind of Image it just
 | |
|    * assumes the image is already prepared for rendering.
 | |
|    */
 | |
|   public boolean prepareImage (Image image, int width, int height,
 | |
|                                ImageObserver observer)
 | |
|   {
 | |
|     /* GtkImages are always prepared, as long as they're loaded. */
 | |
|     if (image instanceof GtkImage)
 | |
|       return ((((GtkImage)image).checkImage (observer)
 | |
|                & ImageObserver.ALLBITS) != 0);
 | |
| 
 | |
|     if (image instanceof AsyncImage)
 | |
|       {
 | |
|         AsyncImage aImg = (AsyncImage) image;
 | |
|         aImg.addObserver(observer);
 | |
|         return aImg.realImage != null;
 | |
|       }
 | |
| 
 | |
|     /* Assume anything else is too */
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   public native void sync();
 | |
| 
 | |
|   protected void setComponentState (Component c, GtkComponentPeer cp)
 | |
|   {
 | |
|     /* Make the Component reflect Peer defaults */
 | |
|     if (c.getForeground () == null)
 | |
|       c.setForeground (cp.getForeground ());
 | |
|     if (c.getBackground () == null)
 | |
|       c.setBackground (cp.getBackground ());
 | |
|     //        if (c.getFont () == null)
 | |
|     //          c.setFont (cp.getFont ());
 | |
| 
 | |
|     /* Make the Peer reflect the state of the Component */
 | |
|     if (! (c instanceof Window))
 | |
|       {
 | |
|         cp.setCursor (c.getCursor ());
 | |
| 
 | |
|         Rectangle bounds = c.getBounds ();
 | |
|         cp.setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
 | |
|         cp.setVisible (c.isVisible ());
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   protected ButtonPeer createButton (Button b)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkButtonPeer (b);
 | |
|   }
 | |
| 
 | |
|   protected CanvasPeer createCanvas (Canvas c)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkCanvasPeer (c);
 | |
|   }
 | |
| 
 | |
|   protected CheckboxPeer createCheckbox (Checkbox cb)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkCheckboxPeer (cb);
 | |
|   }
 | |
| 
 | |
|   protected CheckboxMenuItemPeer createCheckboxMenuItem (CheckboxMenuItem cmi)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkCheckboxMenuItemPeer (cmi);
 | |
|   }
 | |
| 
 | |
|   protected ChoicePeer createChoice (Choice c)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkChoicePeer (c);
 | |
|   }
 | |
| 
 | |
|   protected DialogPeer createDialog (Dialog d)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     GtkMainThread.createWindow();
 | |
|     return new GtkDialogPeer (d);
 | |
|   }
 | |
| 
 | |
|   protected FileDialogPeer createFileDialog (FileDialog fd)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkFileDialogPeer (fd);
 | |
|   }
 | |
| 
 | |
|   protected FramePeer createFrame (Frame f)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     GtkMainThread.createWindow();
 | |
|     return new GtkFramePeer (f);
 | |
|   }
 | |
| 
 | |
|   protected LabelPeer createLabel (Label label)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkLabelPeer (label);
 | |
|   }
 | |
| 
 | |
|   protected ListPeer createList (List list)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkListPeer (list);
 | |
|   }
 | |
| 
 | |
|   protected MenuPeer createMenu (Menu m)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkMenuPeer (m);
 | |
|   }
 | |
| 
 | |
|   protected MenuBarPeer createMenuBar (MenuBar mb)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkMenuBarPeer (mb);
 | |
|   }
 | |
| 
 | |
|   protected MenuItemPeer createMenuItem (MenuItem mi)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkMenuItemPeer (mi);
 | |
|   }
 | |
| 
 | |
|   protected PanelPeer createPanel (Panel p)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkPanelPeer (p);
 | |
|   }
 | |
| 
 | |
|   protected PopupMenuPeer createPopupMenu (PopupMenu target)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkPopupMenuPeer (target);
 | |
|   }
 | |
| 
 | |
|   protected ScrollPanePeer createScrollPane (ScrollPane sp)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkScrollPanePeer (sp);
 | |
|   }
 | |
| 
 | |
|   protected ScrollbarPeer createScrollbar (Scrollbar sb)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkScrollbarPeer (sb);
 | |
|   }
 | |
| 
 | |
|   protected TextAreaPeer createTextArea (TextArea ta)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkTextAreaPeer (ta);
 | |
|   }
 | |
| 
 | |
|   protected TextFieldPeer createTextField (TextField tf)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     return new GtkTextFieldPeer (tf);
 | |
|   }
 | |
| 
 | |
|   protected WindowPeer createWindow (Window w)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     GtkMainThread.createWindow();
 | |
|     return new GtkWindowPeer (w);
 | |
|   }
 | |
| 
 | |
|   public EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w)
 | |
|   {
 | |
|     checkHeadless();
 | |
|     GtkMainThread.createWindow();
 | |
|     return new GtkEmbeddedWindowPeer (w);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @deprecated part of the older "logical font" system in earlier AWT
 | |
|    * implementations. Our newer Font class uses getClasspathFontPeer.
 | |
|    */
 | |
|   protected FontPeer getFontPeer (String name, int style) {
 | |
|     // All fonts get a default size of 12 if size is not specified.
 | |
|     return getFontPeer(name, style, 12);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Private method that allows size to be set at initialization time.
 | |
|    */
 | |
|   private FontPeer getFontPeer (String name, int style, int size)
 | |
|   {
 | |
|     Map<TextAttribute,Object> attrs = new HashMap<TextAttribute,Object>();
 | |
|     ClasspathFontPeer.copyStyleToAttrs (style, attrs);
 | |
|     ClasspathFontPeer.copySizeToAttrs (size, attrs);
 | |
|     return getClasspathFontPeer (name, attrs);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Newer method to produce a peer for a Font object, even though Sun's
 | |
|    * design claims Font should now be peerless, we do not agree with this
 | |
|    * model, hence "ClasspathFontPeer".
 | |
|    */
 | |
| 
 | |
|   public ClasspathFontPeer getClasspathFontPeer (String name,
 | |
|                                                  Map<?,?> attrs)
 | |
|   {
 | |
|     Map<Object,Object> keyMap = new HashMap<Object,Object>(attrs);
 | |
|     // We don't know what kind of "name" the user requested (logical, face,
 | |
|     // family), and we don't actually *need* to know here. The worst case
 | |
|     // involves failure to consolidate fonts with the same backend in our
 | |
|     // cache. This is harmless.
 | |
|     keyMap.put ("GtkToolkit.RequestedFontName", name);
 | |
|     if (fontCache.containsKey (keyMap))
 | |
|       return fontCache.get (keyMap);
 | |
|     else
 | |
|       {
 | |
|         ClasspathFontPeer newPeer = new GdkFontPeer (name, attrs);
 | |
|         fontCache.put (keyMap, newPeer);
 | |
|         return newPeer;
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   protected EventQueue getSystemEventQueueImpl()
 | |
|   {
 | |
|     synchronized (GtkToolkit.class)
 | |
|       {
 | |
|         if (q == null)
 | |
|           {
 | |
|             q = new EventQueue();
 | |
|           }
 | |
|       }
 | |
|     return q;
 | |
|   }
 | |
| 
 | |
|   public Cursor createCustomCursor(Image image, Point hotspot, String name)
 | |
|   {
 | |
|     return new GtkCursor(image, hotspot, name);
 | |
|   }
 | |
| 
 | |
|   protected native void loadSystemColors (int[] systemColors);
 | |
| 
 | |
|   public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e)
 | |
|   {
 | |
|     if (GraphicsEnvironment.isHeadless())
 | |
|       throw new InvalidDnDOperationException();
 | |
|     return new GtkDragSourceContextPeer(e);
 | |
|   }
 | |
| 
 | |
|   public <T extends DragGestureRecognizer> T
 | |
|   createDragGestureRecognizer(Class<T> recognizer, DragSource ds,
 | |
|                               Component comp, int actions,
 | |
|                               DragGestureListener l)
 | |
|   {
 | |
|     if (recognizer.getName().equals("java.awt.dnd.MouseDragGestureRecognizer")
 | |
|         && ! GraphicsEnvironment.isHeadless())
 | |
|       {
 | |
|         GtkMouseDragGestureRecognizer gestureRecognizer
 | |
|           = new GtkMouseDragGestureRecognizer(ds, comp, actions, l);
 | |
|         gestureRecognizer.registerListeners();
 | |
|         return recognizer.cast(gestureRecognizer);
 | |
|       }
 | |
|     else
 | |
|       {
 | |
|         return null;
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   public Map<TextAttribute,?> mapInputMethodHighlight(InputMethodHighlight highlight)
 | |
|   {
 | |
|     throw new Error("not implemented");
 | |
|   }
 | |
| 
 | |
|   public Rectangle getBounds()
 | |
|   {
 | |
|     int[] dims = new int[2];
 | |
|     getScreenSizeDimensions(dims);
 | |
|     return new Rectangle(0, 0, dims[0], dims[1]);
 | |
|   }
 | |
| 
 | |
|   // ClasspathToolkit methods
 | |
| 
 | |
|   public GraphicsEnvironment getLocalGraphicsEnvironment()
 | |
|   {
 | |
|     return new GdkGraphicsEnvironment();
 | |
|   }
 | |
| 
 | |
|   public Font createFont(int format, InputStream stream)
 | |
|   {
 | |
|     throw new UnsupportedOperationException();
 | |
|   }
 | |
| 
 | |
|   public RobotPeer createRobot (GraphicsDevice screen) throws AWTException
 | |
|   {
 | |
|     return new GdkRobotPeer (screen);
 | |
|   }
 | |
| 
 | |
|   public boolean getLockingKeyState(int keyCode)
 | |
|   {
 | |
|     int state = getLockState(keyCode);
 | |
| 
 | |
|     if (state != -1)
 | |
|       return state == 1;
 | |
| 
 | |
|     if (AWTUtilities.isValidKey(keyCode))
 | |
|       throw new UnsupportedOperationException
 | |
|         ("cannot get locking state of key code " + keyCode);
 | |
| 
 | |
|     throw new IllegalArgumentException("invalid key code " + keyCode);
 | |
|   }
 | |
| 
 | |
|   protected native int getLockState(int keyCode);
 | |
| 
 | |
|   public void registerImageIOSpis(IIORegistry reg)
 | |
|   {
 | |
|     GdkPixbufDecoder.registerSpis(reg);
 | |
|   }
 | |
| 
 | |
|   protected MouseInfoPeer getMouseInfoPeer()
 | |
|   {
 | |
|     return new GtkMouseInfoPeer();
 | |
|   }
 | |
| 
 | |
|   public boolean isFrameStateSupported(int state)
 | |
|   {
 | |
|     // GTK supports ICONFIED, NORMAL and MAXIMIZE_BOTH, but
 | |
|     // not (yet?) MAXIMIZE_VERT and MAXIMIZE_HORIZ.
 | |
|     return state == Frame.NORMAL || state == Frame.ICONIFIED
 | |
|            || state == Frame.MAXIMIZED_BOTH;
 | |
|   }
 | |
| 
 | |
|   private void checkHeadless()
 | |
|   {
 | |
|     if (GraphicsEnvironment.isHeadless())
 | |
|       throw new HeadlessException();
 | |
|   }
 | |
| 
 | |
|   public native int getMouseNumberOfButtons();
 | |
| 
 | |
|   @Override
 | |
|   public boolean isModalExclusionTypeSupported
 | |
|   (Dialog.ModalExclusionType modalExclusionType)
 | |
|   {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   @Override
 | |
|   public boolean isModalityTypeSupported(Dialog.ModalityType modalityType)
 | |
|   {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
| } // class GtkToolkit
 |