mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-18 12:41:25 +08:00
2004-01-26 David Jee <djee@redhat.com>
* gnu/java/awt/peer/gtk/GtkComponentPeer.java (handleEvent): Implemented. Handles PaintEvents. (paint): Implemented. Use GTK native methods to queue updates for this heavyweight peer. * gnu/java/awt/peer/gtk/GtkContainerPeer.java (handleEvent): Removed. * java/awt/Component.java (paint): Implemented. Explictly paint the heavyweight peer. (update): Clear the background for heavyweight components. (paintAll): No need to call peer.paint() anymore. (processEvent): Don't process PaintEvents here. It's now done in the peer's handleEvent(). (processPaintEvent): Removed. * java/awt/Container.java (paint): No need to call super.paint(). Visit heavyweight children as well. (update): Don't clear the background here. It's done in Component.update(). (visitChildren): Added check to not recurse into Containers. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c (filter_expose_event_handler): New method. Filter unwanted expose events while painting heavyweight peers. (Java_gnu_java_awt_peer_gtk_GtkComponentPeer_addExposeFilter): New method. Connect filter and block pre_event_handler. (Java_gnu_java_awt_peer_gtk_GtkComponentPeer_removeExposeFilter): New method. Disconnect filter and unblock pre_event_handler. (Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetQueueDrawArea): New method. Invalidate and update given area. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c (pre_event_handler): Add checks for unwanted expose events. From-SVN: r76668
This commit is contained in:
parent
81a88a6157
commit
7edbd87e17
@ -1,3 +1,36 @@
|
||||
2004-01-26 David Jee <djee@redhat.com>
|
||||
|
||||
* gnu/java/awt/peer/gtk/GtkComponentPeer.java
|
||||
(handleEvent): Implemented. Handles PaintEvents.
|
||||
(paint): Implemented. Use GTK native methods to queue updates
|
||||
for this heavyweight peer.
|
||||
* gnu/java/awt/peer/gtk/GtkContainerPeer.java
|
||||
(handleEvent): Removed.
|
||||
* java/awt/Component.java
|
||||
(paint): Implemented. Explictly paint the heavyweight peer.
|
||||
(update): Clear the background for heavyweight components.
|
||||
(paintAll): No need to call peer.paint() anymore.
|
||||
(processEvent): Don't process PaintEvents here. It's now done in
|
||||
the peer's handleEvent().
|
||||
(processPaintEvent): Removed.
|
||||
* java/awt/Container.java
|
||||
(paint): No need to call super.paint(). Visit heavyweight
|
||||
children as well.
|
||||
(update): Don't clear the background here. It's done in
|
||||
Component.update().
|
||||
(visitChildren): Added check to not recurse into Containers.
|
||||
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
|
||||
(filter_expose_event_handler): New method. Filter unwanted
|
||||
expose events while painting heavyweight peers.
|
||||
(Java_gnu_java_awt_peer_gtk_GtkComponentPeer_addExposeFilter):
|
||||
New method. Connect filter and block pre_event_handler.
|
||||
(Java_gnu_java_awt_peer_gtk_GtkComponentPeer_removeExposeFilter):
|
||||
New method. Disconnect filter and unblock pre_event_handler.
|
||||
(Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetQueueDrawArea):
|
||||
New method. Invalidate and update given area.
|
||||
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
|
||||
(pre_event_handler): Add checks for unwanted expose events.
|
||||
|
||||
2004-01-26 David Jee <djee@redhat.com>
|
||||
|
||||
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
|
||||
|
@ -91,6 +91,9 @@ public class GtkComponentPeer extends GtkGenericPeer
|
||||
native void gtkWidgetSetCursor (int type);
|
||||
native void gtkWidgetSetBackground (int red, int green, int blue);
|
||||
native void gtkWidgetSetForeground (int red, int green, int blue);
|
||||
native void gtkWidgetQueueDrawArea(int x, int y, int width, int height);
|
||||
native void addExposeFilter();
|
||||
native void removeExposeFilter();
|
||||
|
||||
void create ()
|
||||
{
|
||||
@ -217,6 +220,37 @@ public class GtkComponentPeer extends GtkGenericPeer
|
||||
|
||||
public void handleEvent (AWTEvent event)
|
||||
{
|
||||
int id = event.getID();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case PaintEvent.PAINT:
|
||||
case PaintEvent.UPDATE:
|
||||
{
|
||||
try
|
||||
{
|
||||
Graphics g = getGraphics ();
|
||||
|
||||
// Some peers like GtkFileDialogPeer are repainted by Gtk itself
|
||||
if (g == null)
|
||||
break;
|
||||
|
||||
g.setClip (((PaintEvent)event).getUpdateRect());
|
||||
|
||||
if (id == PaintEvent.PAINT)
|
||||
awtComponent.paint (g);
|
||||
else
|
||||
awtComponent.update (g);
|
||||
|
||||
g.dispose ();
|
||||
}
|
||||
catch (InternalError e)
|
||||
{
|
||||
System.err.println (e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFocusTraversable ()
|
||||
@ -235,7 +269,21 @@ public class GtkComponentPeer extends GtkGenericPeer
|
||||
|
||||
public void paint (Graphics g)
|
||||
{
|
||||
awtComponent.paint (g);
|
||||
Component parent = awtComponent.getParent();
|
||||
GtkComponentPeer parentPeer = null;
|
||||
if ((parent instanceof Container) && !parent.isLightweight())
|
||||
parentPeer = (GtkComponentPeer) parent.getPeer();
|
||||
|
||||
addExposeFilter();
|
||||
if (parentPeer != null)
|
||||
parentPeer.addExposeFilter();
|
||||
|
||||
Rectangle clip = g.getClipBounds();
|
||||
gtkWidgetQueueDrawArea(clip.x, clip.y, clip.width, clip.height);
|
||||
|
||||
removeExposeFilter();
|
||||
if (parentPeer != null)
|
||||
parentPeer.removeExposeFilter();
|
||||
}
|
||||
|
||||
public Dimension preferredSize ()
|
||||
|
@ -100,41 +100,6 @@ public class GtkContainerPeer extends GtkComponentPeer
|
||||
return new GdkGraphics (this);
|
||||
}
|
||||
|
||||
public void handleEvent (AWTEvent event)
|
||||
{
|
||||
int id = event.getID();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case PaintEvent.PAINT:
|
||||
case PaintEvent.UPDATE:
|
||||
{
|
||||
try
|
||||
{
|
||||
Graphics g = getGraphics ();
|
||||
|
||||
// Some peers like GtkFileDialogPeer are repainted by Gtk itself
|
||||
if (g == null)
|
||||
break;
|
||||
|
||||
g.setClip (((PaintEvent)event).getUpdateRect());
|
||||
|
||||
if (id == PaintEvent.PAINT)
|
||||
awtComponent.paint (g);
|
||||
else
|
||||
awtComponent.update (g);
|
||||
|
||||
g.dispose ();
|
||||
}
|
||||
catch (InternalError e)
|
||||
{
|
||||
System.err.println (e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void beginLayout () { }
|
||||
public void endLayout () { }
|
||||
public boolean isPaintPending () { return false; }
|
||||
|
@ -1702,6 +1702,9 @@ public abstract class Component
|
||||
*/
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
// Paint the heavyweight peer
|
||||
if (!isLightweight() && peer != null)
|
||||
peer.paint(g);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1719,6 +1722,15 @@ public abstract class Component
|
||||
*/
|
||||
public void update(Graphics g)
|
||||
{
|
||||
if (!isLightweight())
|
||||
{
|
||||
Rectangle clip = g.getClipBounds();
|
||||
if (clip == null)
|
||||
g.clearRect(0, 0, width, height);
|
||||
else
|
||||
g.clearRect(clip.x, clip.y, clip.width, clip.height);
|
||||
}
|
||||
|
||||
paint(g);
|
||||
}
|
||||
|
||||
@ -1732,8 +1744,6 @@ public abstract class Component
|
||||
{
|
||||
if (! visible)
|
||||
return;
|
||||
if (peer != null)
|
||||
peer.paint(g);
|
||||
paint(g);
|
||||
}
|
||||
|
||||
@ -2787,8 +2797,6 @@ public abstract class Component
|
||||
|
||||
if (e instanceof FocusEvent)
|
||||
processFocusEvent((FocusEvent) e);
|
||||
else if (e instanceof PaintEvent)
|
||||
processPaintEvent((PaintEvent) e);
|
||||
else if (e instanceof MouseWheelEvent)
|
||||
processMouseWheelEvent((MouseWheelEvent) e);
|
||||
else if (e instanceof MouseEvent)
|
||||
@ -4224,42 +4232,6 @@ p * <li>the set of backward traversal keys
|
||||
return newEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the work for a paint event.
|
||||
*
|
||||
* @param event the event to process
|
||||
*/
|
||||
private void processPaintEvent(PaintEvent event)
|
||||
{
|
||||
// Can't do graphics without peer
|
||||
if (peer == null)
|
||||
return;
|
||||
|
||||
Graphics gfx = getGraphics();
|
||||
try
|
||||
{
|
||||
Shape clip = event.getUpdateRect();
|
||||
gfx.setClip(clip);
|
||||
|
||||
switch (event.id)
|
||||
{
|
||||
case PaintEvent.PAINT:
|
||||
paint(gfx);
|
||||
break;
|
||||
case PaintEvent.UPDATE:
|
||||
update(gfx);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown paint event");
|
||||
}
|
||||
event.consume ();
|
||||
}
|
||||
finally
|
||||
{
|
||||
gfx.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to implement transferFocus(). CHILD is the child
|
||||
* making the request. This is overridden by Container; when called for an
|
||||
|
@ -663,8 +663,9 @@ public class Container extends Component
|
||||
{
|
||||
if (!isShowing())
|
||||
return;
|
||||
super.paint(g);
|
||||
visitChildren(g, GfxPaintVisitor.INSTANCE, true);
|
||||
// Visit heavyweights as well, in case they were
|
||||
// erased when we cleared the background for this container.
|
||||
visitChildren(g, GfxPaintVisitor.INSTANCE, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -678,11 +679,6 @@ public class Container extends Component
|
||||
*/
|
||||
public void update(Graphics g)
|
||||
{
|
||||
Rectangle clip = g.getClipBounds();
|
||||
if (clip == null)
|
||||
g.clearRect(0, 0, width, height);
|
||||
else
|
||||
g.clearRect(clip.x, clip.y, clip.width, clip.height);
|
||||
super.update(g);
|
||||
}
|
||||
|
||||
@ -1204,8 +1200,12 @@ public class Container extends Component
|
||||
for (int i = ncomponents - 1; i >= 0; --i)
|
||||
{
|
||||
Component comp = component[i];
|
||||
// If we're visiting heavyweights as well,
|
||||
// don't recurse into Containers here. This avoids
|
||||
// painting the same nested child multiple times.
|
||||
boolean applicable = comp.isVisible()
|
||||
&& (comp.isLightweight() || !lightweightOnly);
|
||||
&& (comp.isLightweight()
|
||||
|| !lightweightOnly && ! (comp instanceof Container));
|
||||
|
||||
if (applicable)
|
||||
visitChild(gfx, visitor, comp);
|
||||
|
@ -575,6 +575,80 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2Ljava_lang_O
|
||||
(*env)->ReleaseStringUTFChars (env, jname, name);
|
||||
}
|
||||
|
||||
gboolean
|
||||
filter_expose_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
|
||||
{
|
||||
// Prevent the default event handler from getting this signal if applicable
|
||||
// FIXME: I came up with these filters by looking for patterns in the unwanted
|
||||
// expose events that are fed back to us from gtk/X. Perhaps there is
|
||||
// a way to prevent them from occuring in the first place.
|
||||
if (event->type == GDK_EXPOSE && (!GTK_IS_LAYOUT(widget)
|
||||
|| event->any.window != widget->window))
|
||||
{
|
||||
g_signal_stop_emission_by_name(GTK_OBJECT(widget), "event");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// There may be non-expose events that are triggered while we're
|
||||
// painting a heavyweight peer.
|
||||
return pre_event_handler(widget, event, peer);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_addExposeFilter
|
||||
(JNIEnv *env, jobject obj)
|
||||
{
|
||||
void *ptr = NSA_GET_PTR (env, obj);
|
||||
jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
|
||||
g_assert (gref);
|
||||
|
||||
gdk_threads_enter ();
|
||||
|
||||
g_signal_handlers_block_by_func (GTK_OBJECT(ptr), *pre_event_handler, *gref);
|
||||
g_signal_connect( GTK_OBJECT(ptr), "event",
|
||||
G_CALLBACK(filter_expose_event_handler), *gref);
|
||||
|
||||
gdk_threads_leave ();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_removeExposeFilter
|
||||
(JNIEnv *env, jobject obj)
|
||||
{
|
||||
void *ptr = NSA_GET_PTR (env, obj);
|
||||
jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
|
||||
g_assert (gref);
|
||||
|
||||
gdk_threads_enter ();
|
||||
|
||||
g_signal_handlers_disconnect_by_func (GTK_OBJECT(ptr),
|
||||
*filter_expose_event_handler, *gref);
|
||||
g_signal_handlers_unblock_by_func (GTK_OBJECT(ptr), *pre_event_handler, *gref);
|
||||
|
||||
gdk_threads_leave ();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetQueueDrawArea
|
||||
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
void *ptr;
|
||||
|
||||
ptr = NSA_GET_PTR (env, obj);
|
||||
|
||||
rect.x = x + GTK_WIDGET(ptr)->allocation.x;
|
||||
rect.y = y + GTK_WIDGET(ptr)->allocation.y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
gdk_threads_enter ();
|
||||
|
||||
gdk_window_invalidate_rect (GTK_WIDGET (ptr)->window, &rect, 0);
|
||||
gdk_window_process_all_updates();
|
||||
|
||||
gdk_threads_leave ();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectJObject
|
||||
(JNIEnv *env, jobject obj)
|
||||
{
|
||||
|
@ -1012,12 +1012,21 @@ pre_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
|
||||
break;
|
||||
case GDK_EXPOSE:
|
||||
{
|
||||
(*gdk_env)->CallVoidMethod (gdk_env, peer,
|
||||
postExposeEventID,
|
||||
(jint)event->expose.area.x,
|
||||
(jint)event->expose.area.y,
|
||||
(jint)event->expose.area.width,
|
||||
(jint)event->expose.area.height);
|
||||
// This filters out unwanted feedback expose events from gtk/X
|
||||
// when we explictly invalidate and update heavyweight components,
|
||||
// thus avoiding an infinite loop.
|
||||
// FIXME: I'm not quite sure why we're getting these expose events.
|
||||
// Maybe there is a way to avoid them?
|
||||
if((event->any.window == widget->window && event->any.send_event)
|
||||
|| GTK_IS_LAYOUT(widget))
|
||||
{
|
||||
(*gdk_env)->CallVoidMethod (gdk_env, peer,
|
||||
postExposeEventID,
|
||||
(jint)event->expose.area.x,
|
||||
(jint)event->expose.area.y,
|
||||
(jint)event->expose.area.width,
|
||||
(jint)event->expose.area.height);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GDK_FOCUS_CHANGE:
|
||||
|
Loading…
x
Reference in New Issue
Block a user