diff options
author | Rolf W. Rasmussen <rolfwr@ii.uib.no> | 2000-10-22 19:46:09 +0200 |
---|---|---|
committer | Rolf Rasmussen <rolfwr@gcc.gnu.org> | 2000-10-22 17:46:09 +0000 |
commit | 2622c79d2d51f6bf9122a3b5f458daa50c0baf19 (patch) | |
tree | 1165199489e8bc851f2bb5c11ff0228f3667453e /libjava/gnu/awt/xlib/XEventLoop.java | |
parent | 9b95cc4a34af1148dc18c7912ab77f19a753bf80 (diff) | |
download | gcc-2622c79d2d51f6bf9122a3b5f458daa50c0baf19.zip gcc-2622c79d2d51f6bf9122a3b5f458daa50c0baf19.tar.gz gcc-2622c79d2d51f6bf9122a3b5f458daa50c0baf19.tar.bz2 |
Makefile.am: Added rules for libgcjx library.
* Makefile.am: Added rules for libgcjx library.
* Makefile.in: Rebuilt.
* configure.in: Added check for X.
* configure: Rebuilt.
* gnu/awt/LightweightRedirector.java: New file.
* gnu/awt/j2d/AbstractGraphicsState.java: New file.
* gnu/awt/j2d/DirectRasterGraphics.java: New file.
* gnu/awt/j2d/Graphics2DImpl.java: New file.
* gnu/awt/j2d/IntegerGraphicsState.java: New file.
* gnu/awt/j2d/MappedRaster.java: New file.
* gnu/awt/xlib/XCanvasPeer.java: New file.
* gnu/awt/xlib/XEventLoop.java: New file.
* gnu/awt/xlib/XEventQueue.java: New file.
* gnu/awt/xlib/XFontMetrics.java: New file.
* gnu/awt/xlib/XFramePeer.java: New file.
* gnu/awt/xlib/XGraphics.java: New file.
* gnu/awt/xlib/XGraphicsConfiguration.java: New file.
* gnu/awt/xlib/XPanelPeer.java: New file.
* gnu/awt/xlib/XToolkit.java: New file.
* gnu/gcj/xlib/Clip.java: New file.
* gnu/gcj/xlib/Colormap.java: New file.
* gnu/gcj/xlib/Display.java: New file.
* gnu/gcj/xlib/Drawable.java: New file.
* gnu/gcj/xlib/Font.java: New file.
* gnu/gcj/xlib/GC.java: New file.
* gnu/gcj/xlib/Pixmap.java: New file.
* gnu/gcj/xlib/Screen.java: New file.
* gnu/gcj/xlib/Visual.java: New file.
* gnu/gcj/xlib/WMSizeHints.java: New file.
* gnu/gcj/xlib/Window.java: New file.
* gnu/gcj/xlib/WindowAttributes.java: New file.
* gnu/gcj/xlib/XAnyEvent.java: New file.
* gnu/gcj/xlib/XButtonEvent.java: New file.
* gnu/gcj/xlib/XColor.java: New file.
* gnu/gcj/xlib/XConfigureEvent.java: New file.
* gnu/gcj/xlib/XConnectException.java: New file.
* gnu/gcj/xlib/XEvent.java: New file.
* gnu/gcj/xlib/XException.java: New file.
* gnu/gcj/xlib/XExposeEvent.java: New file.
* gnu/gcj/xlib/XID.java: New file.
* gnu/gcj/xlib/XImage.java: New file.
* gnu/gcj/xlib/XUnmapEvent.java: New file.
* gnu/gcj/xlib/natClip.cc: New file.
* gnu/gcj/xlib/natColormap.cc: New file.
* gnu/gcj/xlib/natDisplay.cc: New file.
* gnu/gcj/xlib/natDrawable.cc: New file.
* gnu/gcj/xlib/natFont.cc: New file.
* gnu/gcj/xlib/natGC.cc: New file.
* gnu/gcj/xlib/natPixmap.cc: New file.
* gnu/gcj/xlib/natScreen.cc: New file.
* gnu/gcj/xlib/natVisual.cc: New file.
* gnu/gcj/xlib/natWMSizeHints.cc: New file.
* gnu/gcj/xlib/natWindow.cc: New file.
* gnu/gcj/xlib/natWindowAttributes.cc: New file.
* gnu/gcj/xlib/natXAnyEvent.cc: New file.
* gnu/gcj/xlib/natXButtonEvent.cc: New file.
* gnu/gcj/xlib/natXColor.cc: New file.
* gnu/gcj/xlib/natXConfigureEvent.cc: New file.
* gnu/gcj/xlib/natXException.cc: New file.
* gnu/gcj/xlib/natXExposeEvent.cc: New file.
* gnu/gcj/xlib/natXImage.cc: New file.
* gnu/gcj/xlib/natXUnmapEvent.cc: New file.
* java/awt/EventDispatchThread.java: Start thead on creation.
From-SVN: r37005
Diffstat (limited to 'libjava/gnu/awt/xlib/XEventLoop.java')
-rw-r--r-- | libjava/gnu/awt/xlib/XEventLoop.java | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/libjava/gnu/awt/xlib/XEventLoop.java b/libjava/gnu/awt/xlib/XEventLoop.java new file mode 100644 index 0000000..4d29320 --- /dev/null +++ b/libjava/gnu/awt/xlib/XEventLoop.java @@ -0,0 +1,268 @@ +package gnu.awt.xlib; + +/* Copyright (C) 2000 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. */ + +import java.awt.*; + +import gnu.awt.LightweightRedirector; +import gnu.gcj.xlib.Display; +import gnu.gcj.xlib.XAnyEvent; +import gnu.gcj.xlib.XExposeEvent; +import gnu.gcj.xlib.XButtonEvent; +import gnu.gcj.xlib.XConfigureEvent; +import java.awt.event.PaintEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.util.Vector; + +public class XEventLoop implements Runnable +{ + Display display; + EventQueue queue; + XAnyEvent anyEvent; + Thread eventLoopThread; + + LightweightRedirector lightweightRedirector = new LightweightRedirector(); + + public XEventLoop(Display display, EventQueue queue) + { + this.display = display; + this.queue = queue; + + anyEvent = new XAnyEvent(display); + eventLoopThread = new Thread(this, "AWT thread for XEventLoop"); + eventLoopThread.start(); + } + + public void run() + { + while (true) + postNextEvent(); + } + + void postNextEvent() + { + try + { + AWTEvent evt = getNextEvent(); + queue.postEvent(evt); + + } + catch (InterruptedException ie) + { + // FIXME: what now? + System.err.println(ie); + } + } + + /** get next event. Will block until events become available. */ + + public AWTEvent getNextEvent() + { + // ASSERT: + if (isIdle()) + throw new Error("should not be idle"); + + AWTEvent event = null; + while (event == null) + { + loadNextEvent(); + event = createEvent(); + } + + event = lightweightRedirector.redirect(event); + + return event; + } + + void loadNextEvent() + { + try + { + setIdle(true); + + /* The code below will result in an XFlush(). However, + while we are waiting for events after calling XFlush(), + new X requests issued on other threads will not + automatically be flushed. This can lead to a deadlock + since XFlush() will not be called before after the + processing of the next event, and new events arriving + might be dependent on the delivery of the X + requests. + + Code that issues X requests should therefore call + flushIfIdle() after they're done, to ensure that the + requests are delivered in a timely manner. XFlush is not + run if event processing is underway, since we are assured + that the event loop execution will return to this point, + where requests are flushed again, before waiting for new + events. + + Alternatively, do the work on the AWT thread, since the + XEventQueue knows how to flush the display when it runs out + of events. */ + + //display.flush(); // implicit? + anyEvent.loadNext(); + } + catch (RuntimeException re) + { + System.err.println("Exception thrown on event thread:" + re); + } + finally + { + setIdle(false); + } + } + + /** + * @returns an AWT event created based on the current XEvent. + * Returns null if the current XEvent does not map to any perticular + * AWT event. + */ + + AWTEvent createEvent() + { + /* avoid attempting to get client data before client data has + been set. */ + Object peer; + synchronized (this) + { + peer = anyEvent.getWindow().getClientData(); + } + + Component source = null; + + // Try to identify source component + + if (peer instanceof XCanvasPeer) + { + source = ((XCanvasPeer) peer).getComponent(); + } + + if (source == null) + { + String msg = "unable to locate source for event (" + + anyEvent + ")"; + throw new RuntimeException(msg); + } + + /* if a mapping from anyEvent to AWTEvent is possible, construct a + new AWTEvent and return it. */ + + int type = anyEvent.getType(); + switch (type) + { + case XAnyEvent.TYPE_EXPOSE: + return createPaintEvent(source); + case XAnyEvent.TYPE_BUTTON_PRESS: + case XAnyEvent.TYPE_BUTTON_RELEASE: + return createMouseEvent(type, source); + case XAnyEvent.TYPE_UNMAP_NOTIFY: + case XAnyEvent.TYPE_MAP_NOTIFY: + case XAnyEvent.TYPE_REPARENT_NOTIFY: + return null; // ignore for now + case XAnyEvent.TYPE_CONFIGURE_NOTIFY: + configureNotify(peer); + return null; + + default: + String msg = "Do no know how to handle event (" + anyEvent + ")"; + throw new RuntimeException(msg); + } + } + + AWTEvent createPaintEvent(Component src) + { + XExposeEvent expose = new XExposeEvent(anyEvent); + PaintEvent pe = new PaintEvent(src, PaintEvent.PAINT, + expose.getBounds()); + return pe; + } + + AWTEvent createMouseEvent(int type, Component src) + { + XButtonEvent buttonEvt = new XButtonEvent(anyEvent); + + int modifiers = 0; //buttonToModifierMap[buttonEvt.button]; + + /* Warning: this makes assumptions on the contents of + X.h... Button1 = 1, Button2 = 2, etc... */ + switch (buttonEvt.button) + { + case 1: + modifiers = InputEvent.BUTTON1_MASK; + break; + case 2: + modifiers = InputEvent.BUTTON2_MASK; + break; + case 3: + modifiers = InputEvent.BUTTON2_MASK; + break; + } + + int state = buttonEvt.state; + + // remap bits from state to modifiers: + + if ((state & XButtonEvent.MASK_SHIFT) != 0) + modifiers |= InputEvent.SHIFT_MASK; + + + if ((state & XButtonEvent.MASK_CONTROL) != 0) + modifiers |= InputEvent.CTRL_MASK; + + + /* FIXME: we need additional X code to properly map MODn states to + input modifiers */ + + int clickCount = 1; // FIXME... Can't get this from X. + boolean popupTrigger = false; // FIXME: look up policy somewhere + + int x = buttonEvt.x; + int y = buttonEvt.y; + + int id = (type == XAnyEvent.TYPE_BUTTON_PRESS) ? + MouseEvent.MOUSE_PRESSED : + MouseEvent.MOUSE_RELEASED; + + MouseEvent me = new MouseEvent(src, + id, + buttonEvt.time, modifiers, + buttonEvt.x, buttonEvt.y, + clickCount, popupTrigger); + return me; + } + + void configureNotify(Object peerObj) + { + XConfigureEvent configEvent = new XConfigureEvent(anyEvent); + XFramePeer peer = (XFramePeer) peerObj; + + peer.configureNotify(configEvent); + } + + public void flushIfIdle() + { + if (isIdle()) + display.flush(); + } + + volatile boolean idle = false; + + final synchronized void setIdle(boolean idle) + { + this.idle = idle; + } + + final synchronized boolean isIdle() + { + return idle; + } +} |