Source for gnu.java.awt.peer.x.XWindowPeer

   1: /* XWindowPeer.java -- Window peer for X
   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.Component;
  42: import java.awt.EventQueue;
  43: import java.awt.Font;
  44: import java.awt.FontMetrics;
  45: import java.awt.Graphics;
  46: import java.awt.GraphicsConfiguration;
  47: import java.awt.GraphicsDevice;
  48: import java.awt.GraphicsEnvironment;
  49: import java.awt.Image;
  50: import java.awt.Insets;
  51: import java.awt.Point;
  52: import java.awt.Rectangle;
  53: import java.awt.event.PaintEvent;
  54: import java.awt.event.WindowEvent;
  55: import java.awt.image.VolatileImage;
  56: 
  57: import gnu.x11.Window;
  58: import gnu.x11.event.Event;
  59: 
  60: import gnu.java.awt.peer.swing.SwingWindowPeer;
  61: 
  62: public class XWindowPeer
  63:     extends SwingWindowPeer
  64: {
  65: 
  66:   private static int standardSelect = Event.BUTTON_PRESS_MASK
  67:                                       | Event.BUTTON_RELEASE_MASK
  68:                                       | Event.POINTER_MOTION_MASK
  69:                                       //| Event.RESIZE_REDIRECT_MASK
  70:                                       | Event.EXPOSURE_MASK
  71:                                       //| Event.PROPERTY_CHANGE_MASK
  72:                                       | Event.STRUCTURE_NOTIFY_MASK
  73:                                       | Event.KEY_PRESS_MASK
  74:                                       | Event.KEY_RELEASE_MASK
  75:                                       ;
  76: 
  77:   /**
  78:    * Indicates if we are in callback mode, that is when a property (like size)
  79:    * is changed in reponse to a request from the X server and doesn't need
  80:    * to be propagated back to the X server.
  81:    */
  82:   boolean callback = false;
  83: 
  84:   /**
  85:    * The X window.
  86:    */
  87:   private Window xwindow;
  88: 
  89:   XWindowPeer(java.awt.Window window)
  90:   {
  91:     super(window);
  92:     XGraphicsDevice dev = XToolkit.getDefaultDevice();
  93: 
  94:     // TODO: Maybe initialize lazily in show().
  95:     // FIXME: Howto generate a Window without decorations?
  96:     int x = Math.max(window.getX(), 0);
  97:     int y = Math.max(window.getY(), 0);
  98:     int w = Math.max(window.getWidth(), 1);
  99:     int h = Math.max(window.getHeight(), 1);
 100:     xwindow = new Window(dev.getDisplay().default_root, x, y, w, h);
 101:     xwindow.create();
 102:     xwindow.select_input(standardSelect);
 103:     dev.getEventPump().registerWindow(xwindow, window);
 104:   }
 105: 
 106:   public void toBack()
 107:   {
 108:     // TODO Auto-generated method stub
 109: 
 110:   }
 111: 
 112:   public void toFront()
 113:   {
 114:     // TODO Auto-generated method stub
 115: 
 116:   }
 117: 
 118:   public void updateAlwaysOnTop()
 119:   {
 120:     // TODO Auto-generated method stub
 121: 
 122:   }
 123: 
 124:   public boolean requestWindowFocus()
 125:   {
 126:     // TODO Auto-generated method stub
 127:     return false;
 128:   }
 129: 
 130:   public Point getLocationOnScreen()
 131:   {
 132:     return new Point(xwindow.x, xwindow.y);
 133:   }
 134: 
 135:   /**
 136:    * Returns a XGraphics suitable for drawing on this frame.
 137:    *
 138:    * @return a XGraphics suitable for drawing on this frame
 139:    */
 140:   public Graphics getGraphics()
 141:   {
 142:     return new XGraphics2D(xwindow);
 143:   }
 144: 
 145:   public Image createImage(int w, int h)
 146:   {
 147:     // FIXME: Should return a buffered image.
 148:     return createVolatileImage(w, h);
 149:   }
 150: 
 151:   @Override
 152:   public VolatileImage createVolatileImage(int width, int height)
 153:   {
 154:     GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
 155:     GraphicsDevice gd = ge.getDefaultScreenDevice();
 156:     GraphicsConfiguration gc = gd.getDefaultConfiguration();
 157:     return gc.createCompatibleVolatileImage(width, height);
 158:   }
 159: 
 160:   /**
 161:    * Makes the component visible. This is called by {@link Component#show()}.
 162:    *
 163:    * This is implemented to call setVisible(true) on the Swing component.
 164:    */
 165:   public void show()
 166:   {
 167: //    // Prevent ResizeRedirect events.
 168: //    //xwindow.select_input(noResizeRedirectSelect);
 169: //    Window.Attributes atts = new Window.Attributes();
 170: //    atts.set_override_redirect(true);
 171: //    xwindow.change_attributes(atts);
 172: 
 173:     // Prevent ResizeRedirect events.
 174:     //xwindow.select_input(Event.NO_EVENT_MASK);
 175:     //xwindow.select_input(noResizeRedirectSelect);
 176: 
 177:     xwindow.map();
 178:     EventQueue eq = XToolkit.getDefaultToolkit().getSystemEventQueue();
 179:     java.awt.Window w = (java.awt.Window) super.awtComponent;
 180:     eq.postEvent(new WindowEvent(w, WindowEvent.WINDOW_OPENED));
 181:     eq.postEvent(new PaintEvent(w, PaintEvent.PAINT,
 182:                                 new Rectangle(0, 0, w.getWidth(),
 183:                                               w.getHeight())));
 184: 
 185:     Graphics g = getGraphics();
 186:     g.clearRect(0, 0, awtComponent.getWidth(), awtComponent.getHeight());
 187:     g.dispose();
 188: //    // Reset input selection.
 189: //    atts.set_override_redirect(false);
 190: //    xwindow.change_attributes(atts);
 191:   }
 192: 
 193:   /**
 194:    * Makes the component invisible. This is called from
 195:    * {@link Component#hide()}.
 196:    *
 197:    * This is implemented to call setVisible(false) on the Swing component.
 198:    */
 199:   public void hide()
 200:   {
 201:     xwindow.unmap();
 202:   }
 203: 
 204:   /**
 205:    * Notifies the peer that the bounds of this component have changed. This
 206:    * is called by {@link Component#reshape(int, int, int, int)}.
 207:    *
 208:    * This is implemented to call setBounds() on the Swing component.
 209:    *
 210:    * @param x the X coordinate of the upper left corner of the component
 211:    * @param y the Y coordinate of the upper left corner of the component
 212:    * @param width the width of the component
 213:    * @param height the height of the component
 214:    */
 215:   public void reshape(int x, int y, int width, int height)
 216:   {
 217:     // Prevent ResizeRedirect events.
 218: //    //xwindow.select_input(noResizeRedirectSelect);
 219: //    Window.Attributes atts = new Window.Attributes();
 220: //    atts.set_override_redirect(true);
 221: //    xwindow.change_attributes(atts);
 222: 
 223:     // Need to substract insets because AWT size is including insets,
 224:     // and X size is excuding insets.
 225:     Insets i = insets();
 226:     xwindow.move_resize(x - i.left, y - i.right, width - i.left - i.right,
 227:                         height - i.top - i.bottom);
 228: 
 229:     // Reset input selection.
 230: //    atts = new Window.Attributes();
 231: //    atts.set_override_redirect(false);
 232: //    xwindow.change_attributes(atts);
 233:   }
 234: 
 235:   public Insets insets()
 236:   {
 237:     Insets i = new Insets(0, 0, 0, 0);
 238: //    Window.GeometryReply g = xwindow.geometry();
 239: //    int b = g.border_width();
 240: //    Insets i = new Insets(b, b, b, b);
 241: //    Window.WMSizeHints wmSize = xwindow.wm_normal_hints();
 242: //    if (wmSize != null)
 243: //      {
 244: //        i.left = wmSize.x() - g.x();
 245: //        i.right = wmSize.width() - g.width() - i.left ;
 246: //        i.top = wmSize.y() - g.y();
 247: //        i.bottom = wmSize.height() - g.height() - i.top;
 248: //      }
 249: //    System.err.println("insets: " + i);
 250:     return i;
 251:   }
 252: 
 253:   /**
 254:    * Returns the font metrics for the specified font.
 255:    *
 256:    * @return the font metrics for the specified font
 257:    */
 258:   public FontMetrics getFontMetrics(Font font)
 259:   {
 260:     XFontPeer2 fontPeer = (XFontPeer2) font.getPeer();
 261:     return fontPeer.getFontMetrics(font);
 262:   }
 263: 
 264:   /**
 265:    * Unregisters the window in the event pump when it is closed.
 266:    */
 267:   protected void finalize()
 268:   {
 269:     XGraphicsDevice dev = XToolkit.getDefaultDevice();
 270:     dev.getEventPump().unregisterWindow(xwindow);
 271:   }
 272: }