123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601 |
- /* Copyright (C) 2000, 2002, 2003 Free Software Foundation
- This file is part of libgcj.
- This software is copyrighted work licensed under the terms of the
- Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
- details. */
- package gnu.awt.xlib;
- import java.awt.Dimension;
- import java.awt.BufferCapabilities;
- import java.awt.Component;
- import java.awt.EventQueue;
- import java.awt.Rectangle;
- import java.awt.Color;
- import java.awt.Container;
- import java.awt.Image;
- import java.awt.GraphicsConfiguration;
- import java.awt.Font;
- import java.awt.FontMetrics;
- import java.awt.Graphics;
- import java.awt.Point;
- import java.awt.Toolkit;
- import java.awt.AWTEvent;
- import java.awt.Cursor;
- import java.awt.Shape;
- import java.awt.peer.*;
- import java.awt.image.*;
- import java.awt.event.MouseListener;
- import java.awt.event.PaintEvent;
- import java.util.EventListener;
- import gnu.gcj.xlib.WMSizeHints;
- import gnu.gcj.xlib.Window;
- import gnu.gcj.xlib.WindowAttributes;
- import gnu.gcj.xlib.Display;
- import gnu.gcj.xlib.Visual;
- import gnu.gcj.xlib.Screen;
- import gnu.gcj.xlib.XImage;
- import gnu.awt.j2d.*;
- import sun.awt.CausedFocusEvent;
- public class XCanvasPeer implements CanvasPeer
- {
- static final Dimension MIN_SIZE = new Dimension(1, 1);
-
- public // temporary
-
- Window window;
- Window parent;
- Component component;
- XGraphicsConfiguration config;
- private WindowAttributes attributes = new WindowAttributes();
- private long eventMask;
-
- public XCanvasPeer(Component component)
- {
- this.component = component;
-
- // Set up graphics configuration (ie. screen + visual):
- config = (XGraphicsConfiguration)
- component.getGraphicsConfiguration();
- if (config == null)
- {
- // This will usually only happen for toplevel windows
- config = getXToolkit().getDefaultXGraphicsConfiguration();
- }
- Rectangle bounds = component.getBounds();
- parent = locateParentWindow(bounds);
-
- // Windows in X must atleast be of size 1x1
- boolean boundsChanged = false;
- if (bounds.width < 1)
- {
- boundsChanged = true;
- bounds.width = 1;
- }
- if (bounds.height < 1)
- {
- boundsChanged = true;
- bounds.height = 1;
- }
-
- /* don't worry about this calling back to us, since the real
- component object has not yet received a reference to this peer
- object. */
- component.setBounds(bounds);
-
- /* Set background color */
- Color bg = component.getBackground();
- if (bg != null)
- {
- int[] components =
- {
- bg.getRed(),
- bg.getGreen(),
- bg.getBlue(),
- 0xff
- };
- ColorModel cm = config.getColorModel();
- long pixel = cm.getDataElement(components, 0);
- attributes.setBackground(pixel);
- }
-
- /* Set exposure mask so that we get exposure events
- that can be translated into paint() calls. */
- long eventMask = WindowAttributes.MASK_EXPOSURE;
- /* It would be nice to set up all other required events here, but
- it is not possible to do so before after all the children of
- this component has been realized. The reason is that it is not
- determined whether a component is lightweight before after the
- addNotify() method has been called. Thus, it is not possible
- for parent component to determine what events it needs to
- furnish for lightweight children. Instead, we currently rely
- on the component calling our setEventMask() method after the
- correct event mask has been determined. */
- attributes.setEventMask(eventMask);
-
-
- // TODO: set more window attributes?
- /* don't allow event queue to process events from the newly
- created window before this peer has been registered as client
- data. */
- synchronized (getXToolkit().eventLoop)
- {
- window = new gnu.gcj.xlib.Window(parent, bounds, attributes);
- window.setClientData(this); /* make it possible to find back
- to this peer object. Used by
- XEventQueue. */
- }
-
- initWindowProperties();
- if (component.isVisible())
- EventQueue.invokeLater(new DoMap(window));
- }
- /**
- * Override this in subclasses to implement other ways of obtaining
- * parent windows. Toplevel windows will typically have a different
- * implementation.
- */
- gnu.gcj.xlib.Window locateParentWindow(Rectangle bounds)
- {
- Container parent = component.getParent();
- while (parent.isLightweight())
- {
- bounds.x += parent.getX();
- bounds.y += parent.getY();
- parent = parent.getParent();
- // a null pointer here is a genuine error
- }
-
- XCanvasPeer parentPeer = (XCanvasPeer) parent.getPeer();
- if (parentPeer == null)
- throw new NullPointerException("Parent has no peer. This should " +
- "not be possible, since the " +
- "calls leading here should come " +
- "from parent, after it has " +
- "set the parent peer.");
- return parentPeer.window;
- }
-
- /**
- * Template method to allow subclasses to apply properties to X11
- * window right after creation.
- */
- void initWindowProperties()
- {
- }
-
- XToolkit getXToolkit()
- {
- return XToolkit.INSTANCE;
- }
- protected void ensureFlush()
- {
- getXToolkit().flushIfIdle();
- }
- public Component getComponent()
- {
- return component;
- }
-
- long getBasicEventMask()
- {
- return WindowAttributes.MASK_EXPOSURE;
- }
-
- // -------- java.awt.peer.ComponentPeer implementation
- public int checkImage(Image img, int width, int height, ImageObserver o)
- {
- throw new UnsupportedOperationException("FIXME, not implemented");
- }
- public Image createImage(ImageProducer prod)
- {
- return new XOffScreenImage (config, window, prod, config.getColorModel());
- }
- public Image createImage(int width, int height)
- {
- return new XOffScreenImage (config, window, width, height, config.getColorModel());
- }
- public void dispose()
- {
- throw new UnsupportedOperationException("FIXME, not implemented");
- }
- public GraphicsConfiguration getGraphicsConfiguration()
- {
- return config;
- }
- public FontMetrics getFontMetrics(Font f)
- {
- throw new UnsupportedOperationException("FIXME, not implemented");
- }
- public ColorModel getColorModel ()
- {
- return null;
- }
- public Graphics getGraphics()
- {
- DirectRasterGraphics gfxDevice = new XGraphics(window, config);
- IntegerGraphicsState igState = new IntegerGraphicsState(gfxDevice);
- Graphics2DImpl gfx2d = new Graphics2DImpl(config);
- gfx2d.setState(igState);
- gfx2d.setColor(component.getBackground());
- return gfx2d;
- }
- private Rectangle locationBounds;
- public Point getLocationOnScreen()
- {
- locationBounds = window.getBounds (locationBounds);
- return new Point (locationBounds.x,locationBounds.y);
- }
- public Dimension getMinimumSize ()
- {
- return MIN_SIZE;
- }
- public Dimension minimumSize ()
- {
- return getMinimumSize ();
- }
- public Dimension getPreferredSize ()
- {
- return component.getSize();
- }
-
- public Dimension preferredSize ()
- {
- return getPreferredSize();
- }
-
- public Toolkit getToolkit()
- {
- return getXToolkit();
- }
- public void handleEvent(AWTEvent event)
- {
- int id = event.getID ();
-
- switch (id)
- {
- case PaintEvent.PAINT:
- case PaintEvent.UPDATE:
- {
- try
- {
- Graphics g = getGraphics ();
- g.setClip (((PaintEvent)event).getUpdateRect ());
-
- if (id == PaintEvent.PAINT)
- component.paint (g);
- else
- component.update (g);
-
- g.dispose ();
- }
- catch (InternalError e)
- {
- System.err.println (e);
- }
- }
- break;
- }
- }
- public boolean isFocusTraversable()
- {
- throw new UnsupportedOperationException("FIXME, not implemented");
- }
- public void paint(Graphics gfx)
- {
- // do nothing by default
- }
-
- public boolean prepareImage(Image img, int width, int height,
- ImageObserver o)
- {
- throw new UnsupportedOperationException("FIXME, not implemented");
- }
- public void print(Graphics graphics)
- {
- paint(graphics);
- }
- public void repaint(long tm, int x, int y, int w, int h)
- {
- /* TODO?
- X allows intelligent X servers to do smart
- refreshing. Perhaps involve X in repainting of components,
- rather that keeping it all within the local event queue. */
-
- PaintEvent updateEvent = new PaintEvent(component,
- PaintEvent.UPDATE,
- new Rectangle(x, y, w, h));
- getXToolkit().queue.postEvent(updateEvent);
- }
-
- public void requestFocus()
- {
- throw new UnsupportedOperationException("FIXME, not implemented");
- }
- public void setBackground(Color color)
- {
- if (color != null)
- {
- int[] components =
- {
- color.getRed (),
- color.getGreen (),
- color.getBlue (),
- 0xff
- };
-
- ColorModel cm = config.getColorModel ();
- long pixel = cm.getDataElement (components, 0);
- attributes.setBackground (pixel);
- window.setAttributes (attributes);
- }
- }
- public void setBounds(int x, int y, int width, int height)
- {
- width = Math.max(width, 1);
- height = Math.max(height, 1);
- window.setBounds(x, y, width, height);
- ensureFlush();
- }
-
- public void reshape (int x, int y, int width, int height)
- {
- setBounds (x, y, width, height);
- }
- public void setCursor(Cursor cursor)
- {
- throw new UnsupportedOperationException("FIXME, not implemented");
- }
- public void setEnabled(boolean enabled)
- {
- throw new UnsupportedOperationException("FIXME, not implemented");
- }
- public void enable ()
- {
- setEnabled (true);
- }
- public void disable ()
- {
- setEnabled (false);
- }
- public void setEventMask(long eventMask)
- {
- if (this.eventMask != eventMask)
- {
- this.eventMask = eventMask;
- long xEventMask = getBasicEventMask ();
-
- if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)
- {
- xEventMask |=
- WindowAttributes.MASK_BUTTON_PRESS |
- WindowAttributes.MASK_BUTTON_RELEASE;
- }
-
- attributes.setEventMask (xEventMask);
- window.setAttributes (attributes);
- ensureFlush ();
- }
- }
- public void setFont(Font font)
- {
- /* default canvas peer does not keep track of font, since it won't
- paint anything. */
- }
- public void setForeground(Color color)
- {
- /* default canvas peer does not keep track of foreground, since it won't
- paint anything. */
- }
-
- public void setVisible(boolean visible)
- {
- if (visible)
- {
- window.map();
- ensureFlush();
- }
- else
- {
- window.unmap();
- ensureFlush();
- }
- }
-
- public void show ()
- {
- setVisible (true);
- }
- public void hide ()
- {
- setVisible (false);
- }
- public boolean isFocusable ()
- {
- return false;
- }
- public boolean requestFocus (Component source, boolean b1,
- boolean b2, long x)
- {
- return false;
- }
- public boolean requestFocus (Component source, boolean b1,
- boolean b2, long x,
- CausedFocusEvent.Cause cause)
- {
- return false;
- }
- public boolean isObscured ()
- {
- return false;
- }
- public boolean canDetermineObscurity ()
- {
- return false;
- }
- public void coalescePaintEvent (PaintEvent e)
- {
- }
- public void updateCursorImmediately ()
- {
- }
- public VolatileImage createVolatileImage (int width, int height)
- {
- return null;
- }
- public boolean handlesWheelScrolling ()
- {
- return false;
- }
- public void createBuffers (int x, BufferCapabilities capabilities)
- throws java.awt.AWTException
- {
- }
- public Image getBackBuffer ()
- {
- return null;
- }
- public void flip (BufferCapabilities.FlipContents contents)
- {
- }
- public void destroyBuffers ()
- {
- }
- static class DoMap implements Runnable
- {
- Window window;
- public DoMap(Window w)
- {
- this.window = w;
- }
-
- public void run()
- {
- window.map();
- }
- }
- /**
- * @since 1.5
- */
- public boolean isRestackSupported ()
- {
- return false;
- }
- /**
- * @since 1.5
- */
- public void cancelPendingPaint (int x, int y, int width, int height)
- {
- }
- /**
- * @since 1.5
- */
- public void restack ()
- {
- }
- /**
- * @since 1.5
- */
- public Rectangle getBounds ()
- {
- return null;
- }
- /**
- * @since 1.5
- */
- public void reparent (ContainerPeer parent)
- {
- }
- /**
- * @since 1.5
- */
- public void setBounds (int x, int y, int width, int height, int z)
- {
- }
- /**
- * @since 1.5
- */
- public boolean isReparentSupported ()
- {
- return false;
- }
- /**
- * @since 1.5
- */
- public void layout ()
- {
- }
- }
|