OSDN Git Service

libjava/ChangeLog:
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / java / awt / peer / x / XWindowPeer.java
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.Dialog;
43 import java.awt.EventQueue;
44 import java.awt.Font;
45 import java.awt.FontMetrics;
46 import java.awt.Frame;
47 import java.awt.Graphics;
48 import java.awt.GraphicsConfiguration;
49 import java.awt.GraphicsDevice;
50 import java.awt.GraphicsEnvironment;
51 import java.awt.Image;
52 import java.awt.Insets;
53 import java.awt.Point;
54 import java.awt.Rectangle;
55 import java.awt.event.PaintEvent;
56 import java.awt.event.WindowEvent;
57 import java.awt.image.VolatileImage;
58
59 import gnu.x11.Atom;
60 import gnu.x11.Window;
61 import gnu.x11.event.Event;
62
63 import gnu.java.awt.font.OpenTypeFontPeer;
64 import gnu.java.awt.peer.ClasspathFontPeer;
65 import gnu.java.awt.peer.swing.SwingWindowPeer;
66
67 public class XWindowPeer
68     extends SwingWindowPeer
69 {
70
71   private static int standardSelect = Event.BUTTON_PRESS_MASK
72                                       | Event.BUTTON_RELEASE_MASK
73                                       | Event.POINTER_MOTION_MASK
74                                      // | Event.RESIZE_REDIRECT_MASK //
75                                       | Event.EXPOSURE_MASK
76                                       | Event.PROPERTY_CHANGE_MASK
77                                       //| Event.STRUCTURE_NOTIFY_MASK
78                                       //| Event.SUBSTRUCTURE_NOTIFY_MASK
79                                       | Event.KEY_PRESS_MASK
80                                       | Event.KEY_RELEASE_MASK
81                                       //| Event.VISIBILITY_CHANGE_MASK //
82                                       ;
83   
84   /**
85    * The X window.
86    */
87   protected Window xwindow;
88
89   /**
90    * The frame insets. These get updated in {@link #show()}.
91    */
92   private Insets insets;
93
94   XWindowPeer(java.awt.Window window)
95   {
96     super(window);
97     XGraphicsDevice dev = XToolkit.getDefaultDevice();
98
99     // TODO: Maybe initialize lazily in show().
100     Window.Attributes atts = new Window.Attributes();
101     // FIXME: Howto generate a Window without decorations?
102     int x = Math.max(window.getX(), 0);
103     int y = Math.max(window.getY(), 0);
104     int w = Math.max(window.getWidth(), 1);
105     int h = Math.max(window.getHeight(), 1);
106     xwindow = new Window(dev.getDisplay().default_root, x, y, w, h, 0, atts);
107     xwindow.select_input(standardSelect);
108     
109     dev.getEventPump().registerWindow(xwindow, window);
110     xwindow.set_wm_delete_window();
111     
112     boolean undecorated;
113     if (awtComponent instanceof Frame)
114       {
115         Frame f = (Frame) awtComponent;
116         undecorated = f.isUndecorated();
117       }
118     else if (awtComponent instanceof Dialog)
119       {
120         Dialog d = (Dialog) awtComponent;
121         undecorated = d.isUndecorated();
122       }
123     else
124       {
125         undecorated = true;
126       }
127     if (undecorated)
128       {
129         // First try the Motif implementation of undecorated frames. This
130         // is semantically closest and supported by all major window
131         // managers.
132         // TODO: At the time of writing this, there's no freedesktop.org
133         // standard extension that matches the required semantic. Maybe
134         // undecorated frames are added in the future, if so, then use these.
135         Atom at = Atom.intern(dev.getDisplay(), "_MOTIF_WM_HINTS");
136         if (at != null)
137           {
138             xwindow.change_property(Window.REPLACE, at, at, 32,
139                                     new int[]{1 << 1, 0, 0, 0, 0}, 0, 5);
140           }
141       }
142     insets = new Insets(0, 0, 0, 0);
143   }
144
145   public void toBack()
146   {
147     // TODO Auto-generated method stub
148
149   }
150
151   public void toFront()
152   {
153     // TODO Auto-generated method stub
154
155   }
156
157   public void updateAlwaysOnTop()
158   {
159     // TODO Auto-generated method stub
160
161   }
162
163   public boolean requestWindowFocus()
164   {
165     // TODO Auto-generated method stub
166     return false;
167   }
168
169   public Point getLocationOnScreen()
170   {
171     return new Point(xwindow.x, xwindow.y);
172   }
173
174   /**
175    * Returns a XGraphics suitable for drawing on this frame.
176    *
177    * @return a XGraphics suitable for drawing on this frame
178    */
179   public Graphics getGraphics()
180   {
181         XGraphics2D xg2d = new XGraphics2D(xwindow);
182         xg2d.setColor(awtComponent.getForeground());
183         xg2d.setBackground(awtComponent.getBackground());
184         xg2d.setFont(awtComponent.getFont());
185         return xg2d;
186   }
187
188   public Image createImage(int w, int h)
189   {
190     // FIXME: Should return a buffered image.
191     return createVolatileImage(w, h);
192   }
193
194   @Override
195   public VolatileImage createVolatileImage(int width, int height)
196   {
197     GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
198     GraphicsDevice gd = ge.getDefaultScreenDevice();
199     GraphicsConfiguration gc = gd.getDefaultConfiguration();
200     return gc.createCompatibleVolatileImage(width, height);
201   }
202
203   /**
204    * Makes the component visible. This is called by {@link Component#show()}.
205    *
206    * This is implemented to call setVisible(true) on the Swing component.
207    */
208   public void show()
209   {
210     // Prevent ResizeRedirect events.
211     //xwindow.select_input(Event.NO_EVENT_MASK);
212     //xwindow.select_input(noResizeRedirectSelect);
213
214     XGraphicsDevice dev = XToolkit.getDefaultDevice();
215     xwindow.map();
216     EventQueue eq = XToolkit.getDefaultToolkit().getSystemEventQueue();
217     java.awt.Window w = (java.awt.Window) super.awtComponent;
218     eq.postEvent(new WindowEvent(w, WindowEvent.WINDOW_OPENED));
219     eq.postEvent(new PaintEvent(w, PaintEvent.PAINT,
220                                 new Rectangle(0, 0, w.getWidth(),
221                                               w.getHeight())));
222
223     Graphics g = getGraphics();
224     g.clearRect(0, 0, awtComponent.getWidth(), awtComponent.getHeight());
225     g.dispose();
226 //    // Reset input selection.
227 //    atts.set_override_redirect(false);
228 //    xwindow.change_attributes(atts);
229     
230     // Determine the frame insets.
231     Atom atom = (Atom) Atom.intern(dev.getDisplay(), "_NET_FRAME_EXTENTS");
232     Window.Property p = xwindow.get_property(false, atom, Atom.CARDINAL, 0,
233                                              Window.MAX_WM_LENGTH);
234     if (p.format() != 0)
235       {
236         insets = new Insets(p.value(0), p.value(1), p.value(2), p.value(3));
237         Window.Changes ch = new Window.Changes();
238         ch.width(awtComponent.getWidth() - insets.left - insets.top);
239         ch.height(awtComponent.getHeight() - insets.top - insets.bottom);
240         xwindow.configure(ch);
241       }
242
243   }
244
245   /**
246    * Makes the component invisible. This is called from
247    * {@link Component#hide()}.
248    *
249    * This is implemented to call setVisible(false) on the Swing component.
250    */
251   public void hide()
252   {
253     xwindow.unmap();
254   }
255
256   /**
257    * Notifies the peer that the bounds of this component have changed. This
258    * is called by {@link Component#reshape(int, int, int, int)}.
259    *
260    * This is implemented to call setBounds() on the Swing component.
261    *
262    * @param x the X coordinate of the upper left corner of the component
263    * @param y the Y coordinate of the upper left corner of the component
264    * @param width the width of the component
265    * @param height the height of the component
266    */
267   public void reshape(int x, int y, int width, int height)
268   {
269     Insets i = insets;
270     xwindow.move_resize(x - i.left, y - i.right, width - i.left - i.right,
271                         height - i.top - i.bottom);
272   }
273
274   public Insets insets()
275   {
276     return (Insets) insets.clone();
277   }
278
279   /**
280    * Returns the font metrics for the specified font.
281    *
282    * @return the font metrics for the specified font
283    */
284   public FontMetrics getFontMetrics(Font font)
285   {
286     ClasspathFontPeer fontPeer = (ClasspathFontPeer) font.getPeer();
287     return fontPeer.getFontMetrics(font);
288   }
289
290   /**
291    * Unregisters the window in the event pump when it is closed.
292    */
293   protected void finalize()
294   {
295     XGraphicsDevice dev = XToolkit.getDefaultDevice();
296     dev.getEventPump().unregisterWindow(xwindow);
297   }
298   
299   public Window getXwindow()
300   {
301     return xwindow;
302   }
303 }