[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