aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorDavid Jee <djee@redhat.com>2004-01-26 21:55:42 +0000
committerDavid Jee <djee@gcc.gnu.org>2004-01-26 21:55:42 +0000
commit7edbd87e17d9240077eed1993436365ad6c4365c (patch)
tree9ab7045766c5842438bf57c60f381f2d8dce8bb0 /libjava
parent81a88a6157451550a5753e436021523f93226fc9 (diff)
downloadgcc-7edbd87e17d9240077eed1993436365ad6c4365c.zip
gcc-7edbd87e17d9240077eed1993436365ad6c4365c.tar.gz
gcc-7edbd87e17d9240077eed1993436365ad6c4365c.tar.bz2
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
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog33
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java50
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java35
-rw-r--r--libjava/java/awt/Component.java52
-rw-r--r--libjava/java/awt/Container.java16
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c74
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c21
7 files changed, 191 insertions, 90 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 0e2e661..72c37c2 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,5 +1,38 @@
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
(find_bg_color_widget): For GtkButton, return its child.
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java
index 9a56619..4b29bcc 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java
@@ -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 ()
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java
index e888172..361dea7 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java
@@ -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; }
diff --git a/libjava/java/awt/Component.java b/libjava/java/awt/Component.java
index b440c51..87c73b5 100644
--- a/libjava/java/awt/Component.java
+++ b/libjava/java/awt/Component.java
@@ -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)
@@ -4225,42 +4233,6 @@ p * <li>the set of backward traversal keys
}
/**
- * 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
* ordinary component there is no child and so we always return null.
diff --git a/libjava/java/awt/Container.java b/libjava/java/awt/Container.java
index 5d176be..57cd833 100644
--- a/libjava/java/awt/Container.java
+++ b/libjava/java/awt/Container.java
@@ -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);
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
index 1966227..725c89e 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
@@ -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)
{
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
index 6004847..64b2995 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
@@ -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: