Commit e27d6202 by Scott Gilbertson Committed by Scott Gilbertson

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
parent 27811bfe
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> 2005-07-14 Andrew Haley <aph@redhat.com>
* gnu/java/net/protocol/file/Connection.java (unquote): New * gnu/java/net/protocol/file/Connection.java (unquote): New
......
...@@ -55,6 +55,8 @@ public class XCanvasPeer implements CanvasPeer ...@@ -55,6 +55,8 @@ public class XCanvasPeer implements CanvasPeer
Component component; Component component;
XGraphicsConfiguration config; XGraphicsConfiguration config;
private WindowAttributes attributes = new WindowAttributes();
private long eventMask;
public XCanvasPeer(Component component) public XCanvasPeer(Component component)
{ {
...@@ -92,7 +94,6 @@ public class XCanvasPeer implements CanvasPeer ...@@ -92,7 +94,6 @@ public class XCanvasPeer implements CanvasPeer
object. */ object. */
component.setBounds(bounds); component.setBounds(bounds);
WindowAttributes attributes = new WindowAttributes();
/* Set background color */ /* Set background color */
Color bg = component.getBackground(); Color bg = component.getBackground();
...@@ -349,8 +350,21 @@ public class XCanvasPeer implements CanvasPeer ...@@ -349,8 +350,21 @@ public class XCanvasPeer implements CanvasPeer
public void setBackground(Color color) public void setBackground(Color color)
{ {
/* default canvas peer does not keep track of background, since it won't if (color != null)
* paint anything. */ {
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) public void setBounds(int x, int y, int width, int height)
...@@ -388,20 +402,22 @@ public class XCanvasPeer implements CanvasPeer ...@@ -388,20 +402,22 @@ public class XCanvasPeer implements CanvasPeer
public void setEventMask(long eventMask) public void setEventMask(long eventMask)
{ {
WindowAttributes attributes = new WindowAttributes(); if (this.eventMask != eventMask)
{
long xEventMask = getBasicEventMask(); this.eventMask = eventMask;
long xEventMask = getBasicEventMask ();
if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)
if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)
{ {
xEventMask |= xEventMask |=
WindowAttributes.MASK_BUTTON_PRESS | WindowAttributes.MASK_BUTTON_PRESS |
WindowAttributes.MASK_BUTTON_RELEASE; WindowAttributes.MASK_BUTTON_RELEASE;
} }
attributes.setEventMask(xEventMask); attributes.setEventMask (xEventMask);
window.setAttributes(attributes); window.setAttributes (attributes);
ensureFlush(); ensureFlush ();
}
} }
public void setFont(Font font) public void setFont(Font font)
......
...@@ -21,12 +21,13 @@ import java.awt.event.InputEvent; ...@@ -21,12 +21,13 @@ import java.awt.event.InputEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.Vector; import java.util.Vector;
public class XEventLoop public class XEventLoop implements Runnable
{ {
Display display; Display display;
EventQueue queue; EventQueue queue;
XAnyEvent anyEvent; XAnyEvent anyEvent;
private Thread eventLoopThread;
LightweightRedirector lightweightRedirector = new LightweightRedirector(); LightweightRedirector lightweightRedirector = new LightweightRedirector();
public XEventLoop(Display display, EventQueue queue) public XEventLoop(Display display, EventQueue queue)
...@@ -35,13 +36,17 @@ public class XEventLoop ...@@ -35,13 +36,17 @@ public class XEventLoop
this.queue = queue; this.queue = queue;
anyEvent = new XAnyEvent(display); 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. /** If there's an event available, post it.
* @return true if an event was posted * @return true if an event was posted
*/ */
...@@ -65,7 +70,7 @@ public class XEventLoop ...@@ -65,7 +70,7 @@ public class XEventLoop
AWTEvent event = null; AWTEvent event = null;
if (loadNextEvent(block)) if (loadNextEvent(block))
{ {
event = createEvent(); event = createEvent();
event = lightweightRedirector.redirect(event); event = lightweightRedirector.redirect(event);
} }
return event; return event;
......
...@@ -8,12 +8,16 @@ details. */ ...@@ -8,12 +8,16 @@ details. */
package gnu.awt.xlib; package gnu.awt.xlib;
import java.awt.*;
import gnu.gcj.xlib.Display; 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. * display connection is flushed before waiting for more events.
*/ */
public class XEventQueue extends EventQueue public class XEventQueue extends EventQueue
...@@ -29,6 +33,67 @@ public class XEventQueue extends EventQueue ...@@ -29,6 +33,67 @@ public class XEventQueue extends EventQueue
{ {
if ((peekEvent() == null) && (display != null)) if ((peekEvent() == null) && (display != null))
display.flush(); 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;
} }
} }
...@@ -22,7 +22,8 @@ import gnu.gcj.xlib.XConfigureEvent; ...@@ -22,7 +22,8 @@ import gnu.gcj.xlib.XConfigureEvent;
public class XFramePeer extends XCanvasPeer implements FramePeer public class XFramePeer extends XCanvasPeer implements FramePeer
{ {
private boolean processingConfigureNotify = false;
public XFramePeer(Frame frame) public XFramePeer(Frame frame)
{ {
super(frame); super(frame);
...@@ -62,28 +63,24 @@ public class XFramePeer extends XCanvasPeer implements FramePeer ...@@ -62,28 +63,24 @@ public class XFramePeer extends XCanvasPeer implements FramePeer
void configureNotify(XConfigureEvent configEvent) void configureNotify(XConfigureEvent configEvent)
{ {
processingConfigureNotify = true; // to avoid setBounds flood
component.setBounds(configEvent.getBounds()); component.setBounds(configEvent.getBounds());
processingConfigureNotify = false;
/* 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();
} }
/* Overridden to ignore request to set bounds if the request occurs /* Overridden to ignore request to set bounds if the request occurs
on the X event loop thread. It is assumed that all requests that while processing an XConfigureNotify event, in which case the X
occur on the X event loop thread are results of XConfigureNotify window already has the desired bounds.
events, in which case the X window already has the desired That's what java.awt.Window.setBoundsCallback is for, but it's
bounds. */ 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) public void setBounds(int x, int y, int width, int height)
{ {
if (EventQueue.isDispatchThread()) if (!processingConfigureNotify)
return; super.setBounds(x, y, width, height);
super.setBounds(x, y, width, height);
} }
// Implementing ContainerPeer: // Implementing ContainerPeer:
static final Insets INSETS_0_PROTOTYPE = new Insets(0, 0, 0, 0); static final Insets INSETS_0_PROTOTYPE = new Insets(0, 0, 0, 0);
...@@ -114,12 +111,12 @@ public class XFramePeer extends XCanvasPeer implements FramePeer ...@@ -114,12 +111,12 @@ public class XFramePeer extends XCanvasPeer implements FramePeer
public void toBack() public void toBack()
{ {
throw new UnsupportedOperationException("not implemented yet"); window.toBack ();
} }
public void toFront() public void toFront()
{ {
throw new UnsupportedOperationException("not implemented yet"); window.toFront ();
} }
......
...@@ -83,7 +83,8 @@ public class XGraphics implements Cloneable, DirectRasterGraphics ...@@ -83,7 +83,8 @@ public class XGraphics implements Cloneable, DirectRasterGraphics
public void setColor(Color color) public void setColor(Color color)
{ {
context.setForeground(config.getPixel(color)); if (color != null)
context.setForeground(config.getPixel(color));
} }
public void setPaintMode() public void setPaintMode()
......
...@@ -522,17 +522,20 @@ public class XGraphicsConfiguration extends GraphicsConfiguration ...@@ -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 }; int[] unnormalizedComponents = { 0, 0, 0, 0xff };
ColorModel cm = getColorModel (); ColorModel cm = getColorModel ();
cm.getUnnormalizedComponents(normalizedComponents, 0, if (color != null)
unnormalizedComponents, 0); {
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); return cm.getDataElement (unnormalizedComponents, 0);
} }
} }
...@@ -445,13 +445,16 @@ public class XToolkit extends ClasspathToolkit ...@@ -445,13 +445,16 @@ public class XToolkit extends ClasspathToolkit
} }
public boolean nativeQueueEmpty() 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() 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 /** Checks the native event queue for events. If blocking, waits until an
...@@ -464,6 +467,18 @@ public class XToolkit extends ClasspathToolkit ...@@ -464,6 +467,18 @@ public class XToolkit extends ClasspathToolkit
*/ */
public void iterateNativeQueue(java.awt.EventQueue locked, boolean block) 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
}
}
};
} }
...@@ -34,7 +34,21 @@ public final class Font extends XID ...@@ -34,7 +34,21 @@ public final class Font extends XID
structure = struct; 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); static native int getXIDFromStruct(RawData structure);
......
...@@ -73,6 +73,8 @@ public class Window extends Drawable ...@@ -73,6 +73,8 @@ public class Window extends Drawable
public native void map(); public native void map();
public native void unmap(); public native void unmap();
public native void toFront();
public native void toBack();
protected boolean owned = false; protected boolean owned = false;
......
...@@ -16,7 +16,7 @@ details. */ ...@@ -16,7 +16,7 @@ details. */
#include <gnu/gcj/xlib/Font.h> #include <gnu/gcj/xlib/Font.h>
#include <gnu/gcj/xlib/XException.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) jstring lfdNamePattern)
{ {
::Display* dpy = (::Display*) display->display; ::Display* dpy = (::Display*) display->display;
......
...@@ -77,6 +77,20 @@ void gnu::gcj::xlib::Window::setAttributes(WindowAttributes* attributes) ...@@ -77,6 +77,20 @@ void gnu::gcj::xlib::Window::setAttributes(WindowAttributes* attributes)
// no fast fail // 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() void gnu::gcj::xlib::Window::map()
{ {
::Display* dpy = (::Display*) (display->display); ::Display* dpy = (::Display*) (display->display);
......
...@@ -69,14 +69,11 @@ jboolean gnu::gcj::xlib::XAnyEvent::loadNext(jboolean block) ...@@ -69,14 +69,11 @@ jboolean gnu::gcj::xlib::XAnyEvent::loadNext(jboolean block)
int xfd = XConnectionNumber(dpy); int xfd = XConnectionNumber(dpy);
int pipefd = pipe[0]; int pipefd = pipe[0];
int n = (xfd > pipefd ? xfd : pipefd) + 1; int n = (xfd > pipefd ? xfd : pipefd) + 1;
struct timeval timeout;
timeout.tv_usec = 100000; // 100ms timeout
timeout.tv_sec = 0;
fd_set rfds; fd_set rfds;
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(xfd, &rfds); FD_SET(xfd, &rfds);
FD_SET(pipefd, &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 (sel > 0)
{ {
if (FD_ISSET(xfd, &rfds)) if (FD_ISSET(xfd, &rfds))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment