[kaffe] CVS kaffe (guilhem): Xlib-AWT fixes.
Kaffe CVS
cvs-commits at kaffe.org
Thu Jul 21 10:37:34 PDT 2005
PatchSet 6755
Date: 2005/07/21 17:30:31
Author: guilhem
Branch: HEAD
Tag: (none)
Log:
Xlib-AWT fixes.
* libraries/javalib/awt-implementations/kaffe/java/awt/AWTEvent.java,
libraries/javalib/awt-implementations/kaffe/java/awt/Component.java,
libraries/javalib/awt-implementations/kaffe/java/awt/Font.java,
libraries/javalib/awt-implementations/kaffe/java/awt/FontMetrics.java,
libraries/javalib/awt-implementations/kaffe/java/awt/Image.java,
libraries/javalib/awt-implementations/kaffe/java/awt/ImageFrameLoader.java,
libraries/javalib/awt-implementations/kaffe/java/awt/ImageNativeProducer.java,
libraries/javalib/awt-implementations/kaffe/java/awt/NativeClipboard.java,
libraries/javalib/awt-implementations/kaffe/java/awt/NativeGraphics.java,
libraries/javalib/awt-implementations/kaffe/java/awt/Toolkit.java,
libraries/javalib/awt-implementations/kaffe/java/awt/Window.java:
Use gnu.classpath.RawData instead of kaffe.util.Ptr.
* libraries/clib/awt/X/cbd.c,
libraries/clib/awt/X/evt.c,
libraries/clib/awt/X/fnt.c,
libraries/clib/awt/X/gra.c,
libraries/clib/awt/X/img.c,
libraries/clib/awt/X/toolkit.h,
libraries/clib/awt/X/wnd.c: Encapuslate the system pointers into a
RawData object. Cleaned up type uses.
* libraries/clib/classpath/jcl.c,
libraries/clib/jcl.h
(JCL_NewRawDataObject, JCL_GetRawData): New functions to build and
retrieve data from RawData instances.
* libraries/clib/awt/X/Makefile.am: Added dependence on
libclasspath.
* libraries/clib/awt/X/Makefile.in: Regenerated.
Members:
ChangeLog:1.4280->1.4281
libraries/clib/awt/X/Makefile.am:INITIAL->1.17
libraries/clib/awt/X/Makefile.in:1.138->1.139
libraries/clib/awt/X/cbd.c:1.6->1.7
libraries/clib/awt/X/evt.c:INITIAL->1.27
libraries/clib/awt/X/fnt.c:1.15->1.16
libraries/clib/awt/X/gra.c:1.23->1.24
libraries/clib/awt/X/img.c:1.26->1.27
libraries/clib/awt/X/toolkit.h:INITIAL->1.33
libraries/clib/awt/X/wnd.c:1.11->1.12
libraries/clib/classpath/jcl.c:1.3->1.4
libraries/clib/classpath/jcl.h:1.2->1.3
libraries/javalib/awt-implementations/kaffe/java/awt/AWTEvent.java:1.1->1.2
libraries/javalib/awt-implementations/kaffe/java/awt/Component.java:1.1->1.2
libraries/javalib/awt-implementations/kaffe/java/awt/Font.java:1.1->1.2
libraries/javalib/awt-implementations/kaffe/java/awt/FontMetrics.java:1.1->1.2
libraries/javalib/awt-implementations/kaffe/java/awt/Image.java:1.1->1.2
libraries/javalib/awt-implementations/kaffe/java/awt/ImageFrameLoader.java:1.1->1.2
libraries/javalib/awt-implementations/kaffe/java/awt/ImageNativeProducer.java:1.1->1.2
libraries/javalib/awt-implementations/kaffe/java/awt/NativeClipboard.java:1.1->1.2
libraries/javalib/awt-implementations/kaffe/java/awt/NativeGraphics.java:1.2->1.3
libraries/javalib/awt-implementations/kaffe/java/awt/Toolkit.java:1.1->1.2
libraries/javalib/awt-implementations/kaffe/java/awt/Window.java:1.1->1.2
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4280 kaffe/ChangeLog:1.4281
--- kaffe/ChangeLog:1.4280 Thu Jul 21 13:03:25 2005
+++ kaffe/ChangeLog Thu Jul 21 17:30:31 2005
@@ -1,5 +1,39 @@
2005-07-21 Guilhem Lavaux <guilhem at kaffe.org>
+ * libraries/javalib/awt-implementations/kaffe/java/awt/AWTEvent.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/Component.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/Font.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/FontMetrics.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/Image.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/ImageFrameLoader.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/ImageNativeProducer.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/NativeClipboard.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/NativeGraphics.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/Toolkit.java,
+ libraries/javalib/awt-implementations/kaffe/java/awt/Window.java:
+ Use gnu.classpath.RawData instead of kaffe.util.Ptr.
+
+ * libraries/clib/awt/X/cbd.c,
+ libraries/clib/awt/X/evt.c,
+ libraries/clib/awt/X/fnt.c,
+ libraries/clib/awt/X/gra.c,
+ libraries/clib/awt/X/img.c,
+ libraries/clib/awt/X/toolkit.h,
+ libraries/clib/awt/X/wnd.c: Encapuslate the system pointers into a
+ RawData object. Cleaned up type uses.
+
+ * libraries/clib/classpath/jcl.c,
+ libraries/clib/jcl.h
+ (JCL_NewRawDataObject, JCL_GetRawData): New functions to build and
+ retrieve data from RawData instances.
+
+ * libraries/clib/awt/X/Makefile.am: Added dependence on
+ libclasspath.
+
+ * libraries/clib/awt/X/Makefile.in: Regenerated.
+
+2005-07-21 Guilhem Lavaux <guilhem at kaffe.org>
+
* kaffe/jvmpi/jvmpi_kaffe.c
(jvmpiRequestEvent): Return failure if the argument is wrong.
===================================================================
Checking out kaffe/libraries/clib/awt/X/Makefile.am
RCS: /home/cvs/kaffe/kaffe/libraries/clib/awt/X/Makefile.am,v
VERS: 1.17
***************
--- /dev/null Sun Aug 4 19:57:58 2002
+++ kaffe/libraries/clib/awt/X/Makefile.am Thu Jul 21 17:37:34 2005
@@ -0,0 +1,49 @@
+# X-based AWT support for standard Java libraries
+#
+# Copyright (c) 1998, 1999
+# Transvirtual Technologies, Inc. All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file.
+
+native_LTLIBRARIES = libxawt.la
+
+AM_CPPFLAGS = \
+ -I$(top_builddir)/include \
+ -I$(top_srcdir)/kaffe/kaffevm/jni \
+ -I$(top_srcdir)/libraries/clib/classpath
+
+libxawt_la_CFLAGS = \
+ $(CFLAGS_PG) \
+ $(X_CFLAGS)
+
+libxawt_la_LDFLAGS = \
+ $(KLIBFLAGS) \
+ -no-undefined \
+ -module \
+ -release $(PACKAGE_VERSION) \
+ -export-symbols-regex "^([Jj]ava|kaffe)_"
+
+libxawt_la_LIBADD = \
+ $(top_builddir)/kaffe/kaffevm/libkaffevm.la $(AWT_LIBS) \
+ $(top_builddir)/libraries/clib/classpath/libclasspath.la
+
+libxawt_la_SOURCES = \
+ tlk.c \
+ wnd.c \
+ evt.c \
+ gra.c \
+ fnt.c \
+ clr.c \
+ img.c \
+ imggif.c \
+ imgjpeg.c \
+ imgpng.c \
+ cbd.c
+
+noinst_HEADERS = \
+ keysyms.h \
+ toolkit.h \
+ tlkprops.h
+
+CLEANFILES = so_locations
Index: kaffe/libraries/clib/awt/X/Makefile.in
diff -u kaffe/libraries/clib/awt/X/Makefile.in:1.138 kaffe/libraries/clib/awt/X/Makefile.in:1.139
--- kaffe/libraries/clib/awt/X/Makefile.in:1.138 Tue Jul 19 01:16:24 2005
+++ kaffe/libraries/clib/awt/X/Makefile.in Thu Jul 21 17:30:36 2005
@@ -88,7 +88,8 @@
LTLIBRARIES = $(native_LTLIBRARIES)
am__DEPENDENCIES_1 =
libxawt_la_DEPENDENCIES = $(top_builddir)/kaffe/kaffevm/libkaffevm.la \
- $(am__DEPENDENCIES_1)
+ $(am__DEPENDENCIES_1) \
+ $(top_builddir)/libraries/clib/classpath/libclasspath.la
am_libxawt_la_OBJECTS = libxawt_la-tlk.lo libxawt_la-wnd.lo \
libxawt_la-evt.lo libxawt_la-gra.lo libxawt_la-fnt.lo \
libxawt_la-clr.lo libxawt_la-img.lo libxawt_la-imggif.lo \
@@ -390,7 +391,8 @@
native_LTLIBRARIES = libxawt.la
AM_CPPFLAGS = \
-I$(top_builddir)/include \
- -I$(top_srcdir)/kaffe/kaffevm/jni
+ -I$(top_srcdir)/kaffe/kaffevm/jni \
+ -I$(top_srcdir)/libraries/clib/classpath
libxawt_la_CFLAGS = \
$(CFLAGS_PG) \
@@ -403,7 +405,10 @@
-release $(PACKAGE_VERSION) \
-export-symbols-regex "^([Jj]ava|kaffe)_"
-libxawt_la_LIBADD = $(top_builddir)/kaffe/kaffevm/libkaffevm.la $(AWT_LIBS)
+libxawt_la_LIBADD = \
+ $(top_builddir)/kaffe/kaffevm/libkaffevm.la $(AWT_LIBS) \
+ $(top_builddir)/libraries/clib/classpath/libclasspath.la
+
libxawt_la_SOURCES = \
tlk.c \
wnd.c \
Index: kaffe/libraries/clib/awt/X/cbd.c
diff -u kaffe/libraries/clib/awt/X/cbd.c:1.6 kaffe/libraries/clib/awt/X/cbd.c:1.7
--- kaffe/libraries/clib/awt/X/cbd.c:1.6 Mon Apr 5 05:30:15 2004
+++ kaffe/libraries/clib/awt/X/cbd.c Thu Jul 21 17:30:36 2005
@@ -13,6 +13,7 @@
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include "toolkit.h"
+#include "jcl.h"
jclass NativeClipboard;
@@ -162,7 +163,7 @@
}
void
-Java_java_awt_Toolkit_cbdFreeClipboard ( JNIEnv* env UNUSED, jclass clazz UNUSED, ClipBoard* cbd UNUSED )
+Java_java_awt_Toolkit_cbdFreeClipboard ( JNIEnv* env UNUSED, jclass clazz UNUSED, jobject cbd UNUSED )
{
}
===================================================================
Checking out kaffe/libraries/clib/awt/X/evt.c
RCS: /home/cvs/kaffe/kaffe/libraries/clib/awt/X/evt.c,v
VERS: 1.27
***************
--- /dev/null Sun Aug 4 19:57:58 2002
+++ kaffe/libraries/clib/awt/X/evt.c Thu Jul 21 17:37:34 2005
@@ -0,0 +1,959 @@
+/**
+ * evt.c -
+ *
+ * Copyright (c) 1998
+ * Transvirtual Technologies, Inc. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+
+#include "config.h"
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include "toolkit.h"
+#include "keysyms.h"
+#include "jcl.h"
+
+
+#if !defined (USE_POLLING_AWT)
+#include "jsyscall.h"
+#include "locks.h"
+
+#if defined(UNIX_JTHREADS)
+void jthreadedBlockEAGAIN(int fd); /* move to SysCallInterface ? */
+int jthreadedFileDescriptor(int fd);
+#endif
+
+#endif /* !USE_POLLING_AWT */
+
+
+/*******************************************************************************
+ *
+ */
+
+static int nextEvent ( JNIEnv* env UNUSED, jclass clazz UNUSED, Toolkit *tk, int blockIt UNUSED )
+{
+ if ( tk->preFetched )
+ return 1;
+
+#if !defined(USE_POLLING_AWT) && !defined(SUN_AWT_FIX)
+ /*
+ * We can't use QueuedAfterFlush since it seems to rely on blocked IO. At least
+ * XFree86-3.3.2 subsequently hangs in _XFlushInt. This is the weak point of
+ * our multithreaded X support, which depends on the Xlib in use
+ */
+ if ( blockIt ) { /* this is from a getNextEvent */
+ while ( tk->pending <= 0 ) {
+ XFlush( tk->dsp);
+ if ( (tk->pending = XEventsQueued( tk->dsp, QueuedAlready)) == 0 ) {
+ tk->blocking = 1;
+
+ /* Note that we might get blocked here, but we still have the Toolkit.class
+ * lock. Since the new locking interface requires locks to occur symmetrical
+ * inside of the same stack frame, we have to backup to some VM specific
+ * functionality, here.
+ */
+#if defined (UNIX_JTHREADS)
+ UNBLOCK_EXECUTE( clazz, (jthreadedBlockEAGAIN( ConnectionNumber( tk->dsp))));
+
+#elif defined (UNIX_PTHREADS)
+ /*
+ * Even with pthreads, don't simply do a XNextEvent, because we most probably
+ * would get "unexpected async replies" X errors when doing roundtrips (e.g.
+ * direct or indirect XSyncs) from other threads while still being blocked in
+ * XNextEvent, here. The only thing done outside the Toolkit lock should be
+ * to check availability of X input
+ */
+ {
+ int stat;
+
+ do {
+ UNBLOCK_EXECUTE( clazz, (stat =select( ConnectionNumber(tk->dsp)+1, &tk->rfds, NULL,NULL,NULL)));
+ } while ( stat != 1 );
+ }
+#endif
+
+ /*
+ * getting here just means we got input, it doesn't mean we have events. It also
+ * doesn't mean there currently is no other thread doing X requests
+ */
+ tk->blocking = 0;
+ tk->pending = XEventsQueued( tk->dsp, QueuedAfterReading);
+ }
+ }
+ }
+ else { /* this is from a peekEvent */
+ if ( tk->blocking ){ /* nothing to expect, there is a pending getNextEvent */
+ return 0;
+ }
+
+ if ( tk->pending <= 0 ) {
+ XFlush( tk->dsp);
+ if ( (tk->pending = XEventsQueued( tk->dsp, QueuedAlready)) == 0 ){
+ return 0;
+ }
+ }
+ }
+#else /* USE_POLLING_AWT */
+ /*
+ * We need to use this one for Solaris. We have problems trying to unblock the
+ * AWT thread off the X server connection.
+ */
+ if ( tk->pending <= 0 ) {
+ if ( (tk->pending = XEventsQueued( tk->dsp, QueuedAfterFlush)) == 0 )
+ return 0;
+ }
+#endif /* !USE_POLLING_AWT */
+
+ XNextEvent( tk->dsp, &tk->event);
+ tk->pending--;
+
+ return 1;
+}
+
+
+/* X-to-Java key modifier mapping
+ * altGr : PC
+ * shift - ctrl alt meta : Java
+ * Shift Lock Ctrl Mod1 Mod3 : X symbol
+ * ----------------------------------------------------------
+ * 1 1 2 8 4 : Java value
+ * 1 2 4 8 32 : X
+ */
+
+static inline int keyMod ( int keyState )
+{
+ int mod = 0;
+ if ( keyState & 3 ) mod |= 1; /* shift or lock */
+ if ( keyState & 4 ) mod |= 2;
+ if ( keyState & 8 ) mod |= 8;
+ return mod;
+}
+
+
+jclass AWTEvent;
+jclass ComponentEvent;
+jclass MouseEvent;
+jclass FocusEvent;
+jclass WindowEvent;
+jclass KeyEvent;
+jclass PaintEvent;
+jclass WMEvent;
+
+jmethodID getComponentEvent;
+jmethodID getMouseEvent;
+jmethodID getFocusEvent;
+jmethodID getWindowEvent;
+jmethodID getKeyEvent;
+jmethodID getPaintEvent;
+jmethodID getWMEvent;
+
+#define COMPONENT_RESIZED 101
+
+#define WINDOW_CLOSING 201
+#define WINDOW_CLOSED 202
+#define WINDOW_ICONIFIED 203
+#define WINDOW_DEICONIFIED 204
+
+#define KEY_PRESSED 401
+#define KEY_RELEASED 402
+
+#define MOUSE_PRESSED 501
+#define MOUSE_RELEASED 502
+#define MOUSE_MOVED 503
+#define MOUSE_ENTERED 504
+#define MOUSE_EXITED 505
+
+#define PAINT 800
+#define UPDATE 801
+
+#define FOCUS_GAINED 1004
+#define FOCUS_LOST 1005
+
+#define WM_KILLED 1905
+
+#if defined(KAFFE_VMDEBUG) && !defined(NDEBUG)
+static const char *eventStr ( int evtId )
+{
+ switch (evtId) {
+ case COMPONENT_RESIZED: return "ComponentResized";
+
+ case WINDOW_CLOSING: return "WindowClosing";
+ case WINDOW_CLOSED: return "WindowClosed";
+ case WINDOW_ICONIFIED: return "WindowIconified";
+ case WINDOW_DEICONIFIED: return "WindowDeiconified";
+
+ case KEY_PRESSED: return "KeyPressed";
+ case KEY_RELEASED: return "KeyReleased";
+
+ case MOUSE_PRESSED: return "MousePressed";
+ case MOUSE_RELEASED: return "MouseReleased";
+ case MOUSE_MOVED: return "MouseMoved";
+ case MOUSE_ENTERED: return "MouseEntered";
+ case MOUSE_EXITED: return "MouseExited";
+
+ case PAINT: return "Paint";
+ case UPDATE: return "Update";
+
+ case FOCUS_GAINED: return "FocusGained";
+ case FOCUS_LOST: return "FocusLost";
+
+ case WM_KILLED: return "WMKilled";
+
+ default: return "<unknown>";
+ }
+};
+#endif /* defined(KAFFE_VMDEBUG) && !defined(NDEBUG) */
+
+static jobject
+skip ( JNIEnv* env UNUSED, Toolkit* tk UNUSED )
+{
+ return NULL;
+}
+
+
+static jobject
+keyNotify ( JNIEnv* env, Toolkit* tk )
+{
+ KeySym keysym;
+ KeySym keysym2;
+ XComposeStatus ioStatus;
+ int n, keyCode, keyChar, mod, idx, nchar;
+
+ /*
+ * We should eventually support input methods here.
+ * Note that 'keysym' is queried separately (with a standard state), to
+ * ensure the "one physical key -> one keycode" invariant
+ */
+ n = XLookupString( &tk->event.xkey, tk->buf, tk->nBuf, &keysym2, &ioStatus);
+ keysym = XKeycodeToKeysym( tk->dsp, tk->event.xkey.keycode, 0);
+
+
+ /* Bug fix: the keypad numbers where not handled correctly.
+ * In X, numlock is a modifier, and XKeycodeToKeysym do
+ * not do any modifier interpretation (in order to
+ * build the correct Java KeyEvent).
+ * But, as a result, since there is no NumLock modifier
+ * in Java, the information was lost, and the keypad could
+ * not work with NumLock selected.
+ * The "solution" is to use the returned keysym from XLookupString
+ * (which interpret the modifiers) if and only if it
+ * the original keysym correspond to the keypad; this should
+ * code will all the case where the numlock alter the interpretation
+ * of the keypad; also, if the keysums are the xk_xp_<num>
+ * we set the keychar to the correspoding digit.
+ */
+
+ if ((keysym >= XK_KP_Space) && (keysym <= XK_KP_9)) {
+ keysym = keysym2;
+
+ switch (keysym)
+ {
+ case XK_KP_Multiply:
+ nchar = '*';
+ break;
+ case XK_KP_Add:
+ nchar = '+';
+ break;
+ case XK_KP_Separator:
+ nchar = ',';
+ break;
+ case XK_KP_Subtract:
+ nchar = '-';
+ break;
+ case XK_KP_Decimal:
+ nchar = '.';
+ break;
+ case XK_KP_Divide:
+ nchar = '/';
+ break;
+ case XK_KP_0:
+ nchar = '0';
+ break;
+ case XK_KP_1:
+ nchar = '1';
+ break;
+ case XK_KP_2:
+ nchar = '2';
+ break;
+ case XK_KP_3:
+ nchar = '3';
+ break;
+ case XK_KP_4:
+ nchar = '4';
+ break;
+ case XK_KP_5:
+ nchar = '5';
+ break;
+ case XK_KP_6:
+ nchar = '6';
+ break;
+ case XK_KP_7:
+ nchar = '7';
+ break;
+ case XK_KP_8:
+ nchar = '8';
+ break;
+ case XK_KP_9:
+ nchar = '9';
+ break;
+ default:
+ nchar = -1;
+ break;
+ }
+ }
+ else
+ nchar = -1;
+
+ if ( (keysym >= 0xff00) || (n == 0) ) {
+ keyCode = FKeyCode[keysym & 0xff];
+
+ /*
+ * There are some "control keys" that should generate KEY_TYPED events
+ * (enter, cancel, backspace, del, tab). This is flagged by a negative keyCode
+ * value and leads to non-zero keyChars
+ */
+ if ( keyCode < 0 ){
+ keyChar = keyCode = -keyCode;
+ } else if (nchar >= 0) {
+ keyChar = nchar;
+ }
+ else { /* a "pure" function key */
+ keyChar = 0;
+ }
+
+ }
+ else {
+ keyChar = (unsigned char)X->buf[0];
+ keyCode = LKeyCode[keysym & 0xff];
+ }
+
+ tk->evtId = (tk->event.xany.type == KeyPress)? KEY_PRESSED : KEY_RELEASED;
+ mod = keyMod( tk->event.xkey.state);
+
+ if ( tk->fwdIdx >= 0 ) {
+ /*
+ * watch out - we still might have key events for a already
+ * unregistered forwardee in the queue (since we fake X, we can't rely on it
+ * to remove key events for a destroyed forwardee)
+ */
+ if ( !checkSource( tk, tk->fwdIdx) )
+ return 0;
+ idx = tk->fwdIdx;
+ }
+ else {
+ idx = tk->srcIdx;
+ }
+
+ return (*env)->CallStaticObjectMethod( env, KeyEvent, getKeyEvent,
+ idx, tk->evtId, keyCode, keyChar, mod);
+}
+
+
+static jobject
+buttonNotify ( JNIEnv* env, Toolkit* tk )
+{
+ if ( tk->event.xany.type == ButtonPress ) {
+ tk->evtId = MOUSE_PRESSED;
+
+ if ( (tk->windows[tk->srcIdx].w == tk->focus) && (tk->fwdIdx >= 0) )
+ forwardFocus( FWD_REVERT, tk->event.xany.window);
+ }
+ else {
+ tk->evtId = MOUSE_RELEASED;
+ }
+
+ return (*env)->CallStaticObjectMethod( env, MouseEvent, getMouseEvent,
+ tk->srcIdx, tk->evtId,
+ tk->event.xbutton.button,
+ tk->event.xbutton.x, tk->event.xbutton.y);
+}
+
+
+static jobject
+motionNotify ( JNIEnv* env, Toolkit* tk )
+{
+ return (*env)->CallStaticObjectMethod( env, MouseEvent, getMouseEvent,
+ tk->srcIdx, (tk->evtId = MOUSE_MOVED),
+ 0, tk->event.xmotion.x, tk->event.xmotion.y);
+}
+
+
+static jobject
+mouseNotify ( JNIEnv* env, Toolkit* tk )
+{
+ tk->evtId = (tk->event.xany.type == EnterNotify) ? MOUSE_ENTERED : MOUSE_EXITED;
+
+ return (*env)->CallStaticObjectMethod( env, MouseEvent, getMouseEvent,
+ tk->srcIdx, tk->evtId,
+ 0, tk->event.xcrossing.x, tk->event.xcrossing.y);
+}
+
+
+static jobject
+focusNotify ( JNIEnv* env, Toolkit* tk )
+{
+ int et = tk->event.xany.type;
+ int idx = (tk->focusFwd) ? tk->fwdIdx : tk->srcIdx;
+
+ /*
+ * get rid of all these fancy intermediate focus events (the real thing should
+ * come last), but be aware of that we might get events for already unregistered windows
+ * (in case the app isn't particulary careful with disposing windows), ending up in
+ * ArrayOutOfBoundsExceptions in the getFocusEvent
+ */
+ while ( XCheckMaskEvent( tk->dsp, FocusChangeMask, &tk->event) ){
+ tk->pending--;
+ if ( getSourceIdx( tk, tk->event.xfocus.window) >= 0 ) {
+ et = tk->event.xany.type;
+ idx = (tk->focusFwd) ? tk->fwdIdx : tk->srcIdx;
+ }
+ }
+
+ if ( et == FocusIn ) {
+ tk->evtId = FOCUS_GAINED;
+ tk->focus = tk->event.xany.window;
+ }
+ else {
+ tk->evtId = FOCUS_LOST;
+ tk->focus = 0;
+ }
+
+ /*
+ * No matter what the focus change is - if we get a REAL focus notification,
+ * it means that we will end focus forwarding (which is done on the owner-basis,
+ * not by means of a global grab mode)
+ */
+ resetFocusForwarding( tk);
+
+ if ( checkSource( tk, idx) ){
+ return (*env)->CallStaticObjectMethod( env, FocusEvent, getFocusEvent, idx,
+ tk->evtId, JNI_FALSE);
+ }
+ else {
+ return 0;
+ }
+}
+
+
+static jobject
+expose ( JNIEnv* env, Toolkit* tk )
+{
+ Window wnd = tk->event.xany.window;
+ int x = tk->event.xexpose.x;
+ int y = tk->event.xexpose.y;
+ int w = tk->event.xexpose.width;
+ int h = tk->event.xexpose.height;
+ int xw, yh, exw, eyh;
+
+ while ( XCheckWindowEvent( tk->dsp, wnd, ExposureMask | StructureNotifyMask, &tk->event) ){
+ tk->pending--;
+
+ if ( tk->event.xany.type == Expose ) {
+ xw = x + w;
+ yh = y + h;
+
+ exw = tk->event.xexpose.x + tk->event.xexpose.width;
+ eyh = tk->event.xexpose.y + tk->event.xexpose.height;
+
+ if ( tk->event.xexpose.x < x ) x = tk->event.xexpose.x;
+ if ( tk->event.xexpose.y < y ) y = tk->event.xexpose.y;
+
+ w = (exw > xw) ? exw - x : xw - x;
+ h = (eyh > yh) ? eyh - y : yh - y;
+ }
+ else {
+ tk->preFetched = 1;
+ break;
+ }
+ }
+
+ return (*env)->CallStaticObjectMethod( env, PaintEvent, getPaintEvent,
+ tk->srcIdx, (tk->evtId = UPDATE),
+ x, y, w, h);
+}
+
+
+static jobject
+destroyNotify ( JNIEnv* env, Toolkit* tk )
+{
+ /*
+ * We should get this just for windows which have been destroyed from an
+ * external client, since removeNotify() calls evtUnregisterSource() (i.e.
+ * removes windows properly from the dispatch table)
+ */
+ tk->windows[tk->srcIdx].flags &= ~WND_MAPPED;
+
+ return (*env)->CallStaticObjectMethod( env, WMEvent, getWMEvent,
+ tk->srcIdx, (tk->evtId = WM_KILLED));
+}
+
+
+static jobject
+mapNotify ( JNIEnv* env, Toolkit* tk )
+{
+ int id = 0;
+
+ if ( tk->event.xany.type == MapNotify ) {
+ if ( (tk->windows[tk->srcIdx].flags & WND_MAPPED) == 0 ){
+ id = WINDOW_DEICONIFIED;
+ tk->windows[tk->srcIdx].flags |= WND_MAPPED;
+ }
+ }
+ else {
+ if ( (tk->windows[tk->srcIdx].flags & WND_MAPPED) != 0 ){
+ id = WINDOW_ICONIFIED;
+ tk->windows[tk->srcIdx].flags &= ~WND_MAPPED;
+ }
+ }
+
+ if ( id ) {
+ return (*env)->CallStaticObjectMethod( env, WindowEvent, getWindowEvent,
+ tk->srcIdx, id);
+ }
+ else {
+ /* we do the ComponentEvent show/hide in Java */
+ return 0;
+ }
+}
+
+
+static jobject
+configureNotify ( JNIEnv* env, Toolkit* tk )
+{
+ Window child;
+ int x, y, w, h;
+
+ /*
+ * some window managers are rather loquacious when doing opaque moves
+ */
+
+ while ( XCheckTypedWindowEvent( tk->dsp, tk->event.xany.window, ConfigureNotify, &tk->event) ){
+ tk->pending--;
+ }
+
+ if ( (tk->event.xconfigure.x == 0) && (tk->event.xconfigure.y == 0) ) {
+ XTranslateCoordinates( tk->dsp, tk->event.xconfigure.window,
+ DefaultRootWindow( tk->dsp),
+ tk->event.xconfigure.x, tk->event.xconfigure.y,
+ &tk->event.xconfigure.x, &tk->event.xconfigure.y, &child);
+ }
+
+ x = tk->event.xconfigure.x;
+ y = tk->event.xconfigure.y;
+ w = tk->event.xconfigure.width;
+ h = tk->event.xconfigure.height;
+ X->evtId = COMPONENT_RESIZED;
+
+ return (*env)->CallStaticObjectMethod( env, ComponentEvent, getComponentEvent,
+ tk->srcIdx, tk->evtId, x, y, w, h);
+}
+
+
+static jobject
+clientMessage ( JNIEnv* env, Toolkit* tk )
+{
+ if ( tk->windows[tk->srcIdx].flags & WND_DESTROYED ){
+ /* we lost him, Jim */
+ return 0;
+ }
+
+ if ( tk->event.xclient.message_type == WM_PROTOCOLS ) {
+ if ( tk->event.xclient.data.l[0] == WM_DELETE_WINDOW ) {
+ return (*env)->CallStaticObjectMethod( env, WindowEvent, getWindowEvent,
+ tk->srcIdx, (tk->evtId = WINDOW_CLOSING));
+ }
+ else if ( tk->event.xclient.data.l[0] == WM_TAKE_FOCUS ) {
+ XSetInputFocus( tk->dsp, tk->event.xany.window, RevertToParent, CurrentTime);
+ }
+ }
+
+ /*
+ * This is a workaround for the common problem of requesting the focus for not
+ * yet mapped windows (resulting in BadMatch errors)
+ */
+ else if ( tk->event.xclient.message_type == RETRY_FOCUS ) {
+ if ( tk->windows[tk->srcIdx].flags & WND_MAPPED ) {
+ XSetInputFocus( tk->dsp, tk->event.xclient.window, RevertToParent, CurrentTime);
+ if ( tk->event.xclient.data.l[1] ) {
+ /* we have a pending forward request, too */
+ forwardFocus( FWD_SET, tk->event.xclient.data.l[1]);
+ }
+ }
+ }
+
+ /*
+ * This is a workaround for X not having "owned" windows (popups), which do
+ * not "shade" the titlebar of their owner (i.e. don't indicate a change in
+ * the activeWindow). The only way to implement this reliable (w/o playing
+ * around with a window manager) is to not let these popups select on
+ * key events at all. But rather than to expose this to the Java side (like
+ * the JDK does), we hide this in the native layer
+ */
+ else if ( tk->event.xclient.message_type == FORWARD_FOCUS ) {
+ switch ( tk->event.xclient.data.l[0] ){
+ case FWD_SET:
+ DBG( AWT_EVT, printf("FWD_SET: %lx (%d) %lx\n", tk->event.xany.window, tk->srcIdx, tk->windows[tk->srcIdx].owner));
+
+ if ( (tk->srcIdx != tk->fwdIdx) && (tk->focus == tk->windows[tk->srcIdx].owner) ){
+ tk->fwdIdx = tk->srcIdx;
+ tk->focusFwd = tk->event.xany.window;
+ return (*env)->CallStaticObjectMethod( env, FocusEvent, getFocusEvent,
+ tk->srcIdx, FOCUS_GAINED, JNI_TRUE);
+ }
+ else {
+ return 0;
+ }
+
+ case FWD_CLEAR:
+ DBG( AWT_EVT, printf("FWD_CLEAR: %lx (%d) %lx\n", tk->event.xany.window, tk->srcIdx, tk->windows[tk->srcIdx].owner));
+
+ if ( tk->fwdIdx >= 0 ) {
+ resetFocusForwarding( tk);
+ return (*env)->CallStaticObjectMethod( env, FocusEvent, getFocusEvent,
+ tk->srcIdx, FOCUS_LOST, JNI_FALSE);
+ }
+ else {
+ return 0;
+ }
+
+ case FWD_REVERT:
+ DBG( AWT_EVT, printf("FWD_REVERT: %lx\n", tk->event.xany.window));
+ if ( tk->event.xany.window == tk->focus ) {
+ resetFocusForwarding( tk);
+ return (*env)->CallStaticObjectMethod( env, FocusEvent, getFocusEvent,
+ tk->srcIdx, FOCUS_GAINED, JNI_FALSE);
+ }
+ }
+ }
+ return 0;
+}
+
+static jobject
+reparentNotify ( JNIEnv* env, Toolkit* tk )
+{
+ Window window, parent, root;
+ jclass clazz = 0;
+ jmethodID setDecoInsets = 0;
+ int left, top, right, bottom;
+ int x, y, w, h, bw, d;
+ int xc, yc, wc, hc;
+ DecoInset *in = 0;
+ XSizeHints wmHints;
+ long supHints;
+
+ if ( tk->frameInsets.guess || tk->dialogInsets.guess ) {
+ window = tk->event.xreparent.window;
+ parent = tk->event.xreparent.parent;
+
+ XGetGeometry( tk->dsp, parent, &root, &x, &y, &w, &h, &bw, &d);
+ XGetGeometry( tk->dsp, window, &root, &xc, &yc, &wc, &hc, &bw, &d);
+
+ left = tk->event.xreparent.x;
+ top = tk->event.xreparent.y;
+ right = w - wc - left;
+ bottom = h - hc - top;
+
+ if ( (tk->windows[tk->srcIdx].flags & WND_DIALOG) && tk->dialogInsets.guess ) {
+ in = &(tk->dialogInsets);
+ if ( (left != in->left) || (top != in->top) ||
+ (right != in->right) || (bottom != in->bottom) ){
+ clazz = (*env)->FindClass( env, "java/awt/Dialog");
+ setDecoInsets = (*env)->GetStaticMethodID( env, clazz, "setDecoInsets","(IIIII)V");
+ }
+ in->guess = 0;
+ }
+ else if ( tk->frameInsets.guess ) {
+ in = &(tk->frameInsets);
+ if ( (left != in->left) || (top != in->top) ||
+ (right != in->right) || (bottom != in->bottom) ){
+ clazz = (*env)->FindClass( env, "java/awt/Frame");
+ setDecoInsets = (*env)->GetStaticMethodID( env, clazz, "setDecoInsets","(IIIII)V");
+ }
+ in->guess = 0;
+ }
+
+ if ( clazz ) {
+ wc -= (left + right) - (in->left + in->right);
+ hc -= (top + bottom) - (in->top + in->bottom);
+
+ XCheckTypedWindowEvent( tk->dsp, window, ConfigureNotify, &X->event);
+ XCheckTypedWindowEvent( tk->dsp, window, Expose, &X->event);
+ XResizeWindow( tk->dsp, window, wc, hc);
+
+ in->left = left;
+ in->top = top;
+ in->right = right;
+ in->bottom = bottom;
+
+ (*env)->CallStaticVoidMethod( env, clazz, setDecoInsets,
+ in->top, in->left, in->bottom, in->right, tk->srcIdx);
+
+ /* check if this was a resize locked window (which has to be locked again) */
+ XGetWMNormalHints( tk->dsp, window, &wmHints, &supHints);
+ if ( wmHints.min_width == wmHints.max_width ){
+ wmHints.min_width = wmHints.max_width = wc;
+ wmHints.min_height = wmHints.max_height = hc;
+ XSetWMNormalHints( tk->dsp, window, &wmHints);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+typedef jobject (*EventFunc)(JNIEnv*,Toolkit*);
+
+static EventFunc processEvent[LASTEvent] = {
+ skip, skip, /* 0, 1 are reserved by X */
+ keyNotify, /* KeyPress 2 */
+ keyNotify, /* KeyRelease 3 */
+ buttonNotify, /* ButtonPress 4 */
+ buttonNotify, /* ButtonRelease 5 */
+ motionNotify, /* MotionNotify 6 */
+ mouseNotify, /* EnterNotify 7 */
+ mouseNotify, /* LeaveNotify 8 */
+ focusNotify, /* FocusIn 9 */
+ focusNotify, /* FocusOut 10 */
+ skip, /* KeymapNotify 11 */
+ expose, /* Expose 12 */
+ skip, /* GraphicsExpose 13 */
+ skip, /* NoExpose 14 */
+ skip, /* VisibilityNotify 15 */
+ skip, /* CreateNotify 16 */
+ destroyNotify, /* DestroyNotify 17 */
+ mapNotify, /* UnmapNotify 18 */
+ mapNotify, /* MapNotify 19 */
+ skip, /* MapRequest 20 */
+ reparentNotify, /* ReparentNotify 21 */
+ configureNotify, /* ConfigureNotify 22 */
+ skip, /* ConfigureRequest 23 */
+ skip, /* GravityNotify 24 */
+ skip, /* ResizeRequest 25 */
+ skip, /* CirculateNotify 26 */
+ skip, /* CirculateRequest 27 */
+ skip, /* PropertyNotify 28 */
+ selectionClear, /* SelectionClear 29 */
+ selectionRequest, /* SelectionRequest 30 */
+ skip, /* SelectionNotify 31 */
+ skip, /* ColormapNotify 32 */
+ clientMessage, /* ClientMessage 33 */
+ skip /* MappingNotify 34 */
+};
+
+
+/*******************************************************************************
+ *
+ */
+
+jobject
+Java_java_awt_Toolkit_evtInit ( JNIEnv* env, jclass clazz UNUSED )
+{
+ jclass Component;
+#if !defined(USE_POLLING_AWT)
+ unsigned long mask;
+ XSetWindowAttributes attrs;
+#endif
+
+ if ( ComponentEvent != NULL ){
+ DBG( AWT_EVT, printf("evtInit called twice\n"));
+ return NULL;
+ }
+
+ ComponentEvent = (*env)->FindClass( env, "java/awt/ComponentEvt");
+ assert(ComponentEvent != NULL);
+ MouseEvent = (*env)->FindClass( env, "java/awt/MouseEvt");
+ assert(MouseEvent != NULL);
*** Patch too long, truncated ***
More information about the kaffe
mailing list