XCanvasPeer.java (attributes): New field.

2005-07-15  Scott Gilbertson  <scottg@mantatest.com>

	* gnu/awt/xlib/XCanvasPeer.java (attributes): New field.
	(eventMask): New field.
	(XCanvasPeer(Component)): Use attributes field.
	(setBackground): Implemented.
	(setEventMask): Process mask only if changed.
	* gnu/awt/xlib/XEventLoop.java (class): Iplement Runnable.
	(eventLoopThread): New field.
	(XEventLoop(Display,EventQueue)): Start eventLoopThread.
	(interrupt): Removed.
	(run): New method.
	* gnu/awt/xlib/XEventQueue.java (getNextEvent): Process Container
	and Component events.
	* gnu/awt/xlib/XFramePeer.java (processingConfigureNotify): New
	field.
	(configureNotify): Set and clear processingConfigureNotify.
	(setBounds): Process only if processingConfigureNotify is false.
	(toBack): Implemented.
	(toFront): Implemented.
	* gnu/awt/xlib/XGraphics.java (setColor): Ignore null color.
	* gnu/awt/xlib/XGraphicsConfiguration.java (getPixel): Ignore null
	color.
	* gnu/awt/xlib/XToolkit.java (nativeQueueEmpty): Always return true.
	(wakeNativeQueue): Do nothing.
	(iterateNativeQueue): Do queue.wait if blocking.
	* gnu/gcj/xlib/Font.java (loadFont): New method.
	(loadFontImpl): Renamed native method, was loadFont.
	* gnu/gcj/xlib/Window.java (toFront): New method.
	(toBack): New method.
	* gnu/gcj/xlib/natFont.cc (loadFontImpl): Renamed method, was
	loadFont.
	* gnu/gcj/xlib/natWindow.cc (toBack): New method.
	(toFront): New method.
	* gnu/gcj/xlib/natXAnyEvent.cc (loadNext): Removed timeout.

From-SVN: r102057
This commit is contained in:
Scott Gilbertson 2005-07-15 16:07:18 +00:00 committed by Scott Gilbertson
parent 27811bfe0a
commit e27d6202c0
13 changed files with 229 additions and 64 deletions

View File

@ -1,3 +1,39 @@
2005-07-15 Scott Gilbertson <scottg@mantatest.com>
* gnu/awt/xlib/XCanvasPeer.java (attributes): New field.
(eventMask): New field.
(XCanvasPeer(Component)): Use attributes field.
(setBackground): Implemented.
(setEventMask): Process mask only if changed.
* gnu/awt/xlib/XEventLoop.java (class): Iplement Runnable.
(eventLoopThread): New field.
(XEventLoop(Display,EventQueue)): Start eventLoopThread.
(interrupt): Removed.
(run): New method.
* gnu/awt/xlib/XEventQueue.java (getNextEvent): Process Container
and Component events.
* gnu/awt/xlib/XFramePeer.java (processingConfigureNotify): New
field.
(configureNotify): Set and clear processingConfigureNotify.
(setBounds): Process only if processingConfigureNotify is false.
(toBack): Implemented.
(toFront): Implemented.
* gnu/awt/xlib/XGraphics.java (setColor): Ignore null color.
* gnu/awt/xlib/XGraphicsConfiguration.java (getPixel): Ignore null
color.
* gnu/awt/xlib/XToolkit.java (nativeQueueEmpty): Always return true.
(wakeNativeQueue): Do nothing.
(iterateNativeQueue): Do queue.wait if blocking.
* gnu/gcj/xlib/Font.java (loadFont): New method.
(loadFontImpl): Renamed native method, was loadFont.
* gnu/gcj/xlib/Window.java (toFront): New method.
(toBack): New method.
* gnu/gcj/xlib/natFont.cc (loadFontImpl): Renamed method, was
loadFont.
* gnu/gcj/xlib/natWindow.cc (toBack): New method.
(toFront): New method.
* gnu/gcj/xlib/natXAnyEvent.cc (loadNext): Removed timeout.
2005-07-14 Andrew Haley <aph@redhat.com>
* gnu/java/net/protocol/file/Connection.java (unquote): New

View File

@ -55,6 +55,8 @@ public class XCanvasPeer implements CanvasPeer
Component component;
XGraphicsConfiguration config;
private WindowAttributes attributes = new WindowAttributes();
private long eventMask;
public XCanvasPeer(Component component)
{
@ -92,7 +94,6 @@ public class XCanvasPeer implements CanvasPeer
object. */
component.setBounds(bounds);
WindowAttributes attributes = new WindowAttributes();
/* Set background color */
Color bg = component.getBackground();
@ -349,8 +350,21 @@ public class XCanvasPeer implements CanvasPeer
public void setBackground(Color color)
{
/* default canvas peer does not keep track of background, since it won't
* paint anything. */
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)
@ -388,20 +402,22 @@ public class XCanvasPeer implements CanvasPeer
public void setEventMask(long eventMask)
{
WindowAttributes attributes = new WindowAttributes();
long xEventMask = getBasicEventMask();
if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)
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;
xEventMask |=
WindowAttributes.MASK_BUTTON_PRESS |
WindowAttributes.MASK_BUTTON_RELEASE;
}
attributes.setEventMask(xEventMask);
window.setAttributes(attributes);
ensureFlush();
attributes.setEventMask (xEventMask);
window.setAttributes (attributes);
ensureFlush ();
}
}
public void setFont(Font font)

View File

@ -21,12 +21,13 @@ import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.util.Vector;
public class XEventLoop
public class XEventLoop implements Runnable
{
Display display;
EventQueue queue;
XAnyEvent anyEvent;
private Thread eventLoopThread;
LightweightRedirector lightweightRedirector = new LightweightRedirector();
public XEventLoop(Display display, EventQueue queue)
@ -35,13 +36,17 @@ public class XEventLoop
this.queue = queue;
anyEvent = new XAnyEvent(display);
eventLoopThread = new Thread(this, "AWT thread for XEventLoop");
eventLoopThread.start();
}
void interrupt()
public void run ()
{
anyEvent.interrupt();
// FIXME: do we need an interrupt mechanism for window shutdown?
while (true)
postNextEvent (true);
}
/** If there's an event available, post it.
* @return true if an event was posted
*/
@ -65,7 +70,7 @@ public class XEventLoop
AWTEvent event = null;
if (loadNextEvent(block))
{
event = createEvent();
event = createEvent();
event = lightweightRedirector.redirect(event);
}
return event;

View File

@ -8,12 +8,16 @@ details. */
package gnu.awt.xlib;
import java.awt.*;
import gnu.gcj.xlib.Display;
import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.event.ComponentEvent;
import java.awt.event.ContainerEvent;
/**
* The only difference here from a standard EventQueue is that the X
* The main difference here from a standard EventQueue is that the X
* display connection is flushed before waiting for more events.
*/
public class XEventQueue extends EventQueue
@ -29,6 +33,67 @@ public class XEventQueue extends EventQueue
{
if ((peekEvent() == null) && (display != null))
display.flush();
return super.getNextEvent();
AWTEvent event = super.getNextEvent();
if (event != null)
{
switch (event.getID ())
{
case ContainerEvent.COMPONENT_ADDED:
{
/* If a component has been added to a container, it needs to be
* invalidated, to ensure that it ultimately gets an addNotify.
* If it's not invalidated, the component will never display in
* an already-showing container (probably applies only to CardLayout).
* Perhaps this code should be in java.awt, but the problem only seems
* to happen with xlib peers (not with gtk peers) so it's here instead.
*/
ContainerEvent ce = (ContainerEvent)event;
ce.getChild ().invalidate ();
ce.getContainer ().validate ();
}
break;
case ComponentEvent.COMPONENT_RESIZED:
{
ComponentEvent ce = (ComponentEvent)event;
// FIXME: there may be opportunities to coalesce resize events
ce.getComponent ().validate ();
}
break;
case ComponentEvent.COMPONENT_SHOWN:
{
ComponentEvent ce = (ComponentEvent)event;
Component comp = ce.getComponent ();
if (!comp.isValid ())
{
/* Try to validate, going up the tree to the highest-level invalid
* Container. The idea is to ensure that addNotify gets called for
* any non-top-level component being shown, to make it create a peer.
*/
Container parent = comp.getParent ();
while (parent != null)
{
Container next = parent.getParent ();
if (next == null || next.isValid ())
{
parent.validate ();
break;
}
else
parent = next;
}
if (comp instanceof Container)
comp.validate ();
}
comp.repaint ();
}
break;
default:
break;
}
}
return event;
}
}

View File

@ -22,7 +22,8 @@ import gnu.gcj.xlib.XConfigureEvent;
public class XFramePeer extends XCanvasPeer implements FramePeer
{
private boolean processingConfigureNotify = false;
public XFramePeer(Frame frame)
{
super(frame);
@ -62,28 +63,24 @@ public class XFramePeer extends XCanvasPeer implements FramePeer
void configureNotify(XConfigureEvent configEvent)
{
processingConfigureNotify = true; // to avoid setBounds flood
component.setBounds(configEvent.getBounds());
/* FIXME: Validation should probably not be done here. The best
strategy is probably to validate on the AWT thread in response
to an ComponentEvent. This will make it possible to coalesce
resize validations. */
component.validate();
processingConfigureNotify = false;
}
/* Overridden to ignore request to set bounds if the request occurs
on the X event loop thread. It is assumed that all requests that
occur on the X event loop thread are results of XConfigureNotify
events, in which case the X window already has the desired
bounds. */
while processing an XConfigureNotify event, in which case the X
window already has the desired bounds.
That's what java.awt.Window.setBoundsCallback is for, but it's
package-private, and using our own flag eliminates the need to
circumvent java security.
*/
public void setBounds(int x, int y, int width, int height)
{
if (EventQueue.isDispatchThread())
return;
super.setBounds(x, y, width, height);
if (!processingConfigureNotify)
super.setBounds(x, y, width, height);
}
// Implementing ContainerPeer:
static final Insets INSETS_0_PROTOTYPE = new Insets(0, 0, 0, 0);
@ -114,12 +111,12 @@ public class XFramePeer extends XCanvasPeer implements FramePeer
public void toBack()
{
throw new UnsupportedOperationException("not implemented yet");
window.toBack ();
}
public void toFront()
{
throw new UnsupportedOperationException("not implemented yet");
window.toFront ();
}

View File

@ -83,7 +83,8 @@ public class XGraphics implements Cloneable, DirectRasterGraphics
public void setColor(Color color)
{
context.setForeground(config.getPixel(color));
if (color != null)
context.setForeground(config.getPixel(color));
}
public void setPaintMode()

View File

@ -522,17 +522,20 @@ public class XGraphicsConfiguration extends GraphicsConfiguration
};
*/
float[] normalizedComponents =
{
((float)color.getRed ()) / 255F,
((float)color.getGreen ()) / 255F,
((float)color.getBlue ()) / 255F,
1
};
int[] unnormalizedComponents = { 0, 0, 0, 0xff };
ColorModel cm = getColorModel ();
cm.getUnnormalizedComponents(normalizedComponents, 0,
unnormalizedComponents, 0);
if (color != null)
{
float[] normalizedComponents =
{
((float)color.getRed ()) / 255F,
((float)color.getGreen ()) / 255F,
((float)color.getBlue ()) / 255F,
1
};
cm.getUnnormalizedComponents(normalizedComponents, 0,
unnormalizedComponents, 0);
}
return cm.getDataElement (unnormalizedComponents, 0);
}
}

View File

@ -445,13 +445,16 @@ public class XToolkit extends ClasspathToolkit
}
public boolean nativeQueueEmpty()
{
return eventLoop.isIdle();
{
// Tell EventQueue the native queue is empty, because XEventLoop
// separately ensures that native events are posted to AWT.
return true;
}
public void wakeNativeQueue()
{
eventLoop.interrupt();
// Not implemented, because the native queue is always awake.
// (i.e. it's polled in a thread separate from the AWT dispatch thread)
}
/** Checks the native event queue for events. If blocking, waits until an
@ -464,6 +467,18 @@ public class XToolkit extends ClasspathToolkit
*/
public void iterateNativeQueue(java.awt.EventQueue locked, boolean block)
{
eventLoop.postNextEvent(block);
}
// There is nothing to do here except block, because XEventLoop
// iterates the queue in a dedicated thread.
if (block)
{
try
{
queue.wait ();
}
catch (InterruptedException ie)
{
// InterruptedException intentionally ignored
}
}
};
}

View File

@ -34,7 +34,21 @@ public final class Font extends XID
structure = struct;
}
static native RawData loadFont(Display display, String lfdNamePattern);
static RawData loadFont(Display display, String lfdNamePattern)
{
RawData returnValue = null;
try
{
returnValue = loadFontImpl (display,lfdNamePattern);
}
catch (XException e)
{
// Throw a descriptive exception, including the font pattern
throw new XException ("Font not found: " + lfdNamePattern);
}
return returnValue;
}
static native RawData loadFontImpl(Display display, String lfdNamePattern);
static native int getXIDFromStruct(RawData structure);

View File

@ -73,6 +73,8 @@ public class Window extends Drawable
public native void map();
public native void unmap();
public native void toFront();
public native void toBack();
protected boolean owned = false;

View File

@ -16,7 +16,7 @@ details. */
#include <gnu/gcj/xlib/Font.h>
#include <gnu/gcj/xlib/XException.h>
gnu::gcj::RawData* gnu::gcj::xlib::Font::loadFont(Display* display,
gnu::gcj::RawData* gnu::gcj::xlib::Font::loadFontImpl(Display* display,
jstring lfdNamePattern)
{
::Display* dpy = (::Display*) display->display;

View File

@ -77,6 +77,20 @@ void gnu::gcj::xlib::Window::setAttributes(WindowAttributes* attributes)
// no fast fail
}
void gnu::gcj::xlib::Window::toBack()
{
::Display* dpy = (::Display*) (display->display);
::Window window = xid;
XLowerWindow(dpy, window);
}
void gnu::gcj::xlib::Window::toFront()
{
::Display* dpy = (::Display*) (display->display);
::Window window = xid;
XRaiseWindow(dpy, window);
}
void gnu::gcj::xlib::Window::map()
{
::Display* dpy = (::Display*) (display->display);

View File

@ -69,14 +69,11 @@ jboolean gnu::gcj::xlib::XAnyEvent::loadNext(jboolean block)
int xfd = XConnectionNumber(dpy);
int pipefd = pipe[0];
int n = (xfd > pipefd ? xfd : pipefd) + 1;
struct timeval timeout;
timeout.tv_usec = 100000; // 100ms timeout
timeout.tv_sec = 0;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(xfd, &rfds);
FD_SET(pipefd, &rfds);
int sel = _Jv_select (n, &rfds, NULL, NULL, &timeout);
int sel = _Jv_select (n, &rfds, NULL, NULL, NULL);
if (sel > 0)
{
if (FD_ISSET(xfd, &rfds))