summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog21
-rw-r--r--gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java1
-rw-r--r--gnu/java/awt/peer/gtk/GtkComponentPeer.java16
-rw-r--r--gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java14
-rw-r--r--gnu/java/awt/peer/gtk/GtkWindowPeer.java11
-rw-r--r--include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h5
-rw-r--r--java/awt/Component.java56
-rw-r--r--java/awt/Container.java27
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c34
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c132
10 files changed, 279 insertions, 38 deletions
diff --git a/ChangeLog b/ChangeLog
index cf765c9ac..0074e0c32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2007-11-27 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java,
+ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
+ (isWindowUnderMouse): New method.
+ * include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h:
+ Regenerate.
+ * gnu/java/awt/peer/gtk/GtkComponentPeer.java
+ (getLocationOnScreen): Move WindowPeer section to...
+ * gnu/java/awt/peer/gtk/GtkWindowPeer.java (getLocationOnScreen):
+ New method.
+ * gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java
+ (isWindowUnderMouse): Implement.
+ * java/awt/Component.java (getMousePosition): New method.
+ (getMousePositionHelper): Likewise.
+ (mouseOverComponent): Likewise.
+ * java/awt/Container.java (getMousePosition): New method.
+ (mouseOverComponent): Likewise.
+ * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c:
+ Revert 2007-09-11 changes.
+
2007-11-27 Andrew John Hughes <gnu_andrew@member.fsf.org>
* javax/management/package.html: Added.
diff --git a/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
index 67040b82a..d06af8443 100644
--- a/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
+++ b/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
@@ -155,6 +155,7 @@ public class GdkGraphicsEnvironment extends ClasspathGraphicsEnvironment
* Used by GtkMouseInfoPeer.
*/
native int[] getMouseCoordinates();
+ native boolean isWindowUnderMouse(GtkWindowPeer windowPeer);
public WritableRaster createRaster(ColorModel cm, SampleModel sm)
{
diff --git a/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/gnu/java/awt/peer/gtk/GtkComponentPeer.java
index 6d9ba8857..76fefaaa5 100644
--- a/gnu/java/awt/peer/gtk/GtkComponentPeer.java
+++ b/gnu/java/awt/peer/gtk/GtkComponentPeer.java
@@ -253,20 +253,10 @@ public class GtkComponentPeer extends GtkGenericPeer
public Point getLocationOnScreen ()
{
int point[] = new int[2];
- if( this instanceof WindowPeer )
- {
- if (Thread.currentThread() == GtkMainThread.mainThread)
- gtkWindowGetLocationOnScreenUnlocked (point);
- else
- gtkWindowGetLocationOnScreen (point);
- }
+ if (Thread.currentThread() == GtkMainThread.mainThread)
+ gtkWidgetGetLocationOnScreenUnlocked (point);
else
- {
- if (Thread.currentThread() == GtkMainThread.mainThread)
- gtkWidgetGetLocationOnScreenUnlocked (point);
- else
- gtkWidgetGetLocationOnScreen (point);
- }
+ gtkWidgetGetLocationOnScreen (point);
return new Point (point[0], point[1]);
}
diff --git a/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java b/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java
index 7aea50991..7407744af 100644
--- a/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java
+++ b/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java
@@ -60,17 +60,7 @@ public class GtkMouseInfoPeer implements MouseInfoPeer
public boolean isWindowUnderMouse(Window w)
{
- int[] coords = gde.getMouseCoordinates();
- GraphicsDevice[] gds = gde.getScreenDevices();
-
- // Check if the screen of the Window and the cursor match
- if( gds[ coords[0] ] != w.getGraphicsConfiguration().getDevice() )
- return false;
-
- // Return the bounds-check.
- Point p = w.getLocationOnScreen();
- return (coords[1] >= p.x && coords[1] < p.x + w.getWidth() &&
- coords[2] >= p.y && coords[2] < p.y + w.getHeight() );
- }
+ return gde.isWindowUnderMouse((GtkWindowPeer) w.getPeer());
+ }
}
diff --git a/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/gnu/java/awt/peer/gtk/GtkWindowPeer.java
index d8054150d..9744c3a53 100644
--- a/gnu/java/awt/peer/gtk/GtkWindowPeer.java
+++ b/gnu/java/awt/peer/gtk/GtkWindowPeer.java
@@ -45,6 +45,7 @@ import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.KeyboardFocusManager;
+import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ComponentEvent;
@@ -392,6 +393,16 @@ public class GtkWindowPeer extends GtkContainerPeer
clickCount, popupTrigger);
}
+ public Point getLocationOnScreen()
+ {
+ int point[] = new int[2];
+ if (Thread.currentThread() == GtkMainThread.mainThread)
+ gtkWindowGetLocationOnScreenUnlocked(point);
+ else
+ gtkWindowGetLocationOnScreen(point);
+ return new Point(point[0], point[1]);
+ }
+
// We override this to keep it in sync with our internal
// representation.
public Rectangle getBounds()
diff --git a/include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h b/include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h
index aa0bd0156..de83f57a5 100644
--- a/include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h
+++ b/include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h
@@ -1,10 +1,10 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+
#ifndef __gnu_java_awt_peer_gtk_GdkGraphicsEnvironment__
#define __gnu_java_awt_peer_gtk_GdkGraphicsEnvironment__
-#include <jni.h>
-
#ifdef __cplusplus
extern "C"
{
@@ -17,6 +17,7 @@ JNIEXPORT jobject JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nati
JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nativeGetNumFontFamilies (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nativeGetFontFamilies (JNIEnv *env, jobject, jobjectArray);
JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_getMouseCoordinates (JNIEnv *env, jobject);
+JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_isWindowUnderMouse (JNIEnv *env, jobject, jobject);
#ifdef __cplusplus
}
diff --git a/java/awt/Component.java b/java/awt/Component.java
index f8bed1761..fe4fb9b8b 100644
--- a/java/awt/Component.java
+++ b/java/awt/Component.java
@@ -5834,6 +5834,62 @@ p * <li>the set of backward traversal keys
}
/**
+ * Returns the mouse pointer position relative to this Component's
+ * top-left corner.
+ *
+ * @return relative mouse pointer position
+ *
+ * @throws HeadlessException if in a headless environment
+ */
+ public Point getMousePosition() throws HeadlessException
+ {
+ return getMousePositionHelper(true);
+ }
+
+ Point getMousePositionHelper(boolean allowChildren) throws HeadlessException
+ {
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException("can't get mouse position"
+ + " in headless environment");
+ if (!isShowing())
+ return null;
+
+ Component parent = this;
+ int windowRelativeXOffset = 0;
+ int windowRelativeYOffset = 0;
+ while (parent != null && !(parent instanceof Window))
+ {
+ windowRelativeXOffset += parent.getX();
+ windowRelativeYOffset += parent.getY();
+ parent = parent.getParent();
+ }
+ if (parent == null)
+ return null;
+
+ Window window = (Window) parent;
+ if (!Toolkit.getDefaultToolkit()
+ .getMouseInfoPeer().isWindowUnderMouse(window))
+ return null;
+
+ PointerInfo info = MouseInfo.getPointerInfo();
+ Point mouseLocation = info.getLocation();
+ Point windowLocation = window.getLocationOnScreen();
+
+ int x = mouseLocation.x - windowLocation.x;
+ int y = mouseLocation.y - windowLocation.y;
+
+ if (!mouseOverComponent(window.getComponentAt(x, y), allowChildren))
+ return null;
+
+ return new Point(x - windowRelativeXOffset, y - windowRelativeYOffset);
+ }
+
+ boolean mouseOverComponent(Component component, boolean allowChildren)
+ {
+ return component == this;
+ }
+
+ /**
* 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/java/awt/Container.java b/java/awt/Container.java
index 83d9f7b78..e7622f2e8 100644
--- a/java/awt/Container.java
+++ b/java/awt/Container.java
@@ -1098,6 +1098,33 @@ public class Container extends Component
}
/**
+ * Returns the mouse pointer position relative to this Container's
+ * top-left corner. If allowChildren is false, the mouse pointer
+ * must be directly over this container. If allowChildren is true,
+ * the mouse pointer may be over this container or any of its
+ * descendents.
+ *
+ * @param allowChildren true to allow descendents, false if pointer
+ * must be directly over Container.
+ *
+ * @return relative mouse pointer position
+ *
+ * @throws HeadlessException if in a headless environment
+ */
+ public Point getMousePosition(boolean allowChildren) throws HeadlessException
+ {
+ return super.getMousePositionHelper(allowChildren);
+ }
+
+ boolean mouseOverComponent(Component component, boolean allowChildren)
+ {
+ if (allowChildren)
+ return isAncestorOf(component);
+ else
+ return component == this;
+ }
+
+ /**
* Returns the component located at the specified point. This is done
* by checking whether or not a child component claims to contain this
* point. The first child component that does is returned. If no
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
index 1c88d1b51..6066a6bb2 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
@@ -263,3 +263,37 @@ Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_getMouseCoordinates
return retArray;
}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_isWindowUnderMouse
+(JNIEnv *env, jobject obj, jobject windowPeer)
+{
+ GdkDisplay *display = NULL;
+ gint x = 0;
+ gint y = 0;
+ GtkWidget *windowToTest = NULL;
+ GdkWindow *windowAtPointer = NULL;
+ jboolean retVal = JNI_FALSE;
+
+ display = (GdkDisplay *) gtkpeer_get_display (env, obj);
+ g_assert (display != NULL);
+
+ windowToTest = (GtkWidget *) gtkpeer_get_widget (env, windowPeer);
+
+ gdk_threads_enter ();
+
+ windowAtPointer = gdk_display_get_window_at_pointer (display, &x, &y);
+
+ while (windowAtPointer
+ && windowAtPointer != windowToTest->window)
+ windowAtPointer = gdk_window_get_parent (windowAtPointer);
+
+ gdk_threads_leave ();
+
+ if (windowAtPointer)
+ retVal = JNI_TRUE;
+ else
+ retVal = JNI_FALSE;
+
+ return retVal;
+}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
index 4ea753a8e..6ba8d4767 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
@@ -40,6 +40,8 @@ exception statement from your version. */
#include "gtkpeer.h"
#include "gnu_java_awt_peer_gtk_GtkWindowPeer.h"
#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
#include <gdk/gdkkeysyms.h>
#define AWT_WINDOW_CLOSING 201
@@ -1037,6 +1039,12 @@ static void window_get_frame_extents (GtkWidget *window,
int *top, int *left,
int *bottom, int *right);
+static void request_frame_extents (GtkWidget *window);
+
+static Bool property_notify_predicate (Display *display,
+ XEvent *xevent,
+ XPointer arg);
+
static gboolean window_delete_cb (GtkWidget *widget, GdkEvent *event,
jobject peer);
static void window_destroy_cb (GtkWidget *widget, GdkEvent *event,
@@ -1142,6 +1150,12 @@ union extents_union
unsigned long **extents;
};
+union atom_list_union
+{
+ guchar **gu_extents;
+ Atom **atom_list;
+};
+
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkWindowPeer_create
(JNIEnv *env, jobject obj, jint type, jboolean decorated, jobject parent)
@@ -1503,22 +1517,118 @@ static void
window_get_frame_extents (GtkWidget *window,
int *top, int *left, int *bottom, int *right)
{
- GdkRectangle extents;
- GdkWindow* gdkWindow;
+ unsigned long *extents = NULL;
+ union extents_union gu_ex;
- gint x, y, w, h;
+ /* Guess frame extents in case _NET_FRAME_EXTENTS is not
+ supported. */
+ if (!gtk_window_get_decorated (GTK_WINDOW (window)))
+ {
+ *top = 0;
+ *left = 0;
+ *bottom = 0;
+ *right = 0;
- gdkWindow = window->window;
+ return;
+ }
- gdk_window_get_frame_extents(gdkWindow, &extents);
- gdk_drawable_get_size(gdkWindow, &w, &h);
- gdk_window_get_origin(gdkWindow, &x, &y);
+ *top = 23;
+ *left = 6;
+ *bottom = 6;
+ *right = 6;
- *left = extents.x - x;
- *top = extents.y - y;
- *right = extents.width - w - *left;
- *bottom = extents.height - h - *top;
+ /* Request that the window manager set window's
+ _NET_FRAME_EXTENTS property. */
+ request_frame_extents (window);
+ /* Attempt to retrieve window's frame extents. */
+ gu_ex.extents = &extents;
+ if (gdk_property_get (window->window,
+ gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE),
+ gdk_atom_intern ("CARDINAL", FALSE),
+ 0,
+ sizeof (unsigned long) * 4,
+ FALSE,
+ NULL,
+ NULL,
+ NULL,
+ gu_ex.gu_extents))
+ {
+ *left = extents [0];
+ *right = extents [1];
+ *top = extents [2];
+ *bottom = extents [3];
+ }
+}
+
+static Atom extents_atom = 0;
+
+/* Requests that the window manager set window's
+ _NET_FRAME_EXTENTS property. */
+static void
+request_frame_extents (GtkWidget *window)
+{
+ const char *request_str = "_NET_REQUEST_FRAME_EXTENTS";
+ GdkAtom request_extents = gdk_atom_intern (request_str, FALSE);
+
+ /* Check if the current window manager supports
+ _NET_REQUEST_FRAME_EXTENTS. */
+ if (gdk_net_wm_supports (request_extents))
+ {
+ GdkDisplay *display = gtk_widget_get_display (window);
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ GdkWindow *root_window = gdk_get_default_root_window ();
+ Window xroot_window = GDK_WINDOW_XID (root_window);
+
+ Atom extents_request_atom =
+ gdk_x11_get_xatom_by_name_for_display (display, request_str);
+
+ XEvent xevent;
+ XEvent notify_xevent;
+
+ unsigned long window_id = GDK_WINDOW_XID (GDK_DRAWABLE(window->window));
+
+ if (!extents_atom)
+ {
+ const char *extents_str = "_NET_FRAME_EXTENTS";
+ extents_atom =
+ gdk_x11_get_xatom_by_name_for_display (display, extents_str);
+ }
+
+ xevent.xclient.type = ClientMessage;
+ xevent.xclient.message_type = extents_request_atom;
+ xevent.xclient.display = xdisplay;
+ xevent.xclient.window = window_id;
+ xevent.xclient.format = 32;
+ xevent.xclient.data.l[0] = 0;
+ xevent.xclient.data.l[1] = 0;
+ xevent.xclient.data.l[2] = 0;
+ xevent.xclient.data.l[3] = 0;
+ xevent.xclient.data.l[4] = 0;
+
+ XSendEvent (xdisplay, xroot_window, False,
+ (SubstructureRedirectMask | SubstructureNotifyMask),
+ &xevent);
+
+ XIfEvent(xdisplay, &notify_xevent,
+ property_notify_predicate, (XPointer) &window_id);
+ }
+}
+
+static Bool
+property_notify_predicate (Display *xdisplay __attribute__((unused)),
+ XEvent *event,
+ XPointer window_id)
+{
+ unsigned long *window = (unsigned long *) window_id;
+
+ if (event->xany.type == PropertyNotify
+ && event->xany.window == *window
+ && event->xproperty.atom == extents_atom)
+ return True;
+ else
+ return False;
}
static gboolean