1 /* Copyright (C) 2000, 2002, 2003 Free Software Foundation
3 This file is part of libgcj.
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
11 import java
.awt
.Dimension
;
12 import java
.awt
.BufferCapabilities
;
13 import java
.awt
.Component
;
14 import java
.awt
.EventQueue
;
15 import java
.awt
.Rectangle
;
16 import java
.awt
.Color
;
17 import java
.awt
.Container
;
18 import java
.awt
.Image
;
19 import java
.awt
.GraphicsConfiguration
;
21 import java
.awt
.FontMetrics
;
22 import java
.awt
.Graphics
;
23 import java
.awt
.Point
;
24 import java
.awt
.Toolkit
;
25 import java
.awt
.AWTEvent
;
26 import java
.awt
.Cursor
;
27 import java
.awt
.Shape
;
29 import java
.awt
.peer
.*;
30 import java
.awt
.image
.*;
32 import java
.awt
.event
.MouseListener
;
33 import java
.awt
.event
.PaintEvent
;
35 import java
.util
.EventListener
;
37 import gnu
.gcj
.xlib
.WMSizeHints
;
38 import gnu
.gcj
.xlib
.Window
;
39 import gnu
.gcj
.xlib
.WindowAttributes
;
40 import gnu
.gcj
.xlib
.Display
;
41 import gnu
.gcj
.xlib
.Visual
;
42 import gnu
.gcj
.xlib
.Screen
;
43 import gnu
.gcj
.xlib
.XImage
;
47 import sun
.awt
.CausedFocusEvent
;
49 public class XCanvasPeer
implements CanvasPeer
51 static final Dimension MIN_SIZE
= new Dimension(1, 1);
59 XGraphicsConfiguration config
;
60 private WindowAttributes attributes
= new WindowAttributes();
61 private long eventMask
;
63 public XCanvasPeer(Component component
)
65 this.component
= component
;
67 // Set up graphics configuration (ie. screen + visual):
69 config
= (XGraphicsConfiguration
)
70 component
.getGraphicsConfiguration();
74 // This will usually only happen for toplevel windows
75 config
= getXToolkit().getDefaultXGraphicsConfiguration();
78 Rectangle bounds
= component
.getBounds();
79 parent
= locateParentWindow(bounds
);
81 // Windows in X must atleast be of size 1x1
82 boolean boundsChanged
= false;
88 if (bounds
.height
< 1)
94 /* don't worry about this calling back to us, since the real
95 component object has not yet received a reference to this peer
97 component
.setBounds(bounds
);
100 /* Set background color */
101 Color bg
= component
.getBackground();
112 ColorModel cm
= config
.getColorModel();
113 long pixel
= cm
.getDataElement(components
, 0);
114 attributes
.setBackground(pixel
);
117 /* Set exposure mask so that we get exposure events
118 that can be translated into paint() calls. */
119 long eventMask
= WindowAttributes
.MASK_EXPOSURE
;
121 /* It would be nice to set up all other required events here, but
122 it is not possible to do so before after all the children of
123 this component has been realized. The reason is that it is not
124 determined whether a component is lightweight before after the
125 addNotify() method has been called. Thus, it is not possible
126 for parent component to determine what events it needs to
127 furnish for lightweight children. Instead, we currently rely
128 on the component calling our setEventMask() method after the
129 correct event mask has been determined. */
131 attributes
.setEventMask(eventMask
);
134 // TODO: set more window attributes?
136 /* don't allow event queue to process events from the newly
137 created window before this peer has been registered as client
139 synchronized (getXToolkit().eventLoop
)
141 window
= new gnu
.gcj
.xlib
.Window(parent
, bounds
, attributes
);
142 window
.setClientData(this); /* make it possible to find back
143 to this peer object. Used by
147 initWindowProperties();
149 if (component
.isVisible())
150 EventQueue
.invokeLater(new DoMap(window
));
154 * Override this in subclasses to implement other ways of obtaining
155 * parent windows. Toplevel windows will typically have a different
158 gnu
.gcj
.xlib
.Window
locateParentWindow(Rectangle bounds
)
160 Container parent
= component
.getParent();
161 while (parent
.isLightweight())
163 bounds
.x
+= parent
.getX();
164 bounds
.y
+= parent
.getY();
165 parent
= parent
.getParent();
166 // a null pointer here is a genuine error
169 XCanvasPeer parentPeer
= (XCanvasPeer
) parent
.getPeer();
170 if (parentPeer
== null)
171 throw new NullPointerException("Parent has no peer. This should " +
172 "not be possible, since the " +
173 "calls leading here should come " +
174 "from parent, after it has " +
175 "set the parent peer.");
176 return parentPeer
.window
;
181 * Template method to allow subclasses to apply properties to X11
182 * window right after creation.
184 void initWindowProperties()
188 XToolkit
getXToolkit()
190 return XToolkit
.INSTANCE
;
193 protected void ensureFlush()
195 getXToolkit().flushIfIdle();
198 public Component
getComponent()
203 long getBasicEventMask()
205 return WindowAttributes
.MASK_EXPOSURE
;
208 // -------- java.awt.peer.ComponentPeer implementation
210 public int checkImage(Image img
, int width
, int height
, ImageObserver o
)
212 throw new UnsupportedOperationException("FIXME, not implemented");
214 public Image
createImage(ImageProducer prod
)
216 return new XOffScreenImage (config
, window
, prod
, config
.getColorModel());
218 public Image
createImage(int width
, int height
)
220 return new XOffScreenImage (config
, window
, width
, height
, config
.getColorModel());
222 public void dispose()
224 throw new UnsupportedOperationException("FIXME, not implemented");
227 public GraphicsConfiguration
getGraphicsConfiguration()
232 public FontMetrics
getFontMetrics(Font f
)
234 throw new UnsupportedOperationException("FIXME, not implemented");
237 public ColorModel
getColorModel ()
242 public Graphics
getGraphics()
244 DirectRasterGraphics gfxDevice
= new XGraphics(window
, config
);
245 IntegerGraphicsState igState
= new IntegerGraphicsState(gfxDevice
);
246 Graphics2DImpl gfx2d
= new Graphics2DImpl(config
);
248 gfx2d
.setState(igState
);
249 gfx2d
.setColor(component
.getBackground());
253 private Rectangle locationBounds
;
254 public Point
getLocationOnScreen()
256 locationBounds
= window
.getBounds (locationBounds
);
257 return new Point (locationBounds
.x
,locationBounds
.y
);
260 public Dimension
getMinimumSize ()
265 public Dimension
minimumSize ()
267 return getMinimumSize ();
270 public Dimension
getPreferredSize ()
272 return component
.getSize();
275 public Dimension
preferredSize ()
277 return getPreferredSize();
280 public Toolkit
getToolkit()
282 return getXToolkit();
285 public void handleEvent(AWTEvent event
)
287 int id
= event
.getID ();
291 case PaintEvent
.PAINT
:
292 case PaintEvent
.UPDATE
:
296 Graphics g
= getGraphics ();
297 g
.setClip (((PaintEvent
)event
).getUpdateRect ());
299 if (id
== PaintEvent
.PAINT
)
302 component
.update (g
);
306 catch (InternalError e
)
308 System
.err
.println (e
);
315 public boolean isFocusTraversable()
317 throw new UnsupportedOperationException("FIXME, not implemented");
320 public void paint(Graphics gfx
)
322 // do nothing by default
325 public boolean prepareImage(Image img
, int width
, int height
,
328 throw new UnsupportedOperationException("FIXME, not implemented");
331 public void print(Graphics graphics
)
336 public void repaint(long tm
, int x
, int y
, int w
, int h
)
340 X allows intelligent X servers to do smart
341 refreshing. Perhaps involve X in repainting of components,
342 rather that keeping it all within the local event queue. */
344 PaintEvent updateEvent
= new PaintEvent(component
,
346 new Rectangle(x
, y
, w
, h
));
347 getXToolkit().queue
.postEvent(updateEvent
);
350 public void requestFocus()
352 throw new UnsupportedOperationException("FIXME, not implemented");
355 public void setBackground(Color color
)
367 ColorModel cm
= config
.getColorModel ();
368 long pixel
= cm
.getDataElement (components
, 0);
369 attributes
.setBackground (pixel
);
370 window
.setAttributes (attributes
);
374 public void setBounds(int x
, int y
, int width
, int height
)
376 width
= Math
.max(width
, 1);
377 height
= Math
.max(height
, 1);
378 window
.setBounds(x
, y
, width
, height
);
382 public void reshape (int x
, int y
, int width
, int height
)
384 setBounds (x
, y
, width
, height
);
387 public void setCursor(Cursor cursor
)
389 throw new UnsupportedOperationException("FIXME, not implemented");
392 public void setEnabled(boolean enabled
)
394 throw new UnsupportedOperationException("FIXME, not implemented");
397 public void enable ()
402 public void disable ()
407 public void setEventMask(long eventMask
)
409 if (this.eventMask
!= eventMask
)
411 this.eventMask
= eventMask
;
412 long xEventMask
= getBasicEventMask ();
414 if ((eventMask
& AWTEvent
.MOUSE_EVENT_MASK
) != 0)
417 WindowAttributes
.MASK_BUTTON_PRESS
|
418 WindowAttributes
.MASK_BUTTON_RELEASE
;
421 attributes
.setEventMask (xEventMask
);
422 window
.setAttributes (attributes
);
427 public void setFont(Font font
)
429 /* default canvas peer does not keep track of font, since it won't
433 public void setForeground(Color color
)
435 /* default canvas peer does not keep track of foreground, since it won't
439 public void setVisible(boolean visible
)
463 public boolean isFocusable ()
468 public boolean requestFocus (Component source
, boolean b1
,
474 public boolean requestFocus (Component source
, boolean b1
,
476 CausedFocusEvent
.Cause cause
)
481 public boolean isObscured ()
486 public boolean canDetermineObscurity ()
491 public void coalescePaintEvent (PaintEvent e
)
495 public void updateCursorImmediately ()
499 public VolatileImage
createVolatileImage (int width
, int height
)
504 public boolean handlesWheelScrolling ()
509 public void createBuffers (int x
, BufferCapabilities capabilities
)
510 throws java
.awt
.AWTException
515 public Image
getBackBuffer ()
520 public void flip (BufferCapabilities
.FlipContents contents
)
524 public void destroyBuffers ()
528 static class DoMap
implements Runnable
531 public DoMap(Window w
)
545 public boolean isRestackSupported ()
553 public void cancelPendingPaint (int x
, int y
, int width
, int height
)
560 public void restack ()
567 public Rectangle
getBounds ()
575 public void reparent (ContainerPeer parent
)
582 public void setBounds (int x
, int y
, int width
, int height
, int z
)
589 public boolean isReparentSupported ()
597 public void layout ()