2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / gnu / awt / xlib / XCanvasPeer.java
blob6ecf7bf3296e03d77a727dd9c671041cea020e02
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
7 details. */
9 package gnu.awt.xlib;
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;
20 import java.awt.Font;
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;
45 import gnu.awt.j2d.*;
47 public class XCanvasPeer implements CanvasPeer
49 static final Dimension MIN_SIZE = new Dimension(1, 1);
51 public // temporary
53 Window window;
54 Window parent;
56 Component component;
57 XGraphicsConfiguration config;
59 public XCanvasPeer(Component component)
61 this.component = component;
63 // Set up graphics configuration (ie. screen + visual):
65 config = (XGraphicsConfiguration)
66 component.getGraphicsConfiguration();
68 if (config == null)
70 // This will usually only happen for toplevel windows
71 config = getXToolkit().getDefaultXGraphicsConfiguration();
74 Rectangle bounds = component.getBounds();
75 parent = locateParentWindow(bounds);
77 // Windows in X must atleast be of size 1x1
78 boolean boundsChanged = false;
79 if (bounds.width < 1)
81 boundsChanged = true;
82 bounds.width = 1;
84 if (bounds.height < 1)
86 boundsChanged = true;
87 bounds.height = 1;
90 /* don't worry about this calling back to us, since the real
91 component object has not yet received a reference to this peer
92 object. */
93 component.setBounds(bounds);
95 WindowAttributes attributes = new WindowAttributes();
97 /* Set background color */
98 Color bg = component.getBackground();
99 if (bg != null)
101 int[] components =
103 bg.getRed(),
104 bg.getGreen(),
105 bg.getBlue(),
106 0xff
109 ColorModel cm = config.getColorModel();
110 long pixel = cm.getDataElement(components, 0);
111 attributes.setBackground(pixel);
114 /* Set exposure mask so that we get exposure events
115 that can be translated into paint() calls. */
116 long eventMask = WindowAttributes.MASK_EXPOSURE;
118 /* It would be nice to set up all other required events here, but
119 it is not possible to do so before after all the children of
120 this component has been realized. The reason is that it is not
121 determined whether a component is lightweight before after the
122 addNotify() method has been called. Thus, it is not possible
123 for parent component to determine what events it needs to
124 furnish for lightweight children. Instead, we currently rely
125 on the component calling our setEventMask() method after the
126 correct event mask has been determined. */
128 attributes.setEventMask(eventMask);
131 // TODO: set more window attributes?
133 /* don't allow event queue to process events from the newly
134 created window before this peer has been registered as client
135 data. */
136 synchronized (getXToolkit().eventLoop)
138 window = new gnu.gcj.xlib.Window(parent, bounds, attributes);
139 window.setClientData(this); /* make it possible to find back
140 to this peer object. Used by
141 XEventQueue. */
144 initWindowProperties();
146 if (component.isVisible())
147 EventQueue.invokeLater(new DoMap(window));
151 * Override this in subclasses to implement other ways of obtaining
152 * parent windows. Toplevel windows will typically have a different
153 * implementation.
155 gnu.gcj.xlib.Window locateParentWindow(Rectangle bounds)
157 Container parent = component.getParent();
158 while (parent.isLightweight())
160 bounds.x += parent.getX();
161 bounds.y += parent.getY();
162 parent = parent.getParent();
163 // a null pointer here is a genuine error
166 XCanvasPeer parentPeer = (XCanvasPeer) parent.getPeer();
167 if (parentPeer == null)
168 throw new NullPointerException("Parent has no peer. This should " +
169 "not be possible, since the " +
170 "calls leading here should come " +
171 "from parent, after it has " +
172 "set the parent peer.");
173 return parentPeer.window;
177 /**
178 * Template method to allow subclasses to apply properties to X11
179 * window right after creation.
181 void initWindowProperties()
185 XToolkit getXToolkit()
187 return XToolkit.INSTANCE;
190 protected void ensureFlush()
192 getXToolkit().flushIfIdle();
195 public Component getComponent()
197 return component;
200 long getBasicEventMask()
202 return WindowAttributes.MASK_EXPOSURE;
205 // -------- java.awt.peer.ComponentPeer implementation
207 public int checkImage(Image img, int width, int height, ImageObserver o)
209 throw new UnsupportedOperationException("FIXME, not implemented");
211 public Image createImage(ImageProducer prod)
213 throw new UnsupportedOperationException("FIXME, not implemented");
215 public Image createImage(int width, int height)
217 return new XOffScreenImage (config, window, width, height);
219 public void dispose()
221 throw new UnsupportedOperationException("FIXME, not implemented");
224 public GraphicsConfiguration getGraphicsConfiguration()
226 return config;
229 public FontMetrics getFontMetrics(Font f)
231 throw new UnsupportedOperationException("FIXME, not implemented");
234 public ColorModel getColorModel ()
236 return null;
239 public Graphics getGraphics()
241 DirectRasterGraphics gfxDevice = new XGraphics(window, config);
242 IntegerGraphicsState igState = new IntegerGraphicsState(gfxDevice);
243 Graphics2DImpl gfx2d = new Graphics2DImpl(config);
245 gfx2d.setState(igState);
246 gfx2d.setColor(component.getBackground());
247 return gfx2d;
250 public Point getLocationOnScreen()
252 throw new UnsupportedOperationException("FIXME, not implemented");
255 public Dimension getMinimumSize ()
257 return MIN_SIZE;
260 public Dimension minimumSize ()
262 return getMinimumSize ();
265 public Dimension getPreferredSize ()
267 return component.getSize();
270 public Dimension preferredSize ()
272 return getPreferredSize();
275 public Toolkit getToolkit()
277 return getXToolkit();
280 public void handleEvent(AWTEvent event)
284 public boolean isFocusTraversable()
286 throw new UnsupportedOperationException("FIXME, not implemented");
289 public void paint(Graphics gfx)
291 // do nothing by default
294 public boolean prepareImage(Image img, int width, int height,
295 ImageObserver o)
297 throw new UnsupportedOperationException("FIXME, not implemented");
300 public void print(Graphics graphics)
302 paint(graphics);
305 public void repaint(long tm, int x, int y, int w, int h)
307 /* TODO?
309 X allows intelligent X servers to do smart
310 refreshing. Perhaps involve X in repainting of components,
311 rather that keeping it all within the local event queue. */
313 PaintEvent updateEvent = new PaintEvent(component,
314 PaintEvent.UPDATE,
315 new Rectangle(x, y, w, h));
316 getXToolkit().queue.postEvent(updateEvent);
319 public void requestFocus()
321 throw new UnsupportedOperationException("FIXME, not implemented");
324 public void setBackground(Color color)
326 throw new UnsupportedOperationException("not implemented");
329 public void setBounds(int x, int y, int width, int height)
331 width = Math.max(width, 1);
332 height = Math.max(height, 1);
333 window.setBounds(x, y, width, height);
334 ensureFlush();
337 public void reshape (int x, int y, int width, int height)
339 setBounds (x, y, width, height);
342 public void setCursor(Cursor cursor)
344 throw new UnsupportedOperationException("FIXME, not implemented");
347 public void setEnabled(boolean enabled)
349 throw new UnsupportedOperationException("FIXME, not implemented");
352 public void enable ()
354 setEnabled (true);
357 public void disable ()
359 setEnabled (false);
362 public void setEventMask(long eventMask)
364 WindowAttributes attributes = new WindowAttributes();
366 long xEventMask = getBasicEventMask();
368 if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)
370 xEventMask |=
371 WindowAttributes.MASK_BUTTON_PRESS |
372 WindowAttributes.MASK_BUTTON_RELEASE;
375 attributes.setEventMask(xEventMask);
376 window.setAttributes(attributes);
377 ensureFlush();
380 public void setFont(Font font)
382 /* default canvas peer does keep track of font, since it won't
383 write anything. */
386 public void setForeground(Color color)
388 /* default canvas peer does keep track of foreground, since it won't
389 paint anything. */
392 public void setVisible(boolean visible)
394 if (visible)
396 window.map();
397 ensureFlush();
399 else
401 throw new UnsupportedOperationException("unmap not implemented");
405 public void show ()
407 setVisible (true);
410 public void hide ()
412 setVisible (false);
415 public boolean isFocusable ()
417 return false;
420 public boolean requestFocus (Component source, boolean b1,
421 boolean b2, long x)
423 return false;
426 public boolean isObscured ()
428 return false;
431 public boolean canDetermineObscurity ()
433 return false;
436 public void coalescePaintEvent (PaintEvent e)
440 public void updateCursorImmediately ()
444 public VolatileImage createVolatileImage (int width, int height)
446 return null;
449 public boolean handlesWheelScrolling ()
451 return false;
454 public void createBuffers (int x, BufferCapabilities capabilities)
455 throws java.awt.AWTException
460 public Image getBackBuffer ()
462 return null;
465 public void flip (BufferCapabilities.FlipContents contents)
469 public void destroyBuffers ()
473 static class DoMap implements Runnable
475 Window window;
476 public DoMap(Window w)
478 this.window = w;
481 public void run()
483 window.map();