summaryrefslogtreecommitdiff
path: root/libjava/jni
diff options
context:
space:
mode:
authordjee <djee@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-26 21:55:42 +0000
committerdjee <djee@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-26 21:55:42 +0000
commit7dad6107052ba818bebd1084b6c6b7c4a73313cc (patch)
tree9ab7045766c5842438bf57c60f381f2d8dce8bb0 /libjava/jni
parent7deff5bef7928d09f41d33f6d4ea4efb5042407c (diff)
downloadlinaro-gcc-7dad6107052ba818bebd1084b6c6b7c4a73313cc.tar.gz
linaro-gcc-7dad6107052ba818bebd1084b6c6b7c4a73313cc.tar.bz2
linaro-gcc-7dad6107052ba818bebd1084b6c6b7c4a73313cc.zip
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@76668 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/jni')
-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
2 files changed, 89 insertions, 6 deletions
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 1966227c650..725c89ebd7d 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 6004847c369..64b2995ffbc 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: