| /* XToolkit.java -- The central AWT Toolkit for the X peers |
| Copyright (C) 2006 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.x; |
| |
| 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.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.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.PopupMenu; |
| import java.awt.PrintJob; |
| import java.awt.ScrollPane; |
| import java.awt.Scrollbar; |
| import java.awt.TextArea; |
| import java.awt.TextField; |
| import java.awt.Transparency; |
| import java.awt.Window; |
| import java.awt.datatransfer.Clipboard; |
| import java.awt.dnd.DragGestureEvent; |
| import java.awt.dnd.peer.DragSourceContextPeer; |
| import java.awt.im.InputMethodHighlight; |
| import java.awt.image.BufferedImage; |
| 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.LightweightPeer; |
| import java.awt.peer.ListPeer; |
| import java.awt.peer.MenuBarPeer; |
| import java.awt.peer.MenuItemPeer; |
| import java.awt.peer.MenuPeer; |
| 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.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.WeakHashMap; |
| |
| import javax.imageio.ImageIO; |
| |
| import gnu.classpath.SystemProperties; |
| import gnu.java.awt.ClasspathToolkit; |
| import gnu.java.awt.EmbeddedWindow; |
| import gnu.java.awt.peer.ClasspathFontPeer; |
| import gnu.java.awt.peer.EmbeddedWindowPeer; |
| import gnu.java.awt.peer.swing.SwingCanvasPeer; |
| import gnu.java.awt.peer.swing.SwingLabelPeer; |
| import gnu.java.awt.peer.swing.SwingPanelPeer; |
| |
| public class XToolkit |
| extends ClasspathToolkit |
| { |
| |
| /** |
| * Set to true to enable debug output. |
| */ |
| static boolean DEBUG = false; |
| |
| /** |
| * Maps AWT colors to X colors. |
| */ |
| HashMap colorMap = new HashMap(); |
| |
| /** |
| * The system event queue. |
| */ |
| private EventQueue eventQueue; |
| |
| /** |
| * The default color model of this toolkit. |
| */ |
| private ColorModel colorModel; |
| |
| /** |
| * Maps image URLs to Image instances. |
| */ |
| private HashMap imageCache = new HashMap(); |
| |
| /** |
| * The cached fonts. |
| */ |
| private WeakHashMap fontCache = new WeakHashMap(); |
| |
| public XToolkit() |
| { |
| SystemProperties.setProperty("gnu.javax.swing.noGraphics2D", "true"); |
| SystemProperties.setProperty("java.awt.graphicsenv", |
| "gnu.java.awt.peer.x.XGraphicsEnvironment"); |
| } |
| |
| public GraphicsEnvironment getLocalGraphicsEnvironment() |
| { |
| return new XGraphicsEnvironment(); |
| } |
| |
| /** |
| * Returns the font peer for a font with the specified name and attributes. |
| * |
| * @param name the font name |
| * @param attrs the font attributes |
| * |
| * @return the font peer for a font with the specified name and attributes |
| */ |
| public ClasspathFontPeer getClasspathFontPeer(String name, Map attrs) |
| { |
| String canonical = XFontPeer.encodeFont(name, attrs); |
| ClasspathFontPeer font; |
| if (!fontCache.containsKey(canonical)) |
| { |
| String graphics2d = |
| SystemProperties.getProperty("gnu.xawt.graphics2d"); |
| if (graphics2d != null && graphics2d.equals("gl")) |
| font = new XFontPeer2(name, attrs); |
| else |
| font = new XFontPeer(name, attrs); |
| fontCache.put(canonical, font); |
| } |
| else |
| { |
| font = (ClasspathFontPeer) fontCache.get(canonical); |
| } |
| return font; |
| } |
| |
| public Font createFont(int format, InputStream stream) |
| { |
| return null; |
| } |
| |
| public RobotPeer createRobot(GraphicsDevice screen) throws AWTException |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| public EmbeddedWindowPeer createEmbeddedWindow(EmbeddedWindow w) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected ButtonPeer createButton(Button target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected TextFieldPeer createTextField(TextField target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected LabelPeer createLabel(Label target) |
| { |
| return new SwingLabelPeer(target); |
| } |
| |
| protected ListPeer createList(List target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected CheckboxPeer createCheckbox(Checkbox target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected ScrollbarPeer createScrollbar(Scrollbar target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected ScrollPanePeer createScrollPane(ScrollPane target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected TextAreaPeer createTextArea(TextArea target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected ChoicePeer createChoice(Choice target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected FramePeer createFrame(Frame target) |
| { |
| XFramePeer frame = new XFramePeer(target); |
| return frame; |
| } |
| |
| protected CanvasPeer createCanvas(Canvas target) |
| { |
| return new SwingCanvasPeer(target); |
| } |
| |
| protected PanelPeer createPanel(Panel target) |
| { |
| return new SwingPanelPeer(target); |
| } |
| |
| protected WindowPeer createWindow(Window target) |
| { |
| return new XWindowPeer(target); |
| } |
| |
| protected DialogPeer createDialog(Dialog target) |
| { |
| return new XDialogPeer(target); |
| } |
| |
| protected MenuBarPeer createMenuBar(MenuBar target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected MenuPeer createMenu(Menu target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected PopupMenuPeer createPopupMenu(PopupMenu target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected MenuItemPeer createMenuItem(MenuItem target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected FileDialogPeer createFileDialog(FileDialog target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| protected FontPeer getFontPeer(String name, int style) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| public Dimension getScreenSize() |
| { |
| // FIXME: This is only a hack to get some apps working. |
| return new Dimension(1024, 768); |
| } |
| |
| public int getScreenResolution() |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| /** |
| * Returns the color model used by this toolkit. |
| * |
| * @return the color model used by this toolkit |
| */ |
| public ColorModel getColorModel() |
| { |
| // TODO: I assume 24 bit depth here, we can do this better. |
| if (colorModel == null) |
| colorModel = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF); |
| return colorModel; |
| } |
| |
| public String[] getFontList() |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| public FontMetrics getFontMetrics(Font name) |
| { |
| ClasspathFontPeer peer = (ClasspathFontPeer) name.getPeer(); |
| return peer.getFontMetrics(name); |
| } |
| |
| public void sync() |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| /** |
| * Returns an image that has its pixel data loaded from a file with the |
| * specified name. If that file doesn't exist, an empty or error image |
| * is returned instead. |
| * |
| * @param name the filename of the file that contains the pixel data |
| * |
| * @return the image |
| */ |
| public Image getImage(String name) |
| { |
| Image image; |
| try |
| { |
| File file = new File(name); |
| image = getImage(file.toURL()); |
| } |
| catch (MalformedURLException ex) |
| { |
| // TODO: Replace by a more meaningful error image instead. |
| image = null; |
| } |
| return image; |
| } |
| |
| /** |
| * Returns an image that has its pixel data loaded from the specified URL. |
| * If the image cannot be loaded for some reason, an empty or error image |
| * is returned instead. |
| * |
| * @param url the URL to the image data |
| * |
| * @return the image |
| */ |
| public Image getImage(URL url) |
| { |
| Image image; |
| if (imageCache.containsKey(url)) |
| { |
| image = (Image) imageCache.get(url); |
| } |
| else |
| { |
| image = createImage(url); |
| imageCache.put(url, image); |
| } |
| return image; |
| } |
| |
| /** |
| * Returns an image that has its pixel data loaded from a file with the |
| * specified name. If that file doesn't exist, an empty or error image |
| * is returned instead. |
| * |
| * @param filename the filename of the file that contains the pixel data |
| * |
| * @return the image |
| */ |
| public Image createImage(String filename) |
| { |
| Image im; |
| try |
| { |
| File file = new File(filename); |
| URL url = file.toURL(); |
| im = createImage(url); |
| } |
| catch (MalformedURLException ex) |
| { |
| im = createErrorImage(); |
| } |
| return im; |
| } |
| |
| /** |
| * Returns an image that has its pixel data loaded from the specified URL. |
| * If the image cannot be loaded for some reason, an empty or error image |
| * is returned instead. |
| * |
| * @param url the URL to the image data |
| * |
| * @return the image |
| */ |
| public Image createImage(URL url) |
| { |
| Image image; |
| try |
| { |
| image = createImage(url.openStream()); |
| } |
| catch (IOException ex) |
| { |
| image = createErrorImage(); |
| } |
| return image; |
| } |
| |
| /** |
| * Creates an image that is returned when calls to createImage() yields an |
| * error. |
| * |
| * @return an image that is returned when calls to createImage() yields an |
| * error |
| */ |
| private Image createErrorImage() |
| { |
| // TODO: Create better error image. |
| return new XImage(1, 1); |
| } |
| |
| public boolean prepareImage(Image image, int width, int height, ImageObserver observer) |
| { |
| // Images are loaded synchronously, so we don't bother and return true. |
| return true; |
| } |
| |
| public int checkImage(Image image, int width, int height, ImageObserver observer) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| public Image createImage(ImageProducer producer) |
| { |
| ImageConverter conv = new ImageConverter(); |
| producer.startProduction(conv); |
| Image image = conv.getXImage(); |
| return image; |
| } |
| |
| public Image createImage(byte[] data, int offset, int len) |
| { |
| Image image; |
| try |
| { |
| ByteArrayInputStream i = new ByteArrayInputStream(data, offset, len); |
| image = createImage(i); |
| } |
| catch (IOException ex) |
| { |
| image = createErrorImage(); |
| } |
| return image; |
| } |
| |
| private Image createImage(InputStream i) |
| throws IOException |
| { |
| Image image; |
| BufferedImage buffered = ImageIO.read(i); |
| // If the bufferedimage is opaque, then we can copy it over to an |
| // X Pixmap for faster drawing. |
| if (buffered != null && buffered.getTransparency() == Transparency.OPAQUE) |
| { |
| ImageProducer source = buffered.getSource(); |
| image = createImage(source); |
| } |
| else if (buffered != null) |
| { |
| image = buffered; |
| } |
| else |
| { |
| image = createErrorImage(); |
| } |
| return image; |
| } |
| |
| public PrintJob getPrintJob(Frame frame, String title, Properties props) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| public void beep() |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| public Clipboard getSystemClipboard() |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| /** |
| * Returns the eventqueue used by the XLib peers. |
| * |
| * @return the eventqueue used by the XLib peers |
| */ |
| protected EventQueue getSystemEventQueueImpl() |
| { |
| if (eventQueue == null) |
| eventQueue = new EventQueue(); |
| return eventQueue; |
| } |
| |
| public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| public Map mapInputMethodHighlight(InputMethodHighlight highlight) |
| { |
| // TODO: Implement this. |
| throw new UnsupportedOperationException("Not yet implemented."); |
| } |
| |
| /** |
| * Helper method to quickly fetch the default device (X Display). |
| * |
| * @return the default XGraphicsDevice |
| */ |
| static XGraphicsDevice getDefaultDevice() |
| { |
| XGraphicsEnvironment env = (XGraphicsEnvironment) |
| XGraphicsEnvironment.getLocalGraphicsEnvironment(); |
| return (XGraphicsDevice) env.getDefaultScreenDevice(); |
| } |
| |
| protected LightweightPeer createComponent(Component c) |
| { |
| return new XLightweightPeer(c); |
| } |
| } |