summaryrefslogtreecommitdiff
path: root/libjava/classpath/native
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/native')
-rw-r--r--libjava/classpath/native/.cvsignore8
-rw-r--r--libjava/classpath/native/Makefile.am9
-rw-r--r--libjava/classpath/native/fdlibm/.cvsignore8
-rw-r--r--libjava/classpath/native/fdlibm/Makefile.am53
-rw-r--r--libjava/classpath/native/fdlibm/dtoa.c906
-rw-r--r--libjava/classpath/native/fdlibm/e_acos.c111
-rw-r--r--libjava/classpath/native/fdlibm/e_asin.c120
-rw-r--r--libjava/classpath/native/fdlibm/e_atan2.c131
-rw-r--r--libjava/classpath/native/fdlibm/e_exp.c167
-rw-r--r--libjava/classpath/native/fdlibm/e_fmod.c140
-rw-r--r--libjava/classpath/native/fdlibm/e_log.c152
-rw-r--r--libjava/classpath/native/fdlibm/e_pow.c312
-rw-r--r--libjava/classpath/native/fdlibm/e_rem_pio2.c185
-rw-r--r--libjava/classpath/native/fdlibm/e_remainder.c80
-rw-r--r--libjava/classpath/native/fdlibm/e_scalb.c55
-rw-r--r--libjava/classpath/native/fdlibm/e_sqrt.c452
-rw-r--r--libjava/classpath/native/fdlibm/fdlibm.h354
-rw-r--r--libjava/classpath/native/fdlibm/ieeefp.h167
-rw-r--r--libjava/classpath/native/fdlibm/java-assert.h38
-rw-r--r--libjava/classpath/native/fdlibm/k_cos.c96
-rw-r--r--libjava/classpath/native/fdlibm/k_rem_pio2.c320
-rw-r--r--libjava/classpath/native/fdlibm/k_sin.c79
-rw-r--r--libjava/classpath/native/fdlibm/k_tan.c132
-rw-r--r--libjava/classpath/native/fdlibm/mprec.c958
-rw-r--r--libjava/classpath/native/fdlibm/mprec.h402
-rw-r--r--libjava/classpath/native/fdlibm/s_atan.c181
-rw-r--r--libjava/classpath/native/fdlibm/s_ceil.c80
-rw-r--r--libjava/classpath/native/fdlibm/s_copysign.c82
-rw-r--r--libjava/classpath/native/fdlibm/s_cos.c82
-rw-r--r--libjava/classpath/native/fdlibm/s_fabs.c73
-rw-r--r--libjava/classpath/native/fdlibm/s_finite.c31
-rw-r--r--libjava/classpath/native/fdlibm/s_floor.c134
-rw-r--r--libjava/classpath/native/fdlibm/s_rint.c87
-rw-r--r--libjava/classpath/native/fdlibm/s_scalbn.c104
-rw-r--r--libjava/classpath/native/fdlibm/s_sin.c132
-rw-r--r--libjava/classpath/native/fdlibm/s_tan.c114
-rw-r--r--libjava/classpath/native/fdlibm/sf_fabs.c47
-rw-r--r--libjava/classpath/native/fdlibm/sf_rint.c80
-rw-r--r--libjava/classpath/native/fdlibm/strtod.c719
-rw-r--r--libjava/classpath/native/fdlibm/w_acos.c118
-rw-r--r--libjava/classpath/native/fdlibm/w_asin.c121
-rw-r--r--libjava/classpath/native/fdlibm/w_atan2.c117
-rw-r--r--libjava/classpath/native/fdlibm/w_exp.c140
-rw-r--r--libjava/classpath/native/fdlibm/w_fmod.c107
-rw-r--r--libjava/classpath/native/fdlibm/w_log.c115
-rw-r--r--libjava/classpath/native/fdlibm/w_pow.c231
-rw-r--r--libjava/classpath/native/fdlibm/w_remainder.c119
-rw-r--r--libjava/classpath/native/fdlibm/w_sqrt.c93
-rw-r--r--libjava/classpath/native/jni/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/Makefile.am20
-rw-r--r--libjava/classpath/native/jni/classpath/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/classpath/Makefile.am10
-rw-r--r--libjava/classpath/native/jni/classpath/classpath_jawt.h64
-rw-r--r--libjava/classpath/native/jni/classpath/jcl.c180
-rw-r--r--libjava/classpath/native/jni/classpath/jcl.h68
-rw-r--r--libjava/classpath/native/jni/classpath/jnilink.c125
-rw-r--r--libjava/classpath/native/jni/classpath/jnilink.h82
-rw-r--r--libjava/classpath/native/jni/classpath/native_state.c248
-rw-r--r--libjava/classpath/native/jni/classpath/native_state.h71
-rw-r--r--libjava/classpath/native/jni/classpath/primlib.c724
-rw-r--r--libjava/classpath/native/jni/classpath/primlib.h119
-rw-r--r--libjava/classpath/native/jni/gtk-peer/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/gtk-peer/Makefile.am61
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gdkfont.h142
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c70
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c418
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c642
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c1881
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c102
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c515
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c341
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c192
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c338
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c58
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c77
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c78
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c240
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c248
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c204
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c1161
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c82
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c281
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c180
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c101
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c621
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c183
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c539
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c118
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c56
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c193
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c173
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c112
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c105
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c205
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollbarPeer.c258
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c522
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c423
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c524
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c2181
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gthread-jni.c2592
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gthread-jni.h48
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gtkcairopeer.h93
-rw-r--r--libjava/classpath/native/jni/gtk-peer/gtkpeer.h206
-rw-r--r--libjava/classpath/native/jni/java-io/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/java-io/Makefile.am13
-rw-r--r--libjava/classpath/native/jni/java-io/java_io_VMFile.c734
-rw-r--r--libjava/classpath/native/jni/java-io/java_io_VMObjectInputStream.c69
-rw-r--r--libjava/classpath/native/jni/java-io/java_io_VMObjectStreamClass.c381
-rw-r--r--libjava/classpath/native/jni/java-io/javaio.c363
-rw-r--r--libjava/classpath/native/jni/java-io/javaio.h58
-rw-r--r--libjava/classpath/native/jni/java-lang/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/java-lang/Makefile.am16
-rw-r--r--libjava/classpath/native/jni/java-lang/java_lang_Math.c161
-rw-r--r--libjava/classpath/native/jni/java-lang/java_lang_VMDouble.c381
-rw-r--r--libjava/classpath/native/jni/java-lang/java_lang_VMFloat.c93
-rw-r--r--libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c494
-rw-r--r--libjava/classpath/native/jni/java-lang/java_lang_VMSystem.c156
-rw-r--r--libjava/classpath/native/jni/java-lang/java_lang_reflect_Array.c61
-rw-r--r--libjava/classpath/native/jni/java-net/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/java-net/Makefile.am14
-rw-r--r--libjava/classpath/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c452
-rw-r--r--libjava/classpath/native/jni/java-net/gnu_java_net_PlainSocketImpl.c320
-rw-r--r--libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c282
-rw-r--r--libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c66
-rw-r--r--libjava/classpath/native/jni/java-net/javanet.c1577
-rw-r--r--libjava/classpath/native/jni/java-net/javanet.h109
-rw-r--r--libjava/classpath/native/jni/java-nio/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/java-nio/Makefile.am16
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c56
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c296
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c793
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c219
-rw-r--r--libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c219
-rw-r--r--libjava/classpath/native/jni/java-nio/java_nio.c328
-rw-r--r--libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c83
-rw-r--r--libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c216
-rw-r--r--libjava/classpath/native/jni/java-util/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/java-util/Makefile.am7
-rw-r--r--libjava/classpath/native/jni/java-util/java_util_VMTimeZone.c223
-rw-r--r--libjava/classpath/native/jni/xmlj/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/xmlj/BUGS35
-rw-r--r--libjava/classpath/native/jni/xmlj/Makefile.am25
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_dom.c2617
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_dom.h70
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_error.c169
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_error.h85
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_io.c799
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_io.h170
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_node.c203
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_node.h72
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_sax.c1445
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_sax.h160
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_transform.c868
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_util.c301
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_util.h69
-rw-r--r--libjava/classpath/native/jni/xmlj/xmlj_xpath.c625
-rw-r--r--libjava/classpath/native/target/.cvsignore8
-rw-r--r--libjava/classpath/native/target/Linux/.cvsignore8
-rw-r--r--libjava/classpath/native/target/Linux/Makefile.am10
-rw-r--r--libjava/classpath/native/target/Linux/target_native.h79
-rw-r--r--libjava/classpath/native/target/Linux/target_native_file.h79
-rw-r--r--libjava/classpath/native/target/Linux/target_native_io.h78
-rw-r--r--libjava/classpath/native/target/Linux/target_native_math_float.h80
-rw-r--r--libjava/classpath/native/target/Linux/target_native_math_int.h80
-rw-r--r--libjava/classpath/native/target/Linux/target_native_misc.h79
-rw-r--r--libjava/classpath/native/target/Linux/target_native_network.h79
-rw-r--r--libjava/classpath/native/target/Makefile.am5
-rw-r--r--libjava/classpath/native/target/generic/.cvsignore8
-rw-r--r--libjava/classpath/native/target/generic/Makefile.am10
-rw-r--r--libjava/classpath/native/target/generic/target_generic.h171
-rw-r--r--libjava/classpath/native/target/generic/target_generic_file.h844
-rw-r--r--libjava/classpath/native/target/generic/target_generic_io.h82
-rw-r--r--libjava/classpath/native/target/generic/target_generic_math_float.h130
-rw-r--r--libjava/classpath/native/target/generic/target_generic_math_int.h260
-rw-r--r--libjava/classpath/native/target/generic/target_generic_misc.h203
-rw-r--r--libjava/classpath/native/target/generic/target_generic_network.h1278
-rw-r--r--libjava/classpath/native/target/readme.txt149
-rw-r--r--libjava/classpath/native/testsuite/.cvsignore8
-rw-r--r--libjava/classpath/native/testsuite/Makefile.am2
-rw-r--r--libjava/classpath/native/testsuite/guile-jvm.c223
-rw-r--r--libjava/classpath/native/vmi/.cvsignore8
-rw-r--r--libjava/classpath/native/vmi/Makefile.am6
-rw-r--r--libjava/classpath/native/vmi/TODO28
-rwxr-xr-xlibjava/classpath/native/vmi/vmi.c143
-rwxr-xr-xlibjava/classpath/native/vmi/vmi.h92
185 files changed, 47088 insertions, 0 deletions
diff --git a/libjava/classpath/native/.cvsignore b/libjava/classpath/native/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/Makefile.am b/libjava/classpath/native/Makefile.am
new file mode 100644
index 00000000000..6cc309010c0
--- /dev/null
+++ b/libjava/classpath/native/Makefile.am
@@ -0,0 +1,9 @@
+## Input file for automake to generate the Makefile.in used by configure
+
+if CREATE_JNI_LIBRARIES
+ JNIDIR = jni
+endif
+
+SUBDIRS = fdlibm $(JNIDIR) target
+DIST_SUBDIRS = fdlibm jni target
+
diff --git a/libjava/classpath/native/fdlibm/.cvsignore b/libjava/classpath/native/fdlibm/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/fdlibm/Makefile.am b/libjava/classpath/native/fdlibm/Makefile.am
new file mode 100644
index 00000000000..e3e3eecd2b7
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/Makefile.am
@@ -0,0 +1,53 @@
+noinst_LTLIBRARIES = libfdlibm.la
+
+libfdlibm_la_SOURCES = \
+ dtoa.c \
+ e_acos.c \
+ e_asin.c \
+ e_atan2.c \
+ e_exp.c \
+ e_fmod.c \
+ e_log.c \
+ e_pow.c \
+ e_remainder.c \
+ e_rem_pio2.c \
+ e_scalb.c \
+ e_sqrt.c \
+ fdlibm.h \
+ ieeefp.h \
+ java-assert.h \
+ k_cos.c \
+ k_rem_pio2.c \
+ k_sin.c \
+ k_tan.c \
+ mprec.c \
+ mprec.h \
+ s_atan.c \
+ s_ceil.c \
+ s_copysign.c \
+ s_cos.c \
+ s_fabs.c \
+ sf_fabs.c \
+ s_finite.c \
+ s_floor.c \
+ sf_rint.c \
+ s_rint.c \
+ s_scalbn.c \
+ s_sin.c \
+ s_tan.c \
+ strtod.c \
+ w_acos.c \
+ w_asin.c \
+ w_atan2.c \
+ w_exp.c \
+ w_fmod.c \
+ w_log.c \
+ w_pow.c \
+ w_remainder.c \
+ w_sqrt.c
+
+AM_LDFLAGS = @CLASSPATH_MODULE@
+
+# We just want the standard flags for fdlibm since it is an upstream lib
+# and our normal -pedantic -Wall -Werror breaks this lib. So no AM_CFLAGS.
+# We also don't need extra includes, so no AM_CPPFLAGS either.
diff --git a/libjava/classpath/native/fdlibm/dtoa.c b/libjava/classpath/native/fdlibm/dtoa.c
new file mode 100644
index 00000000000..6d5ad3b422e
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/dtoa.c
@@ -0,0 +1,906 @@
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991 by AT&T.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to
+ David M. Gay
+ AT&T Bell Laboratories, Room 2C-463
+ 600 Mountain Avenue
+ Murray Hill, NJ 07974-2070
+ U.S.A.
+ dmg@research.att.com or research!dmg
+ */
+
+#include "mprec.h"
+#include <string.h>
+
+static int
+_DEFUN (quorem,
+ (b, S),
+ _Jv_Bigint * b _AND _Jv_Bigint * S)
+{
+ int n;
+ long borrow, y;
+ unsigned long carry, q, ys;
+ unsigned long *bx, *bxe, *sx, *sxe;
+#ifdef Pack_32
+ long z;
+ unsigned long si, zs;
+#endif
+
+ n = S->_wds;
+#ifdef DEBUG
+ /*debug*/ if (b->_wds > n)
+ /*debug*/ Bug ("oversize b in quorem");
+#endif
+ if (b->_wds < n)
+ return 0;
+ sx = S->_x;
+ sxe = sx + --n;
+ bx = b->_x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug ("oversized quotient in quorem");
+#endif
+ if (q)
+ {
+ borrow = 0;
+ carry = 0;
+ do
+ {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend (borrow, z);
+ Storeinc (bx, z, y);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ while (sx <= sxe);
+ if (!*bxe)
+ {
+ bx = b->_x;
+ while (--bxe > bx && !*bxe)
+ --n;
+ b->_wds = n;
+ }
+ }
+ if (cmp (b, S) >= 0)
+ {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->_x;
+ sx = S->_x;
+ do
+ {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend (borrow, z);
+ Storeinc (bx, z, y);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ while (sx <= sxe);
+ bx = b->_x;
+ bxe = bx + n;
+ if (!*bxe)
+ {
+ while (--bxe > bx && !*bxe)
+ --n;
+ b->_wds = n;
+ }
+ }
+ return q;
+}
+
+#ifdef DEBUG
+#include <stdio.h>
+
+void
+print (_Jv_Bigint * b)
+{
+ int i, wds;
+ unsigned long *x, y;
+ wds = b->_wds;
+ x = b->_x+wds;
+ i = 0;
+ do
+ {
+ x--;
+ fprintf (stderr, "%08x", *x);
+ }
+ while (++i < wds);
+ fprintf (stderr, "\n");
+}
+#endif
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the long
+ * calculation.
+ */
+
+
+char *
+_DEFUN (_dtoa_r,
+ (ptr, _d, mode, ndigits, decpt, sign, rve, float_type),
+ struct _Jv_reent *ptr _AND
+ double _d _AND
+ int mode _AND
+ int ndigits _AND
+ int *decpt _AND
+ int *sign _AND
+ char **rve _AND
+ int float_type)
+{
+ /*
+ float_type == 0 for double precision, 1 for float.
+
+ Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ > 16 ==> Floating-point arg is treated as single precision.
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim0, j, j1, k, k0,
+ k_check, leftright, m2, m5, s2, s5, try_quick;
+ int ilim = 0, ilim1 = 0, spec_case = 0;
+ union double_union d, d2, eps;
+ long L;
+#ifndef Sudden_Underflow
+ int denorm;
+ unsigned long x;
+#endif
+ _Jv_Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S;
+ double ds;
+ char *s, *s0;
+
+ d.d = _d;
+
+ if (ptr->_result)
+ {
+ ptr->_result->_k = ptr->_result_k;
+ ptr->_result->_maxwds = 1 << ptr->_result_k;
+ Bfree (ptr, ptr->_result);
+ ptr->_result = 0;
+ }
+
+ if (word0 (d) & Sign_bit)
+ {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0 (d) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0 (d) & Exp_mask) == Exp_mask)
+#else
+ if (word0 (d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+ s =
+#ifdef IEEE_Arith
+ !word1 (d) && !(word0 (d) & 0xfffff) ? "Infinity" :
+#endif
+ "NaN";
+ if (rve)
+ *rve =
+#ifdef IEEE_Arith
+ s[3] ? s + 8 :
+#endif
+ s + 3;
+ return s;
+ }
+#endif
+#ifdef IBM
+ d.d += 0; /* normalize */
+#endif
+ if (!d.d)
+ {
+ *decpt = 1;
+ s = "0";
+ if (rve)
+ *rve = s + 1;
+ return s;
+ }
+
+ b = d2b (ptr, d.d, &be, &bbits);
+#ifdef Sudden_Underflow
+ i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1));
+#else
+ if ((i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1))))
+ {
+#endif
+ d2.d = d.d;
+ word0 (d2) &= Frac_mask1;
+ word0 (d2) |= Exp_11;
+#ifdef IBM
+ if (j = 11 - hi0bits (word0 (d2) & Frac_mask))
+ d2.d /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else
+ {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P - 1) - 1);
+ x = i > 32 ? word0 (d) << (64 - i) | word1 (d) >> (i - 32)
+ : word1 (d) << (32 - i);
+ d2.d = x;
+ word0 (d2) -= 31 * Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P - 1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+ ds = (d2.d - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981;
+ k = (int) ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax)
+ {
+ if (d.d < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0)
+ {
+ b2 = 0;
+ s2 = j;
+ }
+ else
+ {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0)
+ {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else
+ {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5)
+ {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch (mode)
+ {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ j = sizeof (unsigned long);
+ for (ptr->_result_k = 0; (int) (sizeof (_Jv_Bigint) - sizeof (unsigned long)) + j <= i;
+ j <<= 1)
+ ptr->_result_k++;
+ ptr->_result = Balloc (ptr, ptr->_result_k);
+ s = s0 = (char *) ptr->_result;
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick)
+ {
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2.d = d.d;
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0)
+ {
+ ds = tens[k & 0xf];
+ j = k >> 4;
+ if (j & Bletch)
+ {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ d.d /= bigtens[n_bigtens - 1];
+ ieps++;
+ }
+ for (; j; j >>= 1, i++)
+ if (j & 1)
+ {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ d.d /= ds;
+ }
+ else if ((j1 = -k))
+ {
+ d.d *= tens[j1 & 0xf];
+ for (j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1)
+ {
+ ieps++;
+ d.d *= bigtens[i];
+ }
+ }
+ if (k_check && d.d < 1. && ilim > 0)
+ {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ d.d *= 10.;
+ ieps++;
+ }
+ eps.d = ieps * d.d + 7.;
+ word0 (eps) -= (P - 1) * Exp_msk1;
+ if (ilim == 0)
+ {
+ S = mhi = 0;
+ d.d -= 5.;
+ if (d.d > eps.d)
+ goto one_digit;
+ if (d.d < -eps.d)
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright)
+ {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ eps.d = 0.5 / tens[ilim - 1] - eps.d;
+ for (i = 0;;)
+ {
+ L = d.d;
+ d.d -= L;
+ *s++ = '0' + (int) L;
+ if (d.d < eps.d)
+ goto ret1;
+ if (1. - d.d < eps.d)
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ eps.d *= 10.;
+ d.d *= 10.;
+ }
+ }
+ else
+ {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ eps.d *= tens[ilim - 1];
+ for (i = 1;; i++, d.d *= 10.)
+ {
+ L = d.d;
+ d.d -= L;
+ *s++ = '0' + (int) L;
+ if (i == ilim)
+ {
+ if (d.d > 0.5 + eps.d)
+ goto bump_up;
+ else if (d.d < 0.5 - eps.d)
+ {
+ while (*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ d.d = d2.d;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max)
+ {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0)
+ {
+ S = mhi = 0;
+ if (ilim < 0 || d.d <= 5 * ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for (i = 1;; i++)
+ {
+ L = d.d / ds;
+ d.d -= L * ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (d.d < 0)
+ {
+ L--;
+ d.d += ds;
+ }
+#endif
+ *s++ = '0' + (int) L;
+ if (i == ilim)
+ {
+ d.d += d.d;
+ if (d.d > ds || (d.d == ds && L & 1))
+ {
+ bump_up:
+ while (*--s == '9')
+ if (s == s0)
+ {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ if (!(d.d *= 10.))
+ break;
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright)
+ {
+ if (mode < 2)
+ {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P - 1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4 * P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ }
+ else
+ {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else
+ {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0)
+ {
+ m2 -= i;
+ i = 0;
+ }
+ }
+ b2 += i;
+ s2 += i;
+ mhi = i2b (ptr, 1);
+ }
+ if (m2 > 0 && s2 > 0)
+ {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0)
+ {
+ if (leftright)
+ {
+ if (m5 > 0)
+ {
+ mhi = pow5mult (ptr, mhi, m5);
+ b1 = mult (ptr, mhi, b);
+ Bfree (ptr, b);
+ b = b1;
+ }
+ if ((j = b5 - m5))
+ b = pow5mult (ptr, b, j);
+ }
+ else
+ b = pow5mult (ptr, b, b5);
+ }
+ S = i2b (ptr, 1);
+ if (s5 > 0)
+ S = pow5mult (ptr, S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ if (mode < 2)
+ {
+ if (!word1 (d) && !(word0 (d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && word0(d) & Exp_mask
+#endif
+ )
+ {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ else
+ spec_case = 0;
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+
+#ifdef Pack_32
+ if ((i = ((s5 ? 32 - hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0x1f))
+ i = 32 - i;
+#else
+ if ((i = ((s5 ? 32 - hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0xf))
+ i = 16 - i;
+#endif
+ if (i > 4)
+ {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4)
+ {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift (ptr, b, b2);
+ if (s2 > 0)
+ S = lshift (ptr, S, s2);
+ if (k_check)
+ {
+ if (cmp (b, S) < 0)
+ {
+ k--;
+ b = multadd (ptr, b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd (ptr, mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && mode > 2)
+ {
+ if (ilim < 0 || cmp (b, S = multadd (ptr, S, 5, 0)) <= 0)
+ {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright)
+ {
+ if (m2 > 0)
+ mhi = lshift (ptr, mhi, m2);
+
+ /* Single precision case, */
+ if (float_type)
+ mhi = lshift (ptr, mhi, 29);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case)
+ {
+ mhi = Balloc (ptr, mhi->_k);
+ Bcopy (mhi, mlo);
+ mhi = lshift (ptr, mhi, Log2P);
+ }
+
+ for (i = 1;; i++)
+ {
+ dig = quorem (b, S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp (b, mlo);
+ delta = diff (ptr, S, mhi);
+ j1 = delta->_sign ? 1 : cmp (b, delta);
+ Bfree (ptr, delta);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && !mode && !(word1 (d) & 1))
+ {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && !mode
+#ifndef ROUND_BIASED
+ && !(word1 (d) & 1)
+#endif
+ ))
+ {
+ if (j1 > 0)
+ {
+ b = lshift (ptr, b, 1);
+ j1 = cmp (b, S);
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0)
+ {
+ if (dig == '9')
+ { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd (ptr, b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd (ptr, mhi, 10, 0);
+ else
+ {
+ mlo = multadd (ptr, mlo, 10, 0);
+ mhi = multadd (ptr, mhi, 10, 0);
+ }
+ }
+ }
+ else
+ for (i = 1;; i++)
+ {
+ *s++ = dig = quorem (b, S) + '0';
+ if (i >= ilim)
+ break;
+ b = multadd (ptr, b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+ b = lshift (ptr, b, 1);
+ j = cmp (b, S);
+ if (j > 0 || (j == 0 && dig & 1))
+ {
+ roundoff:
+ while (*--s == '9')
+ if (s == s0)
+ {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else
+ {
+ while (*--s == '0');
+ s++;
+ }
+ret:
+ Bfree (ptr, S);
+ if (mhi)
+ {
+ if (mlo && mlo != mhi)
+ Bfree (ptr, mlo);
+ Bfree (ptr, mhi);
+ }
+ret1:
+ Bfree (ptr, b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+}
+
+
+_VOID
+_DEFUN (_dtoa,
+ (_d, mode, ndigits, decpt, sign, rve, buf, float_type),
+ double _d _AND
+ int mode _AND
+ int ndigits _AND
+ int *decpt _AND
+ int *sign _AND
+ char **rve _AND
+ char *buf _AND
+ int float_type)
+{
+ struct _Jv_reent reent;
+ char *p;
+ memset (&reent, 0, sizeof reent);
+
+ p = _dtoa_r (&reent, _d, mode, ndigits, decpt, sign, rve, float_type);
+ strcpy (buf, p);
+
+ return;
+}
diff --git a/libjava/classpath/native/fdlibm/e_acos.c b/libjava/classpath/native/fdlibm/e_acos.c
new file mode 100644
index 00000000000..ee6b168a1c5
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_acos.c
@@ -0,0 +1,111 @@
+
+/* @(#)e_acos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_acos(x)
+ * Method :
+ * acos(x) = pi/2 - asin(x)
+ * acos(-x) = pi/2 + asin(x)
+ * For |x|<=0.5
+ * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c)
+ * For x>0.5
+ * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
+ * = 2asin(sqrt((1-x)/2))
+ * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z)
+ * = 2f + (2c + 2s*z*R(z))
+ * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
+ * for f so that f+c ~ sqrt(z).
+ * For x<-0.5
+ * acos(x) = pi - 2asin(sqrt((1-|x|)/2))
+ * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ * Function needed: sqrt
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
+pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+#ifdef __STDC__
+ double __ieee754_acos(double x)
+#else
+ double __ieee754_acos(x)
+ double x;
+#endif
+{
+ double z,p,q,r,w,s,c,df;
+ int32_t hx,ix;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x3ff00000) { /* |x| >= 1 */
+ uint32_t lx;
+ GET_LOW_WORD(lx,x);
+ if(((ix-0x3ff00000)|lx)==0) { /* |x|==1 */
+ if(hx>0) return 0.0; /* acos(1) = 0 */
+ else return pi+2.0*pio2_lo; /* acos(-1)= pi */
+ }
+ return (x-x)/(x-x); /* acos(|x|>1) is NaN */
+ }
+ if(ix<0x3fe00000) { /* |x| < 0.5 */
+ if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
+ z = x*x;
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ r = p/q;
+ return pio2_hi - (x - (pio2_lo-x*r));
+ } else if (hx<0) { /* x < -0.5 */
+ z = (one+x)*0.5;
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ s = __ieee754_sqrt(z);
+ r = p/q;
+ w = r*s-pio2_lo;
+ return pi - 2.0*(s+w);
+ } else { /* x > 0.5 */
+ z = (one-x)*0.5;
+ s = __ieee754_sqrt(z);
+ df = s;
+ SET_LOW_WORD(df,0);
+ c = (z-df*df)/(s+df);
+ p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+ q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+ r = p/q;
+ w = r*s+c;
+ return 2.0*(df+w);
+ }
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/e_asin.c b/libjava/classpath/native/fdlibm/e_asin.c
new file mode 100644
index 00000000000..90fc77ffc3b
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_asin.c
@@ -0,0 +1,120 @@
+
+/* @(#)e_asin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_asin(x)
+ * Method :
+ * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
+ * we approximate asin(x) on [0,0.5] by
+ * asin(x) = x + x*x^2*R(x^2)
+ * where
+ * R(x^2) is a rational approximation of (asin(x)-x)/x^3
+ * and its remez error is bounded by
+ * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
+ *
+ * For x in [0.5,1]
+ * asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ * then for x>0.98
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ * For x<=0.98, let pio4_hi = pio2_hi/2, then
+ * f = hi part of s;
+ * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
+ * and
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+huge = 1.000e+300,
+pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
+ /* coefficient for R(x^2) */
+pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+#ifdef __STDC__
+ double __ieee754_asin(double x)
+#else
+ double __ieee754_asin(x)
+ double x;
+#endif
+{
+ double t = 0., w, p, q, c, r, s;
+ int32_t hx,ix;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>= 0x3ff00000) { /* |x|>= 1 */
+ uint32_t lx;
+ GET_LOW_WORD(lx,x);
+ if(((ix-0x3ff00000)|lx)==0)
+ /* asin(1)=+-pi/2 with inexact */
+ return x*pio2_hi+x*pio2_lo;
+ return (x-x)/(x-x); /* asin(|x|>1) is NaN */
+ } else if (ix<0x3fe00000) { /* |x|<0.5 */
+ if(ix<0x3e400000) { /* if |x| < 2**-27 */
+ if(huge+x>one) return x;/* return x with inexact if x!=0*/
+ } else
+ t = x*x;
+ p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+ q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+ w = p/q;
+ return x+x*w;
+ }
+ /* 1> |x|>= 0.5 */
+ w = one-fabs(x);
+ t = w*0.5;
+ p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+ q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+ s = __ieee754_sqrt(t);
+ if(ix>=0x3FEF3333) { /* if |x| > 0.975 */
+ w = p/q;
+ t = pio2_hi-(2.0*(s+s*w)-pio2_lo);
+ } else {
+ w = s;
+ SET_LOW_WORD(w,0);
+ c = (t-w*w)/(s+w);
+ r = p/q;
+ p = 2.0*s*r-(pio2_lo-2.0*c);
+ q = pio4_hi-2.0*w;
+ t = pio4_hi-(p-q);
+ }
+ if(hx>0) return t; else return -t;
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/e_atan2.c b/libjava/classpath/native/fdlibm/e_atan2.c
new file mode 100644
index 00000000000..c75448db26c
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_atan2.c
@@ -0,0 +1,131 @@
+
+/* @(#)e_atan2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_atan2(y,x)
+ * Method :
+ * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
+ * 2. Reduce x to positive by (if x and y are unexceptional):
+ * ARG (x+iy) = arctan(y/x) ... if x > 0,
+ * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
+ *
+ * Special cases:
+ *
+ * ATAN2((anything), NaN ) is NaN;
+ * ATAN2(NAN , (anything) ) is NaN;
+ * ATAN2(+-0, +(anything but NaN)) is +-0 ;
+ * ATAN2(+-0, -(anything but NaN)) is +-pi ;
+ * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
+ * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
+ * ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
+ * ATAN2(+-INF,+INF ) is +-pi/4 ;
+ * ATAN2(+-INF,-INF ) is +-3pi/4;
+ * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+tiny = 1.0e-300,
+zero = 0.0,
+pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
+pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
+pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
+pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
+
+#ifdef __STDC__
+ double __ieee754_atan2(double y, double x)
+#else
+ double __ieee754_atan2(y,x)
+ double y,x;
+#endif
+{
+ double z;
+ int32_t k,m,hx,hy,ix,iy;
+ uint32_t lx,ly;
+
+ EXTRACT_WORDS(hx,lx,x);
+ ix = hx&0x7fffffff;
+ EXTRACT_WORDS(hy,ly,y);
+ iy = hy&0x7fffffff;
+ if(((ix|((lx|-lx)>>31))>0x7ff00000)||
+ ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */
+ return x+y;
+ if(((hx-0x3ff00000)|lx)==0) return atan(y); /* x=1.0 */
+ m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
+
+ /* when y = 0 */
+ if((iy|ly)==0) {
+ switch(m) {
+ case 0:
+ case 1: return y; /* atan(+-0,+anything)=+-0 */
+ case 2: return pi+tiny;/* atan(+0,-anything) = pi */
+ case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+ }
+ }
+ /* when x = 0 */
+ if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* when x is INF */
+ if(ix==0x7ff00000) {
+ if(iy==0x7ff00000) {
+ switch(m) {
+ case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
+ case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+ case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
+ case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
+ }
+ } else {
+ switch(m) {
+ case 0: return zero ; /* atan(+...,+INF) */
+ case 1: return -zero ; /* atan(-...,+INF) */
+ case 2: return pi+tiny ; /* atan(+...,-INF) */
+ case 3: return -pi-tiny ; /* atan(-...,-INF) */
+ }
+ }
+ }
+ /* when y is INF */
+ if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+ /* compute y/x */
+ k = (iy-ix)>>20;
+ if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */
+ else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
+ else z=atan(fabs(y/x)); /* safe to do y/x */
+ switch (m) {
+ case 0: return z ; /* atan(+,+) */
+ case 1: {
+ uint32_t zh;
+ GET_HIGH_WORD(zh,z);
+ SET_HIGH_WORD(z,zh ^ 0x80000000);
+ }
+ return z ; /* atan(-,+) */
+ case 2: return pi-(z-pi_lo);/* atan(+,-) */
+ default: /* case 3 */
+ return (z-pi_lo)-pi;/* atan(-,-) */
+ }
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/e_exp.c b/libjava/classpath/native/fdlibm/e_exp.c
new file mode 100644
index 00000000000..ad37f86b029
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_exp.c
@@ -0,0 +1,167 @@
+
+/* @(#)e_exp.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_exp(x)
+ * Returns the exponential of x.
+ *
+ * Method
+ * 1. Argument reduction:
+ * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
+ * Given x, find r and integer k such that
+ *
+ * x = k*ln2 + r, |r| <= 0.5*ln2.
+ *
+ * Here r will be represented as r = hi-lo for better
+ * accuracy.
+ *
+ * 2. Approximation of exp(r) by a special rational function on
+ * the interval [0,0.34658]:
+ * Write
+ * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
+ * We use a special Reme algorithm on [0,0.34658] to generate
+ * a polynomial of degree 5 to approximate R. The maximum error
+ * of this polynomial approximation is bounded by 2**-59. In
+ * other words,
+ * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
+ * (where z=r*r, and the values of P1 to P5 are listed below)
+ * and
+ * | 5 | -59
+ * | 2.0+P1*z+...+P5*z - R(z) | <= 2
+ * | |
+ * The computation of exp(r) thus becomes
+ * 2*r
+ * exp(r) = 1 + -------
+ * R - r
+ * r*R1(r)
+ * = 1 + r + ----------- (for better accuracy)
+ * 2 - R1(r)
+ * where
+ * 2 4 10
+ * R1(r) = r - (P1*r + P2*r + ... + P5*r ).
+ *
+ * 3. Scale back to obtain exp(x):
+ * From step 1, we have
+ * exp(x) = 2^k * exp(r)
+ *
+ * Special cases:
+ * exp(INF) is INF, exp(NaN) is NaN;
+ * exp(-INF) is 0, and
+ * for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ * For IEEE double
+ * if x > 7.09782712893383973096e+02 then exp(x) overflow
+ * if x < -7.45133219101941108420e+02 then exp(x) underflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.0,
+halF[2] = {0.5,-0.5,},
+huge = 1.0e+300,
+twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/
+o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */
+ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
+ -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */
+ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
+ -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */
+invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
+P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
+
+
+#ifdef __STDC__
+ double __ieee754_exp(double x) /* default IEEE double exp */
+#else
+ double __ieee754_exp(x) /* default IEEE double exp */
+ double x;
+#endif
+{
+ double y,hi = 0., lo = 0.,c,t;
+ int32_t k = 0, xsb;
+ uint32_t hx;
+
+ GET_HIGH_WORD(hx,x);
+ xsb = (hx>>31)&1; /* sign bit of x */
+ hx &= 0x7fffffff; /* high word of |x| */
+
+ /* filter out non-finite argument */
+ if(hx >= 0x40862E42) { /* if |x|>=709.78... */
+ if(hx>=0x7ff00000) {
+ uint32_t lx;
+ GET_LOW_WORD(lx,x);
+ if(((hx&0xfffff)|lx)!=0)
+ return x+x; /* NaN */
+ else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */
+ }
+ if(x > o_threshold) return huge*huge; /* overflow */
+ if(x < u_threshold) return twom1000*twom1000; /* underflow */
+ }
+
+ /* argument reduction */
+ if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
+ if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
+ hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
+ } else {
+ k = invln2*x+halF[xsb];
+ t = k;
+ hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
+ lo = t*ln2LO[0];
+ }
+ x = hi - lo;
+ }
+ else if(hx < 0x3e300000) { /* when |x|<2**-28 */
+ if(huge+x>one) return one+x;/* trigger inexact */
+ }
+ else k = 0;
+
+ /* x is now in primary range */
+ t = x*x;
+ c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ if(k==0) return one-((x*c)/(c-2.0)-x);
+ else y = one-((lo-(x*c)/(2.0-c))-hi);
+ if(k >= -1021) {
+ uint32_t hy;
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(y,hy+(k<<20)); /* add k to y's exponent */
+ return y;
+ } else {
+ uint32_t hy;
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(y,hy+((k+1000)<<20)); /* add k to y's exponent */
+ return y*twom1000;
+ }
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/e_fmod.c b/libjava/classpath/native/fdlibm/e_fmod.c
new file mode 100644
index 00000000000..1cf09907666
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_fmod.c
@@ -0,0 +1,140 @@
+
+/* @(#)e_fmod.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __ieee754_fmod(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double one = 1.0, Zero[] = {0.0, -0.0,};
+#else
+static double one = 1.0, Zero[] = {0.0, -0.0,};
+#endif
+
+#ifdef __STDC__
+ double __ieee754_fmod(double x, double y)
+#else
+ double __ieee754_fmod(x,y)
+ double x,y ;
+#endif
+{
+ int32_t n,hx,hy,hz,ix,iy,sx,i;
+ uint32_t lx,ly,lz;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ sx = hx&0x80000000; /* sign of x */
+ hx ^=sx; /* |x| */
+ hy &= 0x7fffffff; /* |y| */
+
+ /* purge off exception values */
+ if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
+ ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
+ return (x*y)/(x*y);
+ if(hx<=hy) {
+ if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
+ if(lx==ly)
+ return Zero[(uint32_t)sx>>31]; /* |x|=|y| return x*0*/
+ }
+
+ /* determine ix = ilogb(x) */
+ if(hx<0x00100000) { /* subnormal x */
+ if(hx==0) {
+ for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
+ } else {
+ for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
+ }
+ } else ix = (hx>>20)-1023;
+
+ /* determine iy = ilogb(y) */
+ if(hy<0x00100000) { /* subnormal y */
+ if(hy==0) {
+ for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
+ } else {
+ for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
+ }
+ } else iy = (hy>>20)-1023;
+
+ /* set up {hx,lx}, {hy,ly} and align y to x */
+ if(ix >= -1022)
+ hx = 0x00100000|(0x000fffff&hx);
+ else { /* subnormal x, shift x to normal */
+ n = -1022-ix;
+ if(n<=31) {
+ hx = (hx<<n)|(lx>>(32-n));
+ lx <<= n;
+ } else {
+ hx = lx<<(n-32);
+ lx = 0;
+ }
+ }
+ if(iy >= -1022)
+ hy = 0x00100000|(0x000fffff&hy);
+ else { /* subnormal y, shift y to normal */
+ n = -1022-iy;
+ if(n<=31) {
+ hy = (hy<<n)|(ly>>(32-n));
+ ly <<= n;
+ } else {
+ hy = ly<<(n-32);
+ ly = 0;
+ }
+ }
+
+ /* fix point fmod */
+ n = ix - iy;
+ while(n--) {
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
+ else {
+ if((hz|lz)==0) /* return sign(x)*0 */
+ return Zero[(uint32_t)sx>>31];
+ hx = hz+hz+(lz>>31); lx = lz+lz;
+ }
+ }
+ hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+ if(hz>=0) {hx=hz;lx=lz;}
+
+ /* convert back to floating value and restore the sign */
+ if((hx|lx)==0) /* return sign(x)*0 */
+ return Zero[(uint32_t)sx>>31];
+ while(hx<0x00100000) { /* normalize x */
+ hx = hx+hx+(lx>>31); lx = lx+lx;
+ iy -= 1;
+ }
+ if(iy>= -1022) { /* normalize output */
+ hx = ((hx-0x00100000)|((iy+1023)<<20));
+ INSERT_WORDS(x,hx|sx,lx);
+ } else { /* subnormal output */
+ n = -1022 - iy;
+ if(n<=20) {
+ lx = (lx>>n)|((uint32_t)hx<<(32-n));
+ hx >>= n;
+ } else if (n<=31) {
+ lx = (hx<<(32-n))|(lx>>n); hx = sx;
+ } else {
+ lx = hx>>(n-32); hx = sx;
+ }
+ INSERT_WORDS(x,hx|sx,lx);
+ x *= one; /* create necessary signal */
+ }
+ return x; /* exact output */
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/e_log.c b/libjava/classpath/native/fdlibm/e_log.c
new file mode 100644
index 00000000000..093473e1048
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_log.c
@@ -0,0 +1,152 @@
+
+/* @(#)e_log.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_log(x)
+ * Return the logrithm of x
+ *
+ * Method :
+ * 1. Argument Reduction: find k and f such that
+ * x = 2^k * (1+f),
+ * where sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ * 2. Approximation of log(1+f).
+ * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ * = 2s + s*R
+ * We use a special Reme algorithm on [0,0.1716] to generate
+ * a polynomial of degree 14 to approximate R The maximum error
+ * of this polynomial approximation is bounded by 2**-58.45. In
+ * other words,
+ * 2 4 6 8 10 12 14
+ * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
+ * (the values of Lg1 to Lg7 are listed in the program)
+ * and
+ * | 2 14 | -58.45
+ * | Lg1*s +...+Lg7*s - R(z) | <= 2
+ * | |
+ * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ * In order to guarantee error in log below 1ulp, we compute log
+ * by
+ * log(1+f) = f - s*(f - R) (if f is not too large)
+ * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
+ *
+ * 3. Finally, log(x) = k*ln2 + log(1+f).
+ * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ * Here ln2 is split into two floating point number:
+ * ln2_hi + ln2_lo,
+ * where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ * log(x) is NaN with signal if x < 0 (including -INF) ;
+ * log(+INF) is +INF; log(0) is -INF with signal;
+ * log(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
+ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
+two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_log(double x)
+#else
+ double __ieee754_log(x)
+ double x;
+#endif
+{
+ double hfsq,f,s,z,R,w,t1,t2,dk;
+ int32_t k,hx,i,j;
+ uint32_t lx;
+
+ EXTRACT_WORDS(hx,lx,x);
+
+ k=0;
+ if (hx < 0x00100000) { /* x < 2**-1022 */
+ if (((hx&0x7fffffff)|lx)==0)
+ return -two54/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ k -= 54; x *= two54; /* subnormal number, scale up x */
+ GET_HIGH_WORD(hx,x);
+ }
+ if (hx >= 0x7ff00000) return x+x;
+ k += (hx>>20)-1023;
+ hx &= 0x000fffff;
+ i = (hx+0x95f64)&0x100000;
+ SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
+ k += (i>>20);
+ f = x-1.0;
+ if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
+ if(f==zero) {
+ if(k==0)
+ return zero;
+ else {
+ dk=(double)k;
+ return dk*ln2_hi+dk*ln2_lo;
+ }
+ }
+ R = f*f*(0.5-0.33333333333333333*f);
+ if(k==0) return f-R; else {dk=(double)k;
+ return dk*ln2_hi-((R-dk*ln2_lo)-f);}
+ }
+ s = f/(2.0+f);
+ dk = (double)k;
+ z = s*s;
+ i = hx-0x6147a;
+ w = z*z;
+ j = 0x6b851-hx;
+ t1= w*(Lg2+w*(Lg4+w*Lg6));
+ t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
+ i |= j;
+ R = t2+t1;
+ if(i>0) {
+ hfsq=0.5*f*f;
+ if(k==0) return f-(hfsq-s*(hfsq+R)); else
+ return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
+ } else {
+ if(k==0) return f-s*(f-R); else
+ return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
+ }
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/e_pow.c b/libjava/classpath/native/fdlibm/e_pow.c
new file mode 100644
index 00000000000..b21c0e92b39
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_pow.c
@@ -0,0 +1,312 @@
+
+/* @(#)e_pow.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_pow(x,y) return x**y
+ *
+ * n
+ * Method: Let x = 2 * (1+f)
+ * 1. Compute and return log2(x) in two pieces:
+ * log2(x) = w1 + w2,
+ * where w1 has 53-24 = 29 bit trailing zeros.
+ * 2. Perform y*log2(x) = n+y' by simulating muti-precision
+ * arithmetic, where |y'|<=0.5.
+ * 3. Return x**y = 2**n*exp(y'*log2)
+ *
+ * Special cases:
+ * 1. (anything) ** 0 is 1
+ * 2. (anything) ** 1 is itself
+ * 3. (anything) ** NAN is NAN
+ * 4. NAN ** (anything except 0) is NAN
+ * 5. +-(|x| > 1) ** +INF is +INF
+ * 6. +-(|x| > 1) ** -INF is +0
+ * 7. +-(|x| < 1) ** +INF is +0
+ * 8. +-(|x| < 1) ** -INF is +INF
+ * 9. +-1 ** +-INF is NAN
+ * 10. +0 ** (+anything except 0, NAN) is +0
+ * 11. -0 ** (+anything except 0, NAN, odd integer) is +0
+ * 12. +0 ** (-anything except 0, NAN) is +INF
+ * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
+ * 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
+ * 15. +INF ** (+anything except 0,NAN) is +INF
+ * 16. +INF ** (-anything except 0,NAN) is +0
+ * 17. -INF ** (anything) = -0 ** (-anything)
+ * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ * 19. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ * Accuracy:
+ * pow(x,y) returns x**y nearly rounded. In particular
+ * pow(integer,integer)
+ * always returns the correct integer provided it is
+ * representable.
+ *
+ * Constants :
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+bp[] = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
+dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
+zero = 0.0,
+one = 1.0,
+two = 2.0,
+two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */
+huge = 1.0e300,
+tiny = 1.0e-300,
+ /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
+L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
+L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
+L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
+L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
+L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
+P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
+lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
+lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
+ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
+cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
+cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
+cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
+ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
+ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
+ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
+
+#ifdef __STDC__
+ double __ieee754_pow(double x, double y)
+#else
+ double __ieee754_pow(x,y)
+ double x, y;
+#endif
+{
+ double z,ax,z_h,z_l,p_h,p_l;
+ double y1,t1,t2,r,s,t,u,v,w;
+ int32_t i,j,k,yisint,n;
+ int32_t hx,hy,ix,iy;
+ uint32_t lx,ly;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hy,ly,y);
+ ix = hx&0x7fffffff; iy = hy&0x7fffffff;
+
+ /* y==zero: x**0 = 1 */
+ if((iy|ly)==0) return one;
+
+ /* +-NaN return x+y */
+ if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
+ iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
+ return x+y;
+
+ /* determine if y is an odd int when x < 0
+ * yisint = 0 ... y is not an integer
+ * yisint = 1 ... y is an odd int
+ * yisint = 2 ... y is an even int
+ */
+ yisint = 0;
+ if(hx<0) {
+ if(iy>=0x43400000) yisint = 2; /* even integer y */
+ else if(iy>=0x3ff00000) {
+ k = (iy>>20)-0x3ff; /* exponent */
+ if(k>20) {
+ j = ly>>(52-k);
+ if((uint32_t)(j<<(52-k))==ly) yisint = 2-(j&1);
+ } else if(ly==0) {
+ j = iy>>(20-k);
+ if((j<<(20-k))==iy) yisint = 2-(j&1);
+ }
+ }
+ }
+
+ /* special value of y */
+ if(ly==0) {
+ if (iy==0x7ff00000) { /* y is +-inf */
+ if(((ix-0x3ff00000)|lx)==0)
+ return y - y; /* inf**+-1 is NaN */
+ else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
+ return (hy>=0)? y: zero;
+ else /* (|x|<1)**-,+inf = inf,0 */
+ return (hy<0)?-y: zero;
+ }
+ if(iy==0x3ff00000) { /* y is +-1 */
+ if(hy<0) return one/x; else return x;
+ }
+ if(hy==0x40000000) return x*x; /* y is 2 */
+ if(hy==0x3fe00000) { /* y is 0.5 */
+ if(hx>=0) /* x >= +0 */
+ return __ieee754_sqrt(x);
+ }
+ }
+
+ ax = fabs(x);
+ /* special value of x */
+ if(lx==0) {
+ if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
+ z = ax; /*x is +-0,+-inf,+-1*/
+ if(hy<0) z = one/z; /* z = (1/|x|) */
+ if(hx<0) {
+ if(((ix-0x3ff00000)|yisint)==0) {
+ z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+ } else if(yisint==1)
+ z = -z; /* (x<0)**odd = -(|x|**odd) */
+ }
+ return z;
+ }
+ }
+
+ /* (x<0)**(non-int) is NaN */
+ /* GCJ LOCAL: This used to be
+ if((((hx>>31)+1)|yisint)==0) return (x-x)/(x-x);
+ but ANSI C says a right shift of a signed negative quantity is
+ implementation defined. */
+ if(((((uint32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x);
+
+ /* |y| is huge */
+ if(iy>0x41e00000) { /* if |y| > 2**31 */
+ if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */
+ if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
+ if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
+ }
+ /* over/underflow if x is not close to one */
+ if(ix<0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
+ if(ix>0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
+ /* now |1-x| is tiny <= 2**-20, suffice to compute
+ log(x) by x-x^2/2+x^3/3-x^4/4 */
+ t = x-1; /* t has 20 trailing zeros */
+ w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
+ u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
+ v = t*ivln2_l-w*ivln2;
+ t1 = u+v;
+ SET_LOW_WORD(t1,0);
+ t2 = v-(t1-u);
+ } else {
+ double s2,s_h,s_l,t_h,t_l;
+ n = 0;
+ /* take care subnormal number */
+ if(ix<0x00100000)
+ {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); }
+ n += ((ix)>>20)-0x3ff;
+ j = ix&0x000fffff;
+ /* determine interval */
+ ix = j|0x3ff00000; /* normalize ix */
+ if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */
+ else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */
+ else {k=0;n+=1;ix -= 0x00100000;}
+ SET_HIGH_WORD(ax,ix);
+
+ /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+ u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
+ v = one/(ax+bp[k]);
+ s = u*v;
+ s_h = s;
+ SET_LOW_WORD(s_h,0);
+ /* t_h=ax+bp[k] High */
+ t_h = zero;
+ SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18));
+ t_l = ax - (t_h-bp[k]);
+ s_l = v*((u-s_h*t_h)-s_h*t_l);
+ /* compute log(ax) */
+ s2 = s*s;
+ r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+ r += s_l*(s_h+s);
+ s2 = s_h*s_h;
+ t_h = 3.0+s2+r;
+ SET_LOW_WORD(t_h,0);
+ t_l = r-((t_h-3.0)-s2);
+ /* u+v = s*(1+...) */
+ u = s_h*t_h;
+ v = s_l*t_h+t_l*s;
+ /* 2/(3log2)*(s+...) */
+ p_h = u+v;
+ SET_LOW_WORD(p_h,0);
+ p_l = v-(p_h-u);
+ z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
+ z_l = cp_l*p_h+p_l*cp+dp_l[k];
+ /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+ t = (double)n;
+ t1 = (((z_h+z_l)+dp_h[k])+t);
+ SET_LOW_WORD(t1,0);
+ t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+ }
+
+ s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
+ if(((((uint32_t)hx>>31)-1)|(yisint-1))==0)
+ s = -one;/* (-ve)**(odd int) */
+
+ /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+ y1 = y;
+ SET_LOW_WORD(y1,0);
+ p_l = (y-y1)*t1+y*t2;
+ p_h = y1*t1;
+ z = p_l+p_h;
+ EXTRACT_WORDS(j,i,z);
+ if (j>=0x40900000) { /* z >= 1024 */
+ if(((j-0x40900000)|i)!=0) /* if z > 1024 */
+ return s*huge*huge; /* overflow */
+ else {
+ if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
+ }
+ } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */
+ if(((j-0xc090cc00)|i)!=0) /* z < -1075 */
+ return s*tiny*tiny; /* underflow */
+ else {
+ if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
+ }
+ }
+ /*
+ * compute 2**(p_h+p_l)
+ */
+ i = j&0x7fffffff;
+ k = (i>>20)-0x3ff;
+ n = 0;
+ if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */
+ n = j+(0x00100000>>(k+1));
+ k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */
+ t = zero;
+ SET_HIGH_WORD(t,n&~(0x000fffff>>k));
+ n = ((n&0x000fffff)|0x00100000)>>(20-k);
+ if(j<0) n = -n;
+ p_h -= t;
+ }
+ t = p_l+p_h;
+ SET_LOW_WORD(t,0);
+ u = t*lg2_h;
+ v = (p_l-(t-p_h))*lg2+t*lg2_l;
+ z = u+v;
+ w = v-(z-u);
+ t = z*z;
+ t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+ r = (z*t1)/(t1-two)-(w+z*w);
+ z = one-(r-z);
+ GET_HIGH_WORD(j,z);
+ j += (n<<20);
+ if((j>>20)<=0) z = scalbn(z,(int)n); /* subnormal output */
+ else SET_HIGH_WORD(z,j);
+ return s*z;
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/e_rem_pio2.c b/libjava/classpath/native/fdlibm/e_rem_pio2.c
new file mode 100644
index 00000000000..543234c60c5
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_rem_pio2.c
@@ -0,0 +1,185 @@
+
+/* @(#)e_rem_pio2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_rem_pio2(x,y)
+ *
+ * return the remainder of x rem pi/2 in y[0]+y[1]
+ * use __kernel_rem_pio2()
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
+ */
+#ifdef __STDC__
+static const int32_t two_over_pi[] = {
+#else
+static int32_t two_over_pi[] = {
+#endif
+0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
+0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
+0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
+0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
+0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
+0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
+0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
+0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
+0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
+0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
+0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
+};
+
+#ifdef __STDC__
+static const int32_t npio2_hw[] = {
+#else
+static int32_t npio2_hw[] = {
+#endif
+0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
+0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
+0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
+0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
+0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
+0x404858EB, 0x404921FB,
+};
+
+/*
+ * invpio2: 53 bits of 2/pi
+ * pio2_1: first 33 bit of pi/2
+ * pio2_1t: pi/2 - pio2_1
+ * pio2_2: second 33 bit of pi/2
+ * pio2_2t: pi/2 - (pio2_1+pio2_2)
+ * pio2_3: third 33 bit of pi/2
+ * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
+pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
+pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
+pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
+pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
+pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
+
+#ifdef __STDC__
+ int32_t __ieee754_rem_pio2(double x, double *y)
+#else
+ int32_t __ieee754_rem_pio2(x,y)
+ double x,y[];
+#endif
+{
+ double z = 0., w, t, r, fn;
+ double tx[3];
+ int32_t i,j,n,ix,hx;
+ int e0,nx;
+ uint32_t low;
+
+ GET_HIGH_WORD(hx,x); /* high word of x */
+ ix = hx&0x7fffffff;
+ if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */
+ {y[0] = x; y[1] = 0; return 0;}
+ if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */
+ if(hx>0) {
+ z = x - pio2_1;
+ if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
+ y[0] = z - pio2_1t;
+ y[1] = (z-y[0])-pio2_1t;
+ } else { /* near pi/2, use 33+33+53 bit pi */
+ z -= pio2_2;
+ y[0] = z - pio2_2t;
+ y[1] = (z-y[0])-pio2_2t;
+ }
+ return 1;
+ } else { /* negative x */
+ z = x + pio2_1;
+ if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
+ y[0] = z + pio2_1t;
+ y[1] = (z-y[0])+pio2_1t;
+ } else { /* near pi/2, use 33+33+53 bit pi */
+ z += pio2_2;
+ y[0] = z + pio2_2t;
+ y[1] = (z-y[0])+pio2_2t;
+ }
+ return -1;
+ }
+ }
+ if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
+ t = fabs(x);
+ n = (int32_t) (t*invpio2+half);
+ fn = (double)n;
+ r = t-fn*pio2_1;
+ w = fn*pio2_1t; /* 1st round good to 85 bit */
+ if(n<32&&ix!=npio2_hw[n-1]) {
+ y[0] = r-w; /* quick check no cancellation */
+ } else {
+ uint32_t high;
+ j = ix>>20;
+ y[0] = r-w;
+ GET_HIGH_WORD(high,y[0]);
+ i = j-((high>>20)&0x7ff);
+ if(i>16) { /* 2nd iteration needed, good to 118 */
+ t = r;
+ w = fn*pio2_2;
+ r = t-w;
+ w = fn*pio2_2t-((t-r)-w);
+ y[0] = r-w;
+ GET_HIGH_WORD(high,y[0]);
+ i = j-((high>>20)&0x7ff);
+ if(i>49) { /* 3rd iteration need, 151 bits acc */
+ t = r; /* will cover all possible cases */
+ w = fn*pio2_3;
+ r = t-w;
+ w = fn*pio2_3t-((t-r)-w);
+ y[0] = r-w;
+ }
+ }
+ }
+ y[1] = (r-y[0])-w;
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ else return n;
+ }
+ /*
+ * all other (large) arguments
+ */
+ if(ix>=0x7ff00000) { /* x is inf or NaN */
+ y[0]=y[1]=x-x; return 0;
+ }
+ /* set z = scalbn(|x|,ilogb(x)-23) */
+ GET_LOW_WORD(low,x);
+ SET_LOW_WORD(z,low);
+ e0 = (int)((ix>>20)-1046); /* e0 = ilogb(z)-23; */
+ SET_HIGH_WORD(z, ix - ((int32_t)e0<<20));
+ for(i=0;i<2;i++) {
+ tx[i] = (double)((int32_t)(z));
+ z = (z-tx[i])*two24;
+ }
+ tx[2] = z;
+ nx = 3;
+ while(tx[nx-1]==zero) nx--; /* skip zero term */
+ n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
+ if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+ return n;
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/e_remainder.c b/libjava/classpath/native/fdlibm/e_remainder.c
new file mode 100644
index 00000000000..4716d8d05fd
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_remainder.c
@@ -0,0 +1,80 @@
+
+/* @(#)e_remainder.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_remainder(x,p)
+ * Return :
+ * returns x REM p = x - [x/p]*p as if in infinite
+ * precise arithmetic, where [x/p] is the (infinite bit)
+ * integer nearest x/p (in half way case choose the even one).
+ * Method :
+ * Based on fmod() return x-[x/p]chopped*p exactlp.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+
+#ifdef __STDC__
+ double __ieee754_remainder(double x, double p)
+#else
+ double __ieee754_remainder(x,p)
+ double x,p;
+#endif
+{
+ int32_t hx,hp;
+ uint32_t sx,lx,lp;
+ double p_half;
+
+ EXTRACT_WORDS(hx,lx,x);
+ EXTRACT_WORDS(hp,lp,p);
+ sx = hx&0x80000000;
+ hp &= 0x7fffffff;
+ hx &= 0x7fffffff;
+
+ /* purge off exception values */
+ if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */
+ if((hx>=0x7ff00000)|| /* x not finite */
+ ((hp>=0x7ff00000)&& /* p is NaN */
+ (((hp-0x7ff00000)|lp)!=0)))
+ return (x*p)/(x*p);
+
+
+ if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */
+ if (((hx-hp)|(lx-lp))==0) return zero*x;
+ x = fabs(x);
+ p = fabs(p);
+ if (hp<0x00200000) {
+ if(x+x>p) {
+ x-=p;
+ if(x+x>=p) x -= p;
+ }
+ } else {
+ p_half = 0.5*p;
+ if(x>p_half) {
+ x-=p;
+ if(x>=p_half) x -= p;
+ }
+ }
+ GET_HIGH_WORD(hx,x);
+ SET_HIGH_WORD(x,hx^sx);
+ return x;
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/e_scalb.c b/libjava/classpath/native/fdlibm/e_scalb.c
new file mode 100644
index 00000000000..0bb924b43ee
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_scalb.c
@@ -0,0 +1,55 @@
+
+/* @(#)e_scalb.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __ieee754_scalb(x, fn) is provide for
+ * passing various standard test suite. One
+ * should use scalbn() instead.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef _SCALB_INT
+#ifdef __STDC__
+ double __ieee754_scalb(double x, int fn)
+#else
+ double __ieee754_scalb(x,fn)
+ double x; int fn;
+#endif
+#else
+#ifdef __STDC__
+ double __ieee754_scalb(double x, double fn)
+#else
+ double __ieee754_scalb(x,fn)
+ double x, fn;
+#endif
+#endif
+{
+#ifdef _SCALB_INT
+ return scalbn(x,fn);
+#else
+ if (isnan(x)||isnan(fn)) return x*fn;
+ if (!finite(fn)) {
+ if(fn>0.0) return x*fn;
+ else return x/(-fn);
+ }
+ if (rint(fn)!=fn) return (fn-fn)/(fn-fn);
+ if ( fn > 65000.0) return scalbn(x, 65000);
+ if (-fn > 65000.0) return scalbn(x,-65000);
+ return scalbn(x,(int)fn);
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/e_sqrt.c b/libjava/classpath/native/fdlibm/e_sqrt.c
new file mode 100644
index 00000000000..1d566a0847e
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/e_sqrt.c
@@ -0,0 +1,452 @@
+
+/* @(#)e_sqrt.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_sqrt(x)
+ * Return correctly rounded sqrt.
+ * ------------------------------------------
+ * | Use the hardware sqrt if you have one |
+ * ------------------------------------------
+ * Method:
+ * Bit by bit method using integer arithmetic. (Slow, but portable)
+ * 1. Normalization
+ * Scale x to y in [1,4) with even powers of 2:
+ * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
+ * sqrt(x) = 2^k * sqrt(y)
+ * 2. Bit by bit computation
+ * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
+ * i 0
+ * i+1 2
+ * s = 2*q , and y = 2 * ( y - q ). (1)
+ * i i i i
+ *
+ * To compute q from q , one checks whether
+ * i+1 i
+ *
+ * -(i+1) 2
+ * (q + 2 ) <= y. (2)
+ * i
+ * -(i+1)
+ * If (2) is false, then q = q ; otherwise q = q + 2 .
+ * i+1 i i+1 i
+ *
+ * With some algebric manipulation, it is not difficult to see
+ * that (2) is equivalent to
+ * -(i+1)
+ * s + 2 <= y (3)
+ * i i
+ *
+ * The advantage of (3) is that s and y can be computed by
+ * i i
+ * the following recurrence formula:
+ * if (3) is false
+ *
+ * s = s , y = y ; (4)
+ * i+1 i i+1 i
+ *
+ * otherwise,
+ * -i -(i+1)
+ * s = s + 2 , y = y - s - 2 (5)
+ * i+1 i i+1 i i
+ *
+ * One may easily use induction to prove (4) and (5).
+ * Note. Since the left hand side of (3) contain only i+2 bits,
+ * it does not necessary to do a full (53-bit) comparison
+ * in (3).
+ * 3. Final rounding
+ * After generating the 53 bits result, we compute one more bit.
+ * Together with the remainder, we can decide whether the
+ * result is exact, bigger than 1/2ulp, or less than 1/2ulp
+ * (it will never equal to 1/2ulp).
+ * The rounding mode can be detected by checking whether
+ * huge + tiny is equal to huge, and whether huge - tiny is
+ * equal to huge for some floating point number "huge" and "tiny".
+ *
+ * Special cases:
+ * sqrt(+-0) = +-0 ... exact
+ * sqrt(inf) = inf
+ * sqrt(-ve) = NaN ... with invalid signal
+ * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
+ *
+ * Other methods : see the appended file at the end of the program below.
+ *---------------
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double one = 1.0, tiny=1.0e-300;
+#else
+static double one = 1.0, tiny=1.0e-300;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_sqrt(double x)
+#else
+ double __ieee754_sqrt(x)
+ double x;
+#endif
+{
+ double z;
+ int32_t sign = (int)0x80000000;
+ uint32_t r,t1,s1,ix1,q1;
+ int32_t ix0,s0,q,m,t,i;
+
+ EXTRACT_WORDS(ix0,ix1,x);
+
+ /* take care of Inf and NaN */
+ if((ix0&0x7ff00000)==0x7ff00000) {
+ return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
+ sqrt(-inf)=sNaN */
+ }
+ /* take care of zero */
+ if(ix0<=0) {
+ if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
+ else if(ix0<0)
+ return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
+ }
+ /* normalize x */
+ m = (ix0>>20);
+ if(m==0) { /* subnormal x */
+ while(ix0==0) {
+ m -= 21;
+ ix0 |= (ix1>>11); ix1 <<= 21;
+ }
+ for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
+ m -= i-1;
+ ix0 |= (ix1>>(32-i));
+ ix1 <<= i;
+ }
+ m -= 1023; /* unbias exponent */
+ ix0 = (ix0&0x000fffff)|0x00100000;
+ if(m&1){ /* odd m, double x to make it even */
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ }
+ m >>= 1; /* m = [m/2] */
+
+ /* generate sqrt(x) bit by bit */
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
+ r = 0x00200000; /* r = moving bit from right to left */
+
+ while(r!=0) {
+ t = s0+r;
+ if(t<=ix0) {
+ s0 = t+r;
+ ix0 -= t;
+ q += r;
+ }
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ r>>=1;
+ }
+
+ r = sign;
+ while(r!=0) {
+ t1 = s1+r;
+ t = s0;
+ if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
+ s1 = t1+r;
+ if(((t1&sign)==(uint32_t)sign)&&(s1&sign)==0) s0 += 1;
+ ix0 -= t;
+ if (ix1 < t1) ix0 -= 1;
+ ix1 -= t1;
+ q1 += r;
+ }
+ ix0 += ix0 + ((ix1&sign)>>31);
+ ix1 += ix1;
+ r>>=1;
+ }
+
+ /* use floating add to find out rounding direction */
+ if((ix0|ix1)!=0) {
+ z = one-tiny; /* trigger inexact flag */
+ if (z>=one) {
+ z = one+tiny;
+ if (q1==(uint32_t)0xffffffff) { q1=0; q += 1;}
+ else if (z>one) {
+ if (q1==(uint32_t)0xfffffffe) q+=1;
+ q1+=2;
+ } else
+ q1 += (q1&1);
+ }
+ }
+ ix0 = (q>>1)+0x3fe00000;
+ ix1 = q1>>1;
+ if ((q&1)==1) ix1 |= sign;
+ ix0 += (m <<20);
+ INSERT_WORDS(z,ix0,ix1);
+ return z;
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
+
+/*
+Other methods (use floating-point arithmetic)
+-------------
+(This is a copy of a drafted paper by Prof W. Kahan
+and K.C. Ng, written in May, 1986)
+
+ Two algorithms are given here to implement sqrt(x)
+ (IEEE double precision arithmetic) in software.
+ Both supply sqrt(x) correctly rounded. The first algorithm (in
+ Section A) uses newton iterations and involves four divisions.
+ The second one uses reciproot iterations to avoid division, but
+ requires more multiplications. Both algorithms need the ability
+ to chop results of arithmetic operations instead of round them,
+ and the INEXACT flag to indicate when an arithmetic operation
+ is executed exactly with no roundoff error, all part of the
+ standard (IEEE 754-1985). The ability to perform shift, add,
+ subtract and logical AND operations upon 32-bit words is needed
+ too, though not part of the standard.
+
+A. sqrt(x) by Newton Iteration
+
+ (1) Initial approximation
+
+ Let x0 and x1 be the leading and the trailing 32-bit words of
+ a floating point number x (in IEEE double format) respectively
+
+ 1 11 52 ...widths
+ ------------------------------------------------------
+ x: |s| e | f |
+ ------------------------------------------------------
+ msb lsb msb lsb ...order
+
+
+ ------------------------ ------------------------
+ x0: |s| e | f1 | x1: | f2 |
+ ------------------------ ------------------------
+
+ By performing shifts and subtracts on x0 and x1 (both regarded
+ as integers), we obtain an 8-bit approximation of sqrt(x) as
+ follows.
+
+ k := (x0>>1) + 0x1ff80000;
+ y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
+ Here k is a 32-bit integer and T1[] is an integer array containing
+ correction terms. Now magically the floating value of y (y's
+ leading 32-bit word is y0, the value of its trailing word is 0)
+ approximates sqrt(x) to almost 8-bit.
+
+ Value of T1:
+ static int T1[32]= {
+ 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592,
+ 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215,
+ 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
+ 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,};
+
+ (2) Iterative refinement
+
+ Apply Heron's rule three times to y, we have y approximates
+ sqrt(x) to within 1 ulp (Unit in the Last Place):
+
+ y := (y+x/y)/2 ... almost 17 sig. bits
+ y := (y+x/y)/2 ... almost 35 sig. bits
+ y := y-(y-x/y)/2 ... within 1 ulp
+
+
+ Remark 1.
+ Another way to improve y to within 1 ulp is:
+
+ y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x)
+ y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x)
+
+ 2
+ (x-y )*y
+ y := y + 2* ---------- ...within 1 ulp
+ 2
+ 3y + x
+
+
+ This formula has one division fewer than the one above; however,
+ it requires more multiplications and additions. Also x must be
+ scaled in advance to avoid spurious overflow in evaluating the
+ expression 3y*y+x. Hence it is not recommended uless division
+ is slow. If division is very slow, then one should use the
+ reciproot algorithm given in section B.
+
+ (3) Final adjustment
+
+ By twiddling y's last bit it is possible to force y to be
+ correctly rounded according to the prevailing rounding mode
+ as follows. Let r and i be copies of the rounding mode and
+ inexact flag before entering the square root program. Also we
+ use the expression y+-ulp for the next representable floating
+ numbers (up and down) of y. Note that y+-ulp = either fixed
+ point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+ mode.
+
+ I := FALSE; ... reset INEXACT flag I
+ R := RZ; ... set rounding mode to round-toward-zero
+ z := x/y; ... chopped quotient, possibly inexact
+ If(not I) then { ... if the quotient is exact
+ if(z=y) {
+ I := i; ... restore inexact flag
+ R := r; ... restore rounded mode
+ return sqrt(x):=y.
+ } else {
+ z := z - ulp; ... special rounding
+ }
+ }
+ i := TRUE; ... sqrt(x) is inexact
+ If (r=RN) then z=z+ulp ... rounded-to-nearest
+ If (r=RP) then { ... round-toward-+inf
+ y = y+ulp; z=z+ulp;
+ }
+ y := y+z; ... chopped sum
+ y0:=y0-0x00100000; ... y := y/2 is correctly rounded.
+ I := i; ... restore inexact flag
+ R := r; ... restore rounded mode
+ return sqrt(x):=y.
+
+ (4) Special cases
+
+ Square root of +inf, +-0, or NaN is itself;
+ Square root of a negative number is NaN with invalid signal.
+
+
+B. sqrt(x) by Reciproot Iteration
+
+ (1) Initial approximation
+
+ Let x0 and x1 be the leading and the trailing 32-bit words of
+ a floating point number x (in IEEE double format) respectively
+ (see section A). By performing shifs and subtracts on x0 and y0,
+ we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
+
+ k := 0x5fe80000 - (x0>>1);
+ y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits
+
+ Here k is a 32-bit integer and T2[] is an integer array
+ containing correction terms. Now magically the floating
+ value of y (y's leading 32-bit word is y0, the value of
+ its trailing word y1 is set to zero) approximates 1/sqrt(x)
+ to almost 7.8-bit.
+
+ Value of T2:
+ static int T2[64]= {
+ 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
+ 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
+ 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
+ 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
+ 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
+ 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
+ 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
+ 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
+
+ (2) Iterative refinement
+
+ Apply Reciproot iteration three times to y and multiply the
+ result by x to get an approximation z that matches sqrt(x)
+ to about 1 ulp. To be exact, we will have
+ -1ulp < sqrt(x)-z<1.0625ulp.
+
+ ... set rounding mode to Round-to-nearest
+ y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x)
+ y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
+ ... special arrangement for better accuracy
+ z := x*y ... 29 bits to sqrt(x), with z*y<1
+ z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x)
+
+ Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
+ (a) the term z*y in the final iteration is always less than 1;
+ (b) the error in the final result is biased upward so that
+ -1 ulp < sqrt(x) - z < 1.0625 ulp
+ instead of |sqrt(x)-z|<1.03125ulp.
+
+ (3) Final adjustment
+
+ By twiddling y's last bit it is possible to force y to be
+ correctly rounded according to the prevailing rounding mode
+ as follows. Let r and i be copies of the rounding mode and
+ inexact flag before entering the square root program. Also we
+ use the expression y+-ulp for the next representable floating
+ numbers (up and down) of y. Note that y+-ulp = either fixed
+ point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+ mode.
+
+ R := RZ; ... set rounding mode to round-toward-zero
+ switch(r) {
+ case RN: ... round-to-nearest
+ if(x<= z*(z-ulp)...chopped) z = z - ulp; else
+ if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
+ break;
+ case RZ:case RM: ... round-to-zero or round-to--inf
+ R:=RP; ... reset rounding mod to round-to-+inf
+ if(x<z*z ... rounded up) z = z - ulp; else
+ if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
+ break;
+ case RP: ... round-to-+inf
+ if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
+ if(x>z*z ...chopped) z = z+ulp;
+ break;
+ }
+
+ Remark 3. The above comparisons can be done in fixed point. For
+ example, to compare x and w=z*z chopped, it suffices to compare
+ x1 and w1 (the trailing parts of x and w), regarding them as
+ two's complement integers.
+
+ ...Is z an exact square root?
+ To determine whether z is an exact square root of x, let z1 be the
+ trailing part of z, and also let x0 and x1 be the leading and
+ trailing parts of x.
+
+ If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
+ I := 1; ... Raise Inexact flag: z is not exact
+ else {
+ j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2
+ k := z1 >> 26; ... get z's 25-th and 26-th
+ fraction bits
+ I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
+ }
+ R:= r ... restore rounded mode
+ return sqrt(x):=z.
+
+ If multiplication is cheaper then the foregoing red tape, the
+ Inexact flag can be evaluated by
+
+ I := i;
+ I := (z*z!=x) or I.
+
+ Note that z*z can overwrite I; this value must be sensed if it is
+ True.
+
+ Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
+ zero.
+
+ --------------------
+ z1: | f2 |
+ --------------------
+ bit 31 bit 0
+
+ Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
+ or even of logb(x) have the following relations:
+
+ -------------------------------------------------
+ bit 27,26 of z1 bit 1,0 of x1 logb(x)
+ -------------------------------------------------
+ 00 00 odd and even
+ 01 01 even
+ 10 10 odd
+ 10 00 even
+ 11 01 even
+ -------------------------------------------------
+
+ (4) Special cases (see (4) of Section A).
+
+ */
diff --git a/libjava/classpath/native/fdlibm/fdlibm.h b/libjava/classpath/native/fdlibm/fdlibm.h
new file mode 100644
index 00000000000..156a03c1e45
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/fdlibm.h
@@ -0,0 +1,354 @@
+
+/* @(#)fdlibm.h 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993, 2000 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef __CLASSPATH_FDLIBM_H__
+#define __CLASSPATH_FDLIBM_H__
+
+/* AIX needs _XOPEN_SOURCE */
+#ifdef _AIX
+#define _XOPEN_SOURCE
+#endif
+
+#include <config.h>
+#include <stdlib.h>
+
+/* GCJ LOCAL: Include files. */
+#include "ieeefp.h"
+
+#include "mprec.h"
+
+/* CYGNUS LOCAL: Default to XOPEN_MODE. */
+#define _XOPEN_MODE
+
+#ifdef __P
+#undef __P
+#endif
+
+#ifdef __STDC__
+#define __P(p) p
+#else
+#define __P(p) ()
+#endif
+
+#ifndef HUGE
+#define HUGE ((float)3.40282346638528860e+38)
+#endif
+
+/*
+ * set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
+ * (one may replace the following line by "#include <values.h>")
+ */
+
+#define X_TLOSS 1.41484755040568800000e+16
+
+/* These typedefs are true for the targets running Java. */
+
+#define _IEEE_LIBM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * ANSI/POSIX
+ */
+extern double acos __P((double));
+extern double asin __P((double));
+extern double atan __P((double));
+extern double atan2 __P((double, double));
+extern double cos __P((double));
+extern double sin __P((double));
+extern double tan __P((double));
+
+extern double cosh __P((double));
+extern double sinh __P((double));
+extern double tanh __P((double));
+
+extern double exp __P((double));
+extern double frexp __P((double, int *));
+extern double ldexp __P((double, int));
+extern double log __P((double));
+extern double log10 __P((double));
+extern double modf __P((double, double *));
+
+extern double pow __P((double, double));
+extern double sqrt __P((double));
+
+extern double ceil __P((double));
+extern double fabs __P((double));
+extern double floor __P((double));
+extern double fmod __P((double, double));
+
+extern double erf __P((double));
+extern double erfc __P((double));
+extern double gamma __P((double));
+extern double hypot __P((double, double));
+extern int isnan __P((double));
+extern int finite __P((double));
+extern double j0 __P((double));
+extern double j1 __P((double));
+extern double jn __P((int, double));
+extern double lgamma __P((double));
+extern double y0 __P((double));
+extern double y1 __P((double));
+extern double yn __P((int, double));
+
+extern double acosh __P((double));
+extern double asinh __P((double));
+extern double atanh __P((double));
+extern double cbrt __P((double));
+extern double logb __P((double));
+extern double nextafter __P((double, double));
+extern double remainder __P((double, double));
+
+/* Functions that are not documented, and are not in <math.h>. */
+
+extern double logb __P((double));
+#ifdef _SCALB_INT
+extern double scalb __P((double, int));
+#else
+extern double scalb __P((double, double));
+#endif
+extern double significand __P((double));
+
+/* ieee style elementary functions */
+extern double __ieee754_sqrt __P((double));
+extern double __ieee754_acos __P((double));
+extern double __ieee754_acosh __P((double));
+extern double __ieee754_log __P((double));
+extern double __ieee754_atanh __P((double));
+extern double __ieee754_asin __P((double));
+extern double __ieee754_atan2 __P((double,double));
+extern double __ieee754_exp __P((double));
+extern double __ieee754_cosh __P((double));
+extern double __ieee754_fmod __P((double,double));
+extern double __ieee754_pow __P((double,double));
+extern double __ieee754_lgamma_r __P((double,int *));
+extern double __ieee754_gamma_r __P((double,int *));
+extern double __ieee754_log10 __P((double));
+extern double __ieee754_sinh __P((double));
+extern double __ieee754_hypot __P((double,double));
+extern double __ieee754_j0 __P((double));
+extern double __ieee754_j1 __P((double));
+extern double __ieee754_y0 __P((double));
+extern double __ieee754_y1 __P((double));
+extern double __ieee754_jn __P((int,double));
+extern double __ieee754_yn __P((int,double));
+extern double __ieee754_remainder __P((double,double));
+extern int32_t __ieee754_rem_pio2 __P((double,double*));
+#ifdef _SCALB_INT
+extern double __ieee754_scalb __P((double,int));
+#else
+extern double __ieee754_scalb __P((double,double));
+#endif
+
+/* fdlibm kernel function */
+extern double __kernel_standard __P((double,double,int));
+extern double __kernel_sin __P((double,double,int));
+extern double __kernel_cos __P((double,double));
+extern double __kernel_tan __P((double,double,int));
+extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const int32_t*));
+
+/* Undocumented float functions. */
+extern float logbf __P((float));
+#ifdef _SCALB_INT
+extern float scalbf __P((float, int));
+#else
+extern float scalbf __P((float, float));
+#endif
+extern float significandf __P((float));
+
+/*
+ * Functions callable from C, intended to support IEEE arithmetic.
+ */
+extern double copysign __P((double, double));
+extern int ilogb __P((double));
+extern double rint __P((double));
+extern float rintf __P((float));
+extern double scalbn __P((double, int));
+
+/* ieee style elementary float functions */
+extern float __ieee754_sqrtf __P((float));
+extern float __ieee754_acosf __P((float));
+extern float __ieee754_acoshf __P((float));
+extern float __ieee754_logf __P((float));
+extern float __ieee754_atanhf __P((float));
+extern float __ieee754_asinf __P((float));
+extern float __ieee754_atan2f __P((float,float));
+extern float __ieee754_expf __P((float));
+extern float __ieee754_coshf __P((float));
+extern float __ieee754_fmodf __P((float,float));
+extern float __ieee754_powf __P((float,float));
+extern float __ieee754_lgammaf_r __P((float,int *));
+extern float __ieee754_gammaf_r __P((float,int *));
+extern float __ieee754_log10f __P((float));
+extern float __ieee754_sinhf __P((float));
+extern float __ieee754_hypotf __P((float,float));
+extern float __ieee754_j0f __P((float));
+extern float __ieee754_j1f __P((float));
+extern float __ieee754_y0f __P((float));
+extern float __ieee754_y1f __P((float));
+extern float __ieee754_jnf __P((int,float));
+extern float __ieee754_ynf __P((int,float));
+extern float __ieee754_remainderf __P((float,float));
+extern int32_t __ieee754_rem_pio2f __P((float,float*));
+#ifdef _SCALB_INT
+extern float __ieee754_scalbf __P((float,int));
+#else
+extern float __ieee754_scalbf __P((float,float));
+#endif
+
+/* float versions of fdlibm kernel functions */
+extern float __kernel_sinf __P((float,float,int));
+extern float __kernel_cosf __P((float,float));
+extern float __kernel_tanf __P((float,float,int));
+extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const int32_t*));
+
+/* The original code used statements like
+ n0 = ((*(int*)&one)>>29)^1; * index of high word *
+ ix0 = *(n0+(int*)&x); * high word of x *
+ ix1 = *((1-n0)+(int*)&x); * low word of x *
+ to dig two 32 bit words out of the 64 bit IEEE floating point
+ value. That is non-ANSI, and, moreover, the gcc instruction
+ scheduler gets it wrong. We instead use the following macros.
+ Unlike the original code, we determine the endianness at compile
+ time, not at run time; I don't see much benefit to selecting
+ endianness at run time. */
+
+#ifndef __IEEE_BIG_ENDIAN
+#ifndef __IEEE_LITTLE_ENDIAN
+ #error Must define endianness
+#endif
+#endif
+
+/* A union which permits us to convert between a double and two 32 bit
+ ints. */
+
+#ifdef __IEEE_BIG_ENDIAN
+
+typedef union
+{
+ double value;
+ struct
+ {
+ uint32_t msw;
+ uint32_t lsw;
+ } parts;
+} ieee_double_shape_type;
+
+#endif
+
+#ifdef __IEEE_LITTLE_ENDIAN
+
+typedef union
+{
+ double value;
+ struct
+ {
+ uint32_t lsw;
+ uint32_t msw;
+ } parts;
+} ieee_double_shape_type;
+
+#endif
+
+/* Get two 32 bit ints from a double. */
+
+#define EXTRACT_WORDS(ix0,ix1,d) \
+do { \
+ ieee_double_shape_type ew_u; \
+ ew_u.value = (d); \
+ (ix0) = ew_u.parts.msw; \
+ (ix1) = ew_u.parts.lsw; \
+} while (0)
+
+/* Get the more significant 32 bit int from a double. */
+
+#define GET_HIGH_WORD(i,d) \
+do { \
+ ieee_double_shape_type gh_u; \
+ gh_u.value = (d); \
+ (i) = gh_u.parts.msw; \
+} while (0)
+
+/* Get the less significant 32 bit int from a double. */
+
+#define GET_LOW_WORD(i,d) \
+do { \
+ ieee_double_shape_type gl_u; \
+ gl_u.value = (d); \
+ (i) = gl_u.parts.lsw; \
+} while (0)
+
+/* Set a double from two 32 bit ints. */
+
+#define INSERT_WORDS(d,ix0,ix1) \
+do { \
+ ieee_double_shape_type iw_u; \
+ iw_u.parts.msw = (ix0); \
+ iw_u.parts.lsw = (ix1); \
+ (d) = iw_u.value; \
+} while (0)
+
+/* Set the more significant 32 bits of a double from an int. */
+
+#define SET_HIGH_WORD(d,v) \
+do { \
+ ieee_double_shape_type sh_u; \
+ sh_u.value = (d); \
+ sh_u.parts.msw = (v); \
+ (d) = sh_u.value; \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int. */
+
+#define SET_LOW_WORD(d,v) \
+do { \
+ ieee_double_shape_type sl_u; \
+ sl_u.value = (d); \
+ sl_u.parts.lsw = (v); \
+ (d) = sl_u.value; \
+} while (0)
+
+/* A union which permits us to convert between a float and a 32 bit
+ int. */
+
+typedef union
+{
+ float value;
+ uint32_t word;
+} ieee_float_shape_type;
+
+/* Get a 32 bit int from a float. */
+
+#define GET_FLOAT_WORD(i,d) \
+do { \
+ ieee_float_shape_type gf_u; \
+ gf_u.value = (d); \
+ (i) = gf_u.word; \
+} while (0)
+
+/* Set a float from a 32 bit int. */
+
+#define SET_FLOAT_WORD(d,i) \
+do { \
+ ieee_float_shape_type sf_u; \
+ sf_u.word = (i); \
+ (d) = sf_u.value; \
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CLASSPATH_FDLIBM_H__ */
diff --git a/libjava/classpath/native/fdlibm/ieeefp.h b/libjava/classpath/native/fdlibm/ieeefp.h
new file mode 100644
index 00000000000..405baab5840
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/ieeefp.h
@@ -0,0 +1,167 @@
+#ifndef __CLASSPATH_IEEEFP_H__
+#define __CLASSPATH_IEEEFP_H__
+
+#ifndef __IEEE_BIG_ENDIAN
+#ifndef __IEEE_LITTLE_ENDIAN
+
+#ifdef __alpha__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#if defined(__arm__) || defined(__thumb__)
+/* ARM traditionally used big-endian words; and within those words the
+ byte ordering was big or little endian depending upon the target.
+ Modern floating-point formats are naturally ordered; in this case
+ __VFP_FP__ will be defined, even if soft-float. */
+#ifdef __VFP_FP__
+#ifdef __ARMEL__
+#define __IEEE_LITTLE_ENDIAN
+#else
+#define __IEEE_BIG_ENDIAN
+#endif
+#else
+#define __IEEE_BIG_ENDIAN
+#ifdef __ARMEL__
+#define __IEEE_BYTES_LITTLE_ENDIAN
+#endif
+#endif
+#endif
+
+#ifdef __hppa__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#if defined (__sparc) || defined (__sparc__)
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __m32r__
+#ifdef __LITTLE_ENDIAN__
+#define __IEEE_LITTLE_ENDIAN
+#else
+#define __IEEE_BIG_ENDIAN
+#endif
+#endif
+
+#if defined(__m68k__) || defined(__mc68000__)
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#if defined (__H8300__) || defined (__H8300H__)
+#define __IEEE_BIG_ENDIAN
+#define __SMALL_BITFIELDS
+#define _DOUBLE_IS_32BITS
+#endif
+
+#ifdef __H8500__
+#define __IEEE_BIG_ENDIAN
+#define __SMALL_BITFIELDS
+#define _DOUBLE_IS_32BITS
+#endif
+
+#ifdef __sh__
+#ifdef __LITTLE_ENDIAN__
+#define __IEEE_LITTLE_ENDIAN
+#else
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __SH3E__
+#define _DOUBLE_IS_32BITS
+#endif
+#endif
+
+#ifdef _AM29K
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __i386__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __x86_64__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __i960__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __MIPSEL__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __MIPSEB__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __pj__
+#ifdef __pjl__
+#define __IEEE_LITTLE_ENDIAN
+#else
+#define __IEEE_BIG_ENDIAN
+#endif
+#endif
+
+/* necv70 was __IEEE_LITTLE_ENDIAN. */
+
+#ifdef __W65__
+#define __IEEE_LITTLE_ENDIAN
+#define __SMALL_BITFIELDS
+#define _DOUBLE_IS_32BITS
+#endif
+
+#if defined(__Z8001__) || defined(__Z8002__)
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __m88k__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __v800
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#if defined (__PPC__) || defined (__ppc__) || defined (__ppc64__)
+#if (defined(_BIG_ENDIAN) && _BIG_ENDIAN) || (defined(_AIX) && _AIX) \
+ || defined (__APPLE__)
+#define __IEEE_BIG_ENDIAN
+#else
+#if (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN) || (defined(__sun__) && __sun__) || (defined(__WIN32__) && __WIN32__)
+#define __IEEE_LITTLE_ENDIAN
+#endif
+#endif
+#endif
+
+#ifdef __fr30__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __mcore__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+
+#ifdef __ia64__
+#ifdef __BIG_ENDIAN__
+#define __IEEE_BIG_ENDIAN
+#else
+#define __IEEE_LITTLE_ENDIAN
+#endif
+#endif
+
+#ifdef __s390__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifndef __IEEE_BIG_ENDIAN
+#ifndef __IEEE_LITTLE_ENDIAN
+#error Endianess not declared!!
+#endif /* not __IEEE_LITTLE_ENDIAN */
+#endif /* not __IEEE_BIG_ENDIAN */
+
+#endif /* not __IEEE_LITTLE_ENDIAN */
+#endif /* not __IEEE_BIG_ENDIAN */
+
+#endif /* __CLASSPATH_IEEEFP_H__ */
diff --git a/libjava/classpath/native/fdlibm/java-assert.h b/libjava/classpath/native/fdlibm/java-assert.h
new file mode 100644
index 00000000000..6f178bd9e98
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/java-assert.h
@@ -0,0 +1,38 @@
+// java-assert.h - Header file holding assertion definitions. -*- c++ -*-
+
+/* Copyright (C) 1998, 1999 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#ifndef __JAVA_ASSERT_H__
+#define __JAVA_ASSERT_H__
+
+// This is a libgcj implementation header.
+
+void _Jv_Abort (const char *, const char *, int, const char *)
+ __attribute__ ((__noreturn__));
+
+#ifdef DEBUG
+#define _Jv_AssertDoCall(Message) _Jv_Abort (__FUNCTION__, __FILE__, __LINE__, Message)
+
+#define JvAssertMessage(Expr, Message) \
+ do { if (! (Expr)) _Jv_AssertDoCall (Message); } while (0)
+#define JvAssert(Expr) \
+ do { if (! (Expr)) _Jv_AssertDoCall (# Expr); } while (0)
+
+#define JvFail(Message) _Jv_AssertDoCall (Message)
+
+#else /* DEBUG */
+
+#define _Jv_AssertDoCall(Message)
+#define JvAssertMessage(Expr, Message)
+#define JvAssert(Expr)
+#define JvFail(Message) _Jv_Abort (0, 0, 0, Message)
+
+#endif /* not DEBUG */
+
+#endif /* __JAVA_ASSERT_H__ */
diff --git a/libjava/classpath/native/fdlibm/k_cos.c b/libjava/classpath/native/fdlibm/k_cos.c
new file mode 100644
index 00000000000..acf50a82e83
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/k_cos.c
@@ -0,0 +1,96 @@
+
+/* @(#)k_cos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __kernel_cos( x, y )
+ * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ *
+ * Algorithm
+ * 1. Since cos(-x) = cos(x), we need only to consider positive x.
+ * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
+ * 3. cos(x) is approximated by a polynomial of degree 14 on
+ * [0,pi/4]
+ * 4 14
+ * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
+ * where the remez error is
+ *
+ * | 2 4 6 8 10 12 14 | -58
+ * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
+ * | |
+ *
+ * 4 6 8 10 12 14
+ * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
+ * cos(x) = 1 - x*x/2 + r
+ * since cos(x+y) ~ cos(x) - sin(x)*y
+ * ~ cos(x) - x*y,
+ * a correction term is necessary in cos(x) and hence
+ * cos(x+y) = 1 - (x*x/2 - (r - x*y))
+ * For better accuracy when x > 0.3, let qx = |x|/4 with
+ * the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
+ * Then
+ * cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
+ * Note that 1-qx and (x*x/2-qx) is EXACT here, and the
+ * magnitude of the latter is at least a quarter of x*x/2,
+ * thus, reducing the rounding error in the subtraction.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
+C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
+C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
+C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
+C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
+C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
+
+#ifdef __STDC__
+ double __kernel_cos(double x, double y)
+#else
+ double __kernel_cos(x, y)
+ double x,y;
+#endif
+{
+ double a,hz,z,r,qx;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff; /* ix = |x|'s high word*/
+ if(ix<0x3e400000) { /* if x < 2**27 */
+ if(((int)x)==0) return one; /* generate inexact */
+ }
+ z = x*x;
+ r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
+ if(ix < 0x3FD33333) /* if |x| < 0.3 */
+ return one - (0.5*z - (z*r - x*y));
+ else {
+ if(ix > 0x3fe90000) { /* x > 0.78125 */
+ qx = 0.28125;
+ } else {
+ INSERT_WORDS(qx,ix-0x00200000,0); /* x/4 */
+ }
+ hz = 0.5*z-qx;
+ a = one-qx;
+ return a - (hz - (z*r-x*y));
+ }
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/k_rem_pio2.c b/libjava/classpath/native/fdlibm/k_rem_pio2.c
new file mode 100644
index 00000000000..2f4ca17256c
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/k_rem_pio2.c
@@ -0,0 +1,320 @@
+
+/* @(#)k_rem_pio2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
+ * double x[],y[]; int e0,nx,prec; int ipio2[];
+ *
+ * __kernel_rem_pio2 return the last three digits of N with
+ * y = x - N*pi/2
+ * so that |y| < pi/2.
+ *
+ * The method is to compute the integer (mod 8) and fraction parts of
+ * (2/pi)*x without doing the full multiplication. In general we
+ * skip the part of the product that are known to be a huge integer (
+ * more accurately, = 0 mod 8 ). Thus the number of operations are
+ * independent of the exponent of the input.
+ *
+ * (2/pi) is represented by an array of 24-bit integers in ipio2[].
+ *
+ * Input parameters:
+ * x[] The input value (must be positive) is broken into nx
+ * pieces of 24-bit integers in double precision format.
+ * x[i] will be the i-th 24 bit of x. The scaled exponent
+ * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
+ * match x's up to 24 bits.
+ *
+ * Example of breaking a double positive z into x[0]+x[1]+x[2]:
+ * e0 = ilogb(z)-23
+ * z = scalbn(z,-e0)
+ * for i = 0,1,2
+ * x[i] = floor(z)
+ * z = (z-x[i])*2**24
+ *
+ *
+ * y[] ouput result in an array of double precision numbers.
+ * The dimension of y[] is:
+ * 24-bit precision 1
+ * 53-bit precision 2
+ * 64-bit precision 2
+ * 113-bit precision 3
+ * The actual value is the sum of them. Thus for 113-bit
+ * precison, one may have to do something like:
+ *
+ * long double t,w,r_head, r_tail;
+ * t = (long double)y[2] + (long double)y[1];
+ * w = (long double)y[0];
+ * r_head = t+w;
+ * r_tail = w - (r_head - t);
+ *
+ * e0 The exponent of x[0]
+ *
+ * nx dimension of x[]
+ *
+ * prec an integer indicating the precision:
+ * 0 24 bits (single)
+ * 1 53 bits (double)
+ * 2 64 bits (extended)
+ * 3 113 bits (quad)
+ *
+ * ipio2[]
+ * integer array, contains the (24*i)-th to (24*i+23)-th
+ * bit of 2/pi after binary point. The corresponding
+ * floating value is
+ *
+ * ipio2[i] * 2^(-24(i+1)).
+ *
+ * External function:
+ * double scalbn(), floor();
+ *
+ *
+ * Here is the description of some local variables:
+ *
+ * jk jk+1 is the initial number of terms of ipio2[] needed
+ * in the computation. The recommended value is 2,3,4,
+ * 6 for single, double, extended,and quad.
+ *
+ * jz local integer variable indicating the number of
+ * terms of ipio2[] used.
+ *
+ * jx nx - 1
+ *
+ * jv index for pointing to the suitable ipio2[] for the
+ * computation. In general, we want
+ * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
+ * is an integer. Thus
+ * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
+ * Hence jv = max(0,(e0-3)/24).
+ *
+ * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
+ *
+ * q[] double array with integral value, representing the
+ * 24-bits chunk of the product of x and 2/pi.
+ *
+ * q0 the corresponding exponent of q[0]. Note that the
+ * exponent for q[i] would be q0-24*i.
+ *
+ * PIo2[] double precision array, obtained by cutting pi/2
+ * into 24 bits chunks.
+ *
+ * f[] ipio2[] in floating point
+ *
+ * iq[] integer array by breaking up q[] in 24-bits chunk.
+ *
+ * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
+ *
+ * ih integer. If >0 it indicates q[] is >= 0.5, hence
+ * it also indicates the *sign* of the result.
+ *
+ */
+
+
+/*
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
+#else
+static int init_jk[] = {2,3,4,6};
+#endif
+
+#ifdef __STDC__
+static const double PIo2[] = {
+#else
+static double PIo2[] = {
+#endif
+ 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
+ 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
+ 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
+ 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
+ 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
+ 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
+ 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
+ 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
+};
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+zero = 0.0,
+one = 1.0,
+two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
+
+#ifdef __STDC__
+ int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2)
+#else
+ int __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
+ double x[], y[]; int e0,nx,prec; int32_t ipio2[];
+#endif
+{
+ int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+ double z,fw,f[20],fq[20],q[20];
+
+ /* initialize jk*/
+ jk = init_jk[prec];
+ jp = jk;
+
+ /* determine jx,jv,q0, note that 3>q0 */
+ jx = nx-1;
+ jv = (e0-3)/24; if(jv<0) jv=0;
+ q0 = e0-24*(jv+1);
+
+ /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
+ j = jv-jx; m = jx+jk;
+ for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
+
+ /* compute q[0],q[1],...q[jk] */
+ for (i=0;i<=jk;i++) {
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+ }
+
+ jz = jk;
+recompute:
+ /* distill q[] into iq[] reversingly */
+ for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
+ fw = (double)((int32_t)(twon24* z));
+ iq[i] = (int32_t)(z-two24*fw);
+ z = q[j-1]+fw;
+ }
+
+ /* compute n */
+ z = scalbn(z,(int)q0); /* actual value of z */
+ z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
+ n = (int32_t) z;
+ z -= (double)n;
+ ih = 0;
+ if(q0>0) { /* need iq[jz-1] to determine n */
+ i = (iq[jz-1]>>(24-q0)); n += i;
+ iq[jz-1] -= i<<(24-q0);
+ ih = iq[jz-1]>>(23-q0);
+ }
+ else if(q0==0) ih = iq[jz-1]>>23;
+ else if(z>=0.5) ih=2;
+
+ if(ih>0) { /* q > 0.5 */
+ n += 1; carry = 0;
+ for(i=0;i<jz ;i++) { /* compute 1-q */
+ j = iq[i];
+ if(carry==0) {
+ if(j!=0) {
+ carry = 1; iq[i] = 0x1000000- j;
+ }
+ } else iq[i] = 0xffffff - j;
+ }
+ if(q0>0) { /* rare case: chance is 1 in 12 */
+ switch(q0) {
+ case 1:
+ iq[jz-1] &= 0x7fffff; break;
+ case 2:
+ iq[jz-1] &= 0x3fffff; break;
+ }
+ }
+ if(ih==2) {
+ z = one - z;
+ if(carry!=0) z -= scalbn(one,(int)q0);
+ }
+ }
+
+ /* check if recomputation is needed */
+ if(z==zero) {
+ j = 0;
+ for (i=jz-1;i>=jk;i--) j |= iq[i];
+ if(j==0) { /* need recomputation */
+ for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */
+
+ for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */
+ f[jx+i] = (double) ipio2[jv+i];
+ for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
+ q[i] = fw;
+ }
+ jz += k;
+ goto recompute;
+ }
+ }
+
+ /* chop off zero terms */
+ if(z==0.0) {
+ jz -= 1; q0 -= 24;
+ while(iq[jz]==0) { jz--; q0-=24;}
+ } else { /* break z into 24-bit if necessary */
+ z = scalbn(z,-(int)q0);
+ if(z>=two24) {
+ fw = (double)((int32_t)(twon24*z));
+ iq[jz] = (int32_t)(z-two24*fw);
+ jz += 1; q0 += 24;
+ iq[jz] = (int32_t) fw;
+ } else iq[jz] = (int32_t) z ;
+ }
+
+ /* convert integer "bit" chunk to floating-point value */
+ fw = scalbn(one,(int)q0);
+ for(i=jz;i>=0;i--) {
+ q[i] = fw*(double)iq[i]; fw*=twon24;
+ }
+
+ /* compute PIo2[0,...,jp]*q[jz,...,0] */
+ for(i=jz;i>=0;i--) {
+ for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
+ fq[jz-i] = fw;
+ }
+
+ /* compress fq[] into y[] */
+ switch(prec) {
+ case 0:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ break;
+ case 1:
+ case 2:
+ fw = 0.0;
+ for (i=jz;i>=0;i--) fw += fq[i];
+ y[0] = (ih==0)? fw: -fw;
+ fw = fq[0]-fw;
+ for (i=1;i<=jz;i++) fw += fq[i];
+ y[1] = (ih==0)? fw: -fw;
+ break;
+ case 3: /* painful */
+ for (i=jz;i>0;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (i=jz;i>1;i--) {
+ fw = fq[i-1]+fq[i];
+ fq[i] += fq[i-1]-fw;
+ fq[i-1] = fw;
+ }
+ for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
+ if(ih==0) {
+ y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
+ } else {
+ y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
+ }
+ }
+ return n&7;
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/k_sin.c b/libjava/classpath/native/fdlibm/k_sin.c
new file mode 100644
index 00000000000..b4ad387c589
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/k_sin.c
@@ -0,0 +1,79 @@
+
+/* @(#)k_sin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __kernel_sin( x, y, iy)
+ * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
+ *
+ * Algorithm
+ * 1. Since sin(-x) = -sin(x), we need only to consider positive x.
+ * 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0.
+ * 3. sin(x) is approximated by a polynomial of degree 13 on
+ * [0,pi/4]
+ * 3 13
+ * sin(x) ~ x + S1*x + ... + S6*x
+ * where
+ *
+ * |sin(x) 2 4 6 8 10 12 | -58
+ * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
+ * | x |
+ *
+ * 4. sin(x+y) = sin(x) + sin'(x')*y
+ * ~ sin(x) + (1-x*x/2)*y
+ * For better accuracy, let
+ * 3 2 2 2 2
+ * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
+ * then 3 2
+ * sin(x) = x + (S1*x + (x *(r-y/2)+y))
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
+S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
+S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
+S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
+S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
+S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
+
+#ifdef __STDC__
+ double __kernel_sin(double x, double y, int iy)
+#else
+ double __kernel_sin(x, y, iy)
+ double x,y; int iy; /* iy=0 if y is zero */
+#endif
+{
+ double z,r,v;
+ int32_t ix;
+ GET_HIGH_WORD(ix,x);
+ ix &= 0x7fffffff; /* high word of x */
+ if(ix<0x3e400000) /* |x| < 2**-27 */
+ {if((int)x==0) return x;} /* generate inexact */
+ z = x*x;
+ v = z*x;
+ r = S2+z*(S3+z*(S4+z*(S5+z*S6)));
+ if(iy==0) return x+v*(S1+z*r);
+ else return x-((z*(half*y-v*r)-y)-v*S1);
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/k_tan.c b/libjava/classpath/native/fdlibm/k_tan.c
new file mode 100644
index 00000000000..a1067a70a0d
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/k_tan.c
@@ -0,0 +1,132 @@
+
+/* @(#)k_tan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* __kernel_tan( x, y, k )
+ * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input k indicates whether tan (if k=1) or
+ * -1/tan (if k= -1) is returned.
+ *
+ * Algorithm
+ * 1. Since tan(-x) = -tan(x), we need only to consider positive x.
+ * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
+ * 3. tan(x) is approximated by a odd polynomial of degree 27 on
+ * [0,0.67434]
+ * 3 27
+ * tan(x) ~ x + T1*x + ... + T13*x
+ * where
+ *
+ * |tan(x) 2 4 26 | -59.2
+ * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
+ * | x |
+ *
+ * Note: tan(x+y) = tan(x) + tan'(x)*y
+ * ~ tan(x) + (1+x*x)*y
+ * Therefore, for better accuracy in computing tan(x+y), let
+ * 3 2 2 2 2
+ * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
+ * then
+ * 3 2
+ * tan(x+y) = x + (T1*x + (x *(r+y)+y))
+ *
+ * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
+ * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
+ * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
+pio4lo= 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */
+T[] = {
+ 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */
+ 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */
+ 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */
+ 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */
+ 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */
+ 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */
+ 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */
+ 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */
+ 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */
+ 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */
+ 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */
+ -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */
+ 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */
+};
+
+#ifdef __STDC__
+ double __kernel_tan(double x, double y, int iy)
+#else
+ double __kernel_tan(x, y, iy)
+ double x,y; int iy;
+#endif
+{
+ double z,r,v,w,s;
+ int32_t ix,hx;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff; /* high word of |x| */
+ if(ix<0x3e300000) /* x < 2**-28 */
+ {if((int)x==0) { /* generate inexact */
+ uint32_t low;
+ GET_LOW_WORD(low,x);
+ if(((ix|low)|(iy+1))==0) return one/fabs(x);
+ else return (iy==1)? x: -one/x;
+ }
+ }
+ if(ix>=0x3FE59428) { /* |x|>=0.6744 */
+ if(hx<0) {x = -x; y = -y;}
+ z = pio4-x;
+ w = pio4lo-y;
+ x = z+w; y = 0.0;
+ }
+ z = x*x;
+ w = z*z;
+ /* Break x^5*(T[1]+x^2*T[2]+...) into
+ * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
+ * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
+ */
+ r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
+ v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
+ s = z*x;
+ r = y + z*(s*(r+v)+y);
+ r += T[0]*s;
+ w = x+r;
+ if(ix>=0x3FE59428) {
+ v = (double)iy;
+ return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r)));
+ }
+ if(iy==1) return w;
+ else { /* if allow error up to 2 ulp,
+ simply return -1.0/(x+r) here */
+ /* compute -1.0/(x+r) accurately */
+ double a,t;
+ z = w;
+ SET_LOW_WORD(z,0);
+ v = r-(z - x); /* z+v = r+x */
+ t = a = -1.0/w; /* a = -1.0/w */
+ SET_LOW_WORD(t,0);
+ s = 1.0+t*z;
+ return t+a*(s+t*v);
+ }
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/mprec.c b/libjava/classpath/native/fdlibm/mprec.c
new file mode 100644
index 00000000000..00679ed3918
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/mprec.c
@@ -0,0 +1,958 @@
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991 by AT&T.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to
+ David M. Gay
+ AT&T Bell Laboratories, Room 2C-463
+ 600 Mountain Avenue
+ Murray Hill, NJ 07974-2070
+ U.S.A.
+ dmg@research.att.com or research!dmg
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Sudden_Underflow for IEEE-format machines without gradual
+ * underflow (i.e., that flush to zero on underflow).
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic.
+ * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define Just_16 to store 16 bits per 32-bit long when doing high-precision
+ * integer arithmetic. Whether this speeds things up or slows things
+ * down depends on the machine and the number being converted.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <java-assert.h>
+#include "mprec.h"
+
+/* reent.c knows this value */
+#define _Kmax 15
+#include <stdio.h>
+
+_Jv_Bigint *
+_DEFUN (Balloc, (ptr, k), struct _Jv_reent *ptr _AND int k)
+{
+ _Jv_Bigint *rv = NULL;
+
+ int i = 0;
+ int j = 1;
+
+ JvAssert ((1 << k) < MAX_BIGNUM_WDS);
+
+ while ((ptr->_allocation_map & j) && i < MAX_BIGNUMS)
+ i++, j <<= 1;
+
+ JvAssert (i < MAX_BIGNUMS);
+
+ if (i >= MAX_BIGNUMS)
+ return NULL;
+
+ ptr->_allocation_map |= j;
+ rv = &ptr->_freelist[i];
+
+ rv->_k = k;
+ rv->_maxwds = 32;
+
+ return rv;
+}
+
+
+void
+_DEFUN (Bfree, (ptr, v), struct _Jv_reent *ptr _AND _Jv_Bigint * v)
+{
+ long i;
+
+ i = v - ptr->_freelist;
+
+ JvAssert (i >= 0 && i < MAX_BIGNUMS);
+
+ if (i >= 0 && i < MAX_BIGNUMS)
+ ptr->_allocation_map &= ~ (1 << i);
+}
+
+
+_Jv_Bigint *
+_DEFUN (multadd, (ptr, b, m, a),
+ struct _Jv_reent *ptr _AND
+ _Jv_Bigint * b _AND
+ int m _AND
+ int a)
+{
+ int i, wds;
+ unsigned long *x, y;
+#ifdef Pack_32
+ unsigned long xi, z;
+#endif
+ _Jv_Bigint *b1;
+
+ wds = b->_wds;
+ x = b->_x;
+ i = 0;
+ do
+ {
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + a;
+ z = (xi >> 16) * m + (y >> 16);
+ a = (int) (z >> 16);
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + a;
+ a = (int) (y >> 16);
+ *x++ = y & 0xffff;
+#endif
+ }
+ while (++i < wds);
+ if (a)
+ {
+ if (wds >= b->_maxwds)
+ {
+ b1 = Balloc (ptr, b->_k + 1);
+ Bcopy (b1, b);
+ Bfree (ptr, b);
+ b = b1;
+ }
+ b->_x[wds++] = a;
+ b->_wds = wds;
+ }
+ return b;
+}
+
+_Jv_Bigint *
+_DEFUN (s2b, (ptr, s, nd0, nd, y9),
+ struct _Jv_reent * ptr _AND
+ _CONST char *s _AND
+ int nd0 _AND
+ int nd _AND
+ unsigned long y9)
+{
+ _Jv_Bigint *b;
+ int i, k;
+ long x, y;
+
+ x = (nd + 8) / 9;
+ for (k = 0, y = 1; x > y; y <<= 1, k++);
+#ifdef Pack_32
+ b = Balloc (ptr, k);
+ b->_x[0] = y9;
+ b->_wds = 1;
+#else
+ b = Balloc (ptr, k + 1);
+ b->_x[0] = y9 & 0xffff;
+ b->_wds = (b->_x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0)
+ {
+ s += 9;
+ do
+ b = multadd (ptr, b, 10, *s++ - '0');
+ while (++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for (; i < nd; i++)
+ b = multadd (ptr, b, 10, *s++ - '0');
+ return b;
+}
+
+int
+_DEFUN (hi0bits,
+ (x), register unsigned long x)
+{
+ register int k = 0;
+
+ if (!(x & 0xffff0000))
+ {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000))
+ {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000))
+ {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000))
+ {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000))
+ {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+}
+
+int
+_DEFUN (lo0bits, (y), unsigned long *y)
+{
+ register int k;
+ register unsigned long x = *y;
+
+ if (x & 7)
+ {
+ if (x & 1)
+ return 0;
+ if (x & 2)
+ {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff))
+ {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff))
+ {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf))
+ {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3))
+ {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1))
+ {
+ k++;
+ x >>= 1;
+ if (!(x & 1))
+ return 32;
+ }
+ *y = x;
+ return k;
+}
+
+_Jv_Bigint *
+_DEFUN (i2b, (ptr, i), struct _Jv_reent * ptr _AND int i)
+{
+ _Jv_Bigint *b;
+
+ b = Balloc (ptr, 1);
+ b->_x[0] = i;
+ b->_wds = 1;
+ return b;
+}
+
+_Jv_Bigint *
+_DEFUN (mult, (ptr, a, b), struct _Jv_reent * ptr _AND _Jv_Bigint * a _AND _Jv_Bigint * b)
+{
+ _Jv_Bigint *c;
+ int k, wa, wb, wc;
+ unsigned long carry, y, z;
+ unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+#ifdef Pack_32
+ unsigned long z2;
+#endif
+
+ if (a->_wds < b->_wds)
+ {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->_k;
+ wa = a->_wds;
+ wb = b->_wds;
+ wc = wa + wb;
+ if (wc > a->_maxwds)
+ k++;
+ c = Balloc (ptr, k);
+ for (x = c->_x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->_x;
+ xae = xa + wa;
+ xb = b->_x;
+ xbe = xb + wb;
+ xc0 = c->_x;
+#ifdef Pack_32
+ for (; xb < xbe; xb++, xc0++)
+ {
+ if ((y = *xb & 0xffff))
+ {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do
+ {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc (xc, z2, z);
+ }
+ while (x < xae);
+ *xc = carry;
+ }
+ if ((y = *xb >> 16))
+ {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do
+ {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc (xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ }
+ while (x < xae);
+ *xc = z2;
+ }
+ }
+#else
+ for (; xb < xbe; xc0++)
+ {
+ if ((y = *xb++))
+ {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do
+ {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ }
+ while (x < xae);
+ *xc = carry;
+ }
+ }
+#endif
+ for (xc0 = c->_x, xc = xc0 + wc; wc > 0 && !*--xc; --wc);
+ c->_wds = wc;
+ return c;
+}
+
+_Jv_Bigint *
+_DEFUN (pow5mult,
+ (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int k)
+{
+ _Jv_Bigint *b1, *p5, *p51;
+ int i;
+ static _CONST int p05[3] = {5, 25, 125};
+
+ if ((i = k & 3))
+ b = multadd (ptr, b, p05[i - 1], 0);
+
+ if (!(k >>= 2))
+ return b;
+ if (!(p5 = ptr->_p5s))
+ {
+ /* first time */
+ p5 = ptr->_p5s = i2b (ptr, 625);
+ p5->_next = 0;
+ }
+ for (;;)
+ {
+ if (k & 1)
+ {
+ b1 = mult (ptr, b, p5);
+ Bfree (ptr, b);
+ b = b1;
+ }
+ if (!(k >>= 1))
+ break;
+ if (!(p51 = p5->_next))
+ {
+ p51 = p5->_next = mult (ptr, p5, p5);
+ p51->_next = 0;
+ }
+ p5 = p51;
+ }
+ return b;
+}
+
+_Jv_Bigint *
+_DEFUN (lshift, (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int k)
+{
+ int i, k1, n, n1;
+ _Jv_Bigint *b1;
+ unsigned long *x, *x1, *xe, z;
+
+#ifdef Pack_32
+ n = k >> 5;
+#else
+ n = k >> 4;
+#endif
+ k1 = b->_k;
+ n1 = n + b->_wds + 1;
+ for (i = b->_maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc (ptr, k1);
+ x1 = b1->_x;
+ for (i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->_x;
+ xe = x + b->_wds;
+#ifdef Pack_32
+ if (k &= 0x1f)
+ {
+ k1 = 32 - k;
+ z = 0;
+ do
+ {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while (x < xe);
+ if ((*x1 = z))
+ ++n1;
+ }
+#else
+ if (k &= 0xf)
+ {
+ k1 = 16 - k;
+ z = 0;
+ do
+ {
+ *x1++ = (*x << k & 0xffff) | z;
+ z = *x++ >> k1;
+ }
+ while (x < xe);
+ if ((*x1 = z))
+ ++n1;
+ }
+#endif
+ else
+ do
+ *x1++ = *x++;
+ while (x < xe);
+ b1->_wds = n1 - 1;
+ Bfree (ptr, b);
+ return b1;
+}
+
+int
+_DEFUN (cmp, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
+{
+ unsigned long *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->_wds;
+ j = b->_wds;
+#ifdef DEBUG
+ if (i > 1 && !a->_x[i - 1])
+ Bug ("cmp called with a->_x[a->_wds-1] == 0");
+ if (j > 1 && !b->_x[j - 1])
+ Bug ("cmp called with b->_x[b->_wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->_x;
+ xa = xa0 + j;
+ xb0 = b->_x;
+ xb = xb0 + j;
+ for (;;)
+ {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+}
+
+_Jv_Bigint *
+_DEFUN (diff, (ptr, a, b), struct _Jv_reent * ptr _AND
+ _Jv_Bigint * a _AND _Jv_Bigint * b)
+{
+ _Jv_Bigint *c;
+ int i, wa, wb;
+ long borrow, y; /* We need signed shifts here. */
+ unsigned long *xa, *xae, *xb, *xbe, *xc;
+#ifdef Pack_32
+ long z;
+#endif
+
+ i = cmp (a, b);
+ if (!i)
+ {
+ c = Balloc (ptr, 0);
+ c->_wds = 1;
+ c->_x[0] = 0;
+ return c;
+ }
+ if (i < 0)
+ {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc (ptr, a->_k);
+ c->_sign = i;
+ wa = a->_wds;
+ xa = a->_x;
+ xae = xa + wa;
+ wb = b->_wds;
+ xb = b->_x;
+ xbe = xb + wb;
+ xc = c->_x;
+ borrow = 0;
+#ifdef Pack_32
+ do
+ {
+ y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend (borrow, z);
+ Storeinc (xc, z, y);
+ }
+ while (xb < xbe);
+ while (xa < xae)
+ {
+ y = (*xa & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ z = (*xa++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend (borrow, z);
+ Storeinc (xc, z, y);
+ }
+#else
+ do
+ {
+ y = *xa++ - *xb++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ *xc++ = y & 0xffff;
+ }
+ while (xb < xbe);
+ while (xa < xae)
+ {
+ y = *xa++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ *xc++ = y & 0xffff;
+ }
+#endif
+ while (!*--xc)
+ wa--;
+ c->_wds = wa;
+ return c;
+}
+
+double
+_DEFUN (ulp, (_x), double _x)
+{
+ union double_union x, a;
+ register long L;
+
+ x.d = _x;
+
+ L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0)
+ {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ word0 (a) = L;
+#ifndef _DOUBLE_IS_32BITS
+ word1 (a) = 0;
+#endif
+
+#ifndef Sudden_Underflow
+ }
+ else
+ {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift)
+ {
+ word0 (a) = 0x80000 >> L;
+#ifndef _DOUBLE_IS_32BITS
+ word1 (a) = 0;
+#endif
+ }
+ else
+ {
+ word0 (a) = 0;
+ L -= Exp_shift;
+#ifndef _DOUBLE_IS_32BITS
+ word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+#endif
+ }
+ }
+#endif
+ return a.d;
+}
+
+double
+_DEFUN (b2d, (a, e),
+ _Jv_Bigint * a _AND int *e)
+{
+ unsigned long *xa, *xa0, w, y, z;
+ int k;
+ union double_union d;
+#ifdef VAX
+ unsigned long d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+ xa0 = a->_x;
+ xa = xa0 + a->_wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y)
+ Bug ("zero y in b2d");
+#endif
+ k = hi0bits (y);
+ *e = 32 - k;
+#ifdef Pack_32
+ if (k < Ebits)
+ {
+ d0 = Exp_1 | y >> (Ebits - k);
+ w = xa > xa0 ? *--xa : 0;
+#ifndef _DOUBLE_IS_32BITS
+ d1 = y << (32 - Ebits + k) | w >> (Ebits - k);
+#endif
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits)
+ {
+ d0 = Exp_1 | y << k | z >> (32 - k);
+ y = xa > xa0 ? *--xa : 0;
+#ifndef _DOUBLE_IS_32BITS
+ d1 = z << k | y >> (32 - k);
+#endif
+ }
+ else
+ {
+ d0 = Exp_1 | y;
+#ifndef _DOUBLE_IS_32BITS
+ d1 = z;
+#endif
+ }
+#else
+ if (k < Ebits + 16)
+ {
+ z = xa > xa0 ? *--xa : 0;
+ d0 = Exp_1 | y << (k - Ebits) | z >> (Ebits + 16 - k);
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << (k + 16 - Ebits) | w << (k - Ebits) | y >> (16 + Ebits - k);
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ d0 = Exp_1 | y << (k + 16) | z << k | w >> (16 - k);
+ y = xa > xa0 ? *--xa : 0;
+ d1 = w << (k + 16) | y << k;
+#endif
+ret_d:
+#ifdef VAX
+ word0 (d) = d0 >> 16 | d0 << 16;
+ word1 (d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+ return d.d;
+}
+
+_Jv_Bigint *
+_DEFUN (d2b,
+ (ptr, _d, e, bits),
+ struct _Jv_reent * ptr _AND
+ double _d _AND
+ int *e _AND
+ int *bits)
+
+{
+ union double_union d;
+ _Jv_Bigint *b;
+ int de, i, k;
+ unsigned long *x, y, z;
+#ifdef VAX
+ unsigned long d0, d1;
+ d.d = _d;
+ d0 = word0 (d) >> 16 | word0 (d) << 16;
+ d1 = word1 (d) >> 16 | word1 (d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+ d.d = _d;
+#endif
+
+#ifdef Pack_32
+ b = Balloc (ptr, 1);
+#else
+ b = Balloc (ptr, 2);
+#endif
+ x = b->_x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+ de = (int) (d0 >> Exp_shift);
+#ifndef IBM
+ z |= Exp_msk11;
+#endif
+#else
+ if ((de = (int) (d0 >> Exp_shift)))
+ z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+#ifndef _DOUBLE_IS_32BITS
+ if ((y = d1))
+ {
+ if ((k = lo0bits (&y)))
+ {
+ x[0] = y | z << (32 - k);
+ z >>= k;
+ }
+ else
+ x[0] = y;
+ i = b->_wds = (x[1] = z) ? 2 : 1;
+ }
+ else
+#endif
+ {
+#ifdef DEBUG
+ if (!z)
+ Bug ("Zero passed to d2b");
+#endif
+ k = lo0bits (&z);
+ x[0] = z;
+ i = b->_wds = 1;
+#ifndef _DOUBLE_IS_32BITS
+ k += 32;
+#endif
+ }
+#else
+ if ((y = d1))
+ {
+ if ((k = lo0bits (&y)))
+ if (k >= 16)
+ {
+ x[0] = y | (z << (32 - k) & 0xffff);
+ x[1] = z >> (k - 16) & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ }
+ else
+ {
+ x[0] = y & 0xffff;
+ x[1] = (y >> 16 | z << (16 - k)) & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> (k + 16);
+ i = 3;
+ }
+ else
+ {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ }
+ else
+ {
+#ifdef DEBUG
+ if (!z)
+ Bug ("Zero passed to d2b");
+#endif
+ k = lo0bits (&z);
+ if (k >= 16)
+ {
+ x[0] = z;
+ i = 0;
+ }
+ else
+ {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while (!x[i])
+ --i;
+ b->_wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de)
+ {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P - 1) << 2) + k;
+ *bits = 4 * P + 8 - k - hi0bits (word0 (d) & Frac_mask);
+#else
+ *e = de - Bias - (P - 1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else
+ {
+ *e = de - Bias - (P - 1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32 * i - hi0bits (x[i - 1]);
+#else
+ *bits = (i + 2) * 16 - hi0bits (x[i]);
+#endif
+ }
+#endif
+ return b;
+}
+#undef d0
+#undef d1
+
+double
+_DEFUN (ratio, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
+
+{
+ union double_union da, db;
+ int k, ka, kb;
+
+ da.d = b2d (a, &ka);
+ db.d = b2d (b, &kb);
+#ifdef Pack_32
+ k = ka - kb + 32 * (a->_wds - b->_wds);
+#else
+ k = ka - kb + 16 * (a->_wds - b->_wds);
+#endif
+#ifdef IBM
+ if (k > 0)
+ {
+ word0 (da) += (k >> 2) * Exp_msk1;
+ if (k &= 3)
+ da.d *= 1 << k;
+ }
+ else
+ {
+ k = -k;
+ word0 (db) += (k >> 2) * Exp_msk1;
+ if (k &= 3)
+ db.d *= 1 << k;
+ }
+#else
+ if (k > 0)
+ word0 (da) += k * Exp_msk1;
+ else
+ {
+ k = -k;
+ word0 (db) += k * Exp_msk1;
+ }
+#endif
+ return da.d / db.d;
+}
+
+
+_CONST double
+ tens[] =
+{
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22, 1e23, 1e24
+
+};
+
+#if !defined(_DOUBLE_IS_32BITS) && !defined(__v800)
+_CONST double bigtens[] =
+{1e16, 1e32, 1e64, 1e128, 1e256};
+
+_CONST double tinytens[] =
+{1e-16, 1e-32, 1e-64, 1e-128, 1e-256};
+#else
+_CONST double bigtens[] =
+{1e16, 1e32};
+
+_CONST double tinytens[] =
+{1e-16, 1e-32};
+#endif
+
+
diff --git a/libjava/classpath/native/fdlibm/mprec.h b/libjava/classpath/native/fdlibm/mprec.h
new file mode 100644
index 00000000000..d796b81de82
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/mprec.h
@@ -0,0 +1,402 @@
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 2000 by AT&T.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to
+ David M. Gay
+ AT&T Bell Laboratories, Room 2C-463
+ 600 Mountain Avenue
+ Murray Hill, NJ 07974-2070
+ U.S.A.
+ dmg@research.att.com or research!dmg
+ */
+
+#ifndef __CLASSPATH_MPREC_H__
+#define __CLASSPATH_MPREC_H__
+
+#include <config.h>
+#include "ieeefp.h"
+
+#if defined HAVE_STDINT_H
+#include <stdint.h>
+#elif defined HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#if defined HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if defined HAVE_SYS_CONFIG_H
+#include <sys/config.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ISO C99 int type declarations */
+
+#if !defined HAVE_INT32_DEFINED && defined HAVE_BSD_INT32_DEFINED
+typedef u_int32_t uint32_t;
+#endif
+
+#if !defined HAVE_BSD_INT32_DEFINED && !defined HAVE_INT32_DEFINED
+/* FIXME this could have problems with systems that don't define SI to be 4 */
+typedef int int32_t __attribute__((mode(SI)));
+
+/* This is a blatant hack: on Solaris 2.5, pthread.h defines uint32_t
+ in pthread.h, which we sometimes include. We protect our
+ definition the same way Solaris 2.5 does, to avoid redefining it. */
+# ifndef _UINT32_T
+typedef unsigned int uint32_t __attribute__((mode(SI)));
+# endif
+#endif
+
+ /* These typedefs are true for the targets running Java. */
+
+#ifdef __IEEE_LITTLE_ENDIAN
+#define IEEE_8087
+#endif
+
+#ifdef __IEEE_BIG_ENDIAN
+#define IEEE_MC68k
+#endif
+
+#ifdef __Z8000__
+#define Just_16
+#endif
+
+#ifdef DEBUG
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+
+#ifdef Unsigned_Shifts
+#define Sign_Extend(a,b) if (b < 0) a |= (uint32_t)0xffff0000;
+#else
+#define Sign_Extend(a,b) /*no-op*/
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
+#endif
+
+/* If we are going to examine or modify specific bits in a double using
+ the word0 and/or word1 macros, then we must wrap the double inside
+ a union. This is necessary to avoid undefined behavior according to
+ the ANSI C spec. */
+union double_union
+{
+ double d;
+ uint32_t i[2];
+};
+
+#ifdef IEEE_8087
+#define word0(x) (x.i[1])
+#define word1(x) (x.i[0])
+#else
+#define word0(x) (x.i[0])
+#define word1(x) (x.i[1])
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_8087) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k)
+#if defined (_DOUBLE_IS_32BITS)
+#define Exp_shift 23
+#define Exp_shift1 23
+#define Exp_msk1 ((uint32_t)0x00800000L)
+#define Exp_msk11 ((uint32_t)0x00800000L)
+#define Exp_mask ((uint32_t)0x7f800000L)
+#define P 24
+#define Bias 127
+#if 0
+#define IEEE_Arith /* it is, but the code doesn't handle IEEE singles yet */
+#endif
+#define Emin (-126)
+#define Exp_1 ((uint32_t)0x3f800000L)
+#define Exp_11 ((uint32_t)0x3f800000L)
+#define Ebits 8
+#define Frac_mask ((uint32_t)0x007fffffL)
+#define Frac_mask1 ((uint32_t)0x007fffffL)
+#define Ten_pmax 10
+#define Sign_bit ((uint32_t)0x80000000L)
+#define Ten_pmax 10
+#define Bletch 2
+#define Bndry_mask ((uint32_t)0x007fffffL)
+#define Bndry_mask1 ((uint32_t)0x007fffffL)
+#define LSB 1
+#define Sign_bit ((uint32_t)0x80000000L)
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 5
+#define Int_max 6
+#define Infinite(x) (word0(x) == ((uint32_t)0x7f800000L))
+#undef word0
+#undef word1
+
+#define word0(x) (x.i[0])
+#define word1(x) 0
+#else
+
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 ((uint32_t)0x100000L)
+#define Exp_msk11 ((uint32_t)0x100000L)
+#define Exp_mask ((uint32_t)0x7ff00000L)
+#define P 53
+#define Bias 1023
+#define IEEE_Arith
+#define Emin (-1022)
+#define Exp_1 ((uint32_t)0x3ff00000L)
+#define Exp_11 ((uint32_t)0x3ff00000L)
+#define Ebits 11
+#define Frac_mask ((uint32_t)0xfffffL)
+#define Frac_mask1 ((uint32_t)0xfffffL)
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask ((uint32_t)0xfffffL)
+#define Bndry_mask1 ((uint32_t)0xfffffL)
+#define LSB 1
+#define Sign_bit ((uint32_t)0x80000000L)
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#define Infinite(x) (word0(x) == ((uint32_t)0x7ff00000L)) /* sufficient test for here */
+#endif
+
+#else
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 ((uint32_t)0x1000000L)
+#define Exp_msk11 ((uint32_t)0x1000000L)
+#define Exp_mask ((uint32_t)0x7f000000L)
+#define P 14
+#define Bias 65
+#define Exp_1 ((uint32_t)0x41000000L)
+#define Exp_11 ((uint32_t)0x41000000L)
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask ((uint32_t)0xffffffL)
+#define Frac_mask1 ((uint32_t)0xffffffL)
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask ((uint32_t)0xefffffL)
+#define Bndry_mask1 ((uint32_t)0xffffffL)
+#define LSB 1
+#define Sign_bit ((uint32_t)0x80000000L)
+#define Log2P 4
+#define Tiny0 ((uint32_t)0x100000L)
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 ((uint32_t)0x800000L)
+#define Exp_mask ((uint32_t)0x7f80L)
+#define P 56
+#define Bias 129
+#define Exp_1 ((uint32_t)0x40800000L)
+#define Exp_11 ((uint32_t)0x4080L)
+#define Ebits 8
+#define Frac_mask ((uint32_t)0x7fffffL)
+#define Frac_mask1 ((uint32_t)0xffff007fL)
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask ((uint32_t)0xffff007fL)
+#define Bndry_mask1 ((uint32_t)0xffff007fL)
+#define LSB ((uint32_t)0x10000L)
+#define Sign_bit ((uint32_t)0x8000L)
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+#ifdef KR_headers
+extern double rnd_prod(), rnd_quot();
+#else
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#endif
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 ((uint32_t)0xffffffffL)
+
+#ifndef Just_16
+/* When Pack_32 is not defined, we store 16 bits per 32-bit long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per long.
+ */
+
+#ifndef Pack_32
+#if SIZEOF_VOID_P != 8
+#define Pack_32
+#endif
+#endif
+#endif
+
+
+#define MAX_BIGNUMS 16
+#define MAX_BIGNUM_WDS 32
+
+struct _Jv_Bigint
+{
+ struct _Jv_Bigint *_next;
+ int _k, _maxwds, _sign, _wds;
+ unsigned long _x[MAX_BIGNUM_WDS];
+};
+
+
+#define _PTR void *
+#define _AND ,
+#define _NOARGS void
+#define _CONST const
+#define _VOLATILE volatile
+#define _SIGNED signed
+#define _DOTS , ...
+#define _VOID void
+#define _EXFUN(name, proto) name proto
+#define _DEFUN(name, arglist, args) name(args)
+#define _DEFUN_VOID(name) name(_NOARGS)
+#define _CAST_VOID (void)
+
+
+struct _Jv_reent
+{
+ /* local copy of errno */
+ int _errno;
+
+ /* used by mprec routines */
+ struct _Jv_Bigint *_result;
+ int _result_k;
+ struct _Jv_Bigint *_p5s;
+
+ struct _Jv_Bigint _freelist[MAX_BIGNUMS];
+ int _allocation_map;
+
+ int num;
+};
+
+
+typedef struct _Jv_Bigint _Jv_Bigint;
+
+#define Balloc _Jv_Balloc
+#define Bfree _Jv_Bfree
+#define multadd _Jv_multadd
+#define s2b _Jv_s2b
+#define lo0bits _Jv_lo0bits
+#define hi0bits _Jv_hi0bits
+#define i2b _Jv_i2b
+#define mult _Jv_mult
+#define pow5mult _Jv_pow5mult
+#define lshift _Jv_lshift
+#define cmp _Jv__mcmp
+#define diff _Jv__mdiff
+#define ulp _Jv_ulp
+#define b2d _Jv_b2d
+#define d2b _Jv_d2b
+#define ratio _Jv_ratio
+
+#define tens _Jv__mprec_tens
+#define bigtens _Jv__mprec_bigtens
+#define tinytens _Jv__mprec_tinytens
+
+#define _dtoa _Jv_dtoa
+#define _dtoa_r _Jv_dtoa_r
+#define _strtod_r _Jv_strtod_r
+
+extern double _EXFUN(_strtod_r, (struct _Jv_reent *ptr, const char *s00, char **se));
+extern char* _EXFUN(_dtoa_r, (struct _Jv_reent *ptr, double d,
+ int mode, int ndigits, int *decpt, int *sign,
+ char **rve, int float_type));
+void _EXFUN(_dtoa, (double d, int mode, int ndigits, int *decpt, int *sign,
+ char **rve, char *buf, int float_type));
+
+double _EXFUN(ulp,(double x));
+double _EXFUN(b2d,(_Jv_Bigint *a , int *e));
+_Jv_Bigint * _EXFUN(Balloc,(struct _Jv_reent *p, int k));
+void _EXFUN(Bfree,(struct _Jv_reent *p, _Jv_Bigint *v));
+_Jv_Bigint * _EXFUN(multadd,(struct _Jv_reent *p, _Jv_Bigint *, int, int));
+_Jv_Bigint * _EXFUN(s2b,(struct _Jv_reent *, const char*, int, int, unsigned long));
+_Jv_Bigint * _EXFUN(i2b,(struct _Jv_reent *,int));
+_Jv_Bigint * _EXFUN(mult, (struct _Jv_reent *, _Jv_Bigint *, _Jv_Bigint *));
+_Jv_Bigint * _EXFUN(pow5mult, (struct _Jv_reent *, _Jv_Bigint *, int k));
+int _EXFUN(hi0bits,(unsigned long));
+int _EXFUN(lo0bits,(unsigned long *));
+_Jv_Bigint * _EXFUN(d2b,(struct _Jv_reent *p, double d, int *e, int *bits));
+_Jv_Bigint * _EXFUN(lshift,(struct _Jv_reent *p, _Jv_Bigint *b, int k));
+_Jv_Bigint * _EXFUN(diff,(struct _Jv_reent *p, _Jv_Bigint *a, _Jv_Bigint *b));
+int _EXFUN(cmp,(_Jv_Bigint *a, _Jv_Bigint *b));
+
+double _EXFUN(ratio,(_Jv_Bigint *a, _Jv_Bigint *b));
+#define Bcopy(x,y) memcpy((char *)&x->_sign, (char *)&y->_sign, y->_wds*sizeof(long) + 2*sizeof(int))
+
+#if defined(_DOUBLE_IS_32BITS) && defined(__v800)
+#define n_bigtens 2
+#else
+#define n_bigtens 5
+#endif
+
+extern _CONST double tinytens[];
+extern _CONST double bigtens[];
+extern _CONST double tens[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CLASSPATH_MPREC_H__ */
diff --git a/libjava/classpath/native/fdlibm/s_atan.c b/libjava/classpath/native/fdlibm/s_atan.c
new file mode 100644
index 00000000000..2ee74585423
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_atan.c
@@ -0,0 +1,181 @@
+
+/* @(#)s_atan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/*
+FUNCTION
+ <<atan>>, <<atanf>>---arc tangent
+
+INDEX
+ atan
+INDEX
+ atanf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double atan(double <[x]>);
+ float atanf(float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double atan(<[x]>);
+ double <[x]>;
+
+ float atanf(<[x]>);
+ float <[x]>;
+
+DESCRIPTION
+
+<<atan>> computes the inverse tangent (arc tangent) of the input value.
+
+<<atanf>> is identical to <<atan>>, save that it operates on <<floats>>.
+
+RETURNS
+@ifinfo
+<<atan>> returns a value in radians, in the range of -pi/2 to pi/2.
+@end ifinfo
+@tex
+<<atan>> returns a value in radians, in the range of $-\pi/2$ to $\pi/2$.
+@end tex
+
+PORTABILITY
+<<atan>> is ANSI C. <<atanf>> is an extension.
+
+*/
+
+/* atan(x)
+ * Method
+ * 1. Reduce x to positive by atan(x) = -atan(-x).
+ * 2. According to the integer k=4t+0.25 chopped, t=x, the argument
+ * is further reduced to one of the following intervals and the
+ * arctangent of t is evaluated by the corresponding formula:
+ *
+ * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
+ * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
+ * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
+ * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
+ * [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following
+ * constants. The decimal values may be used, provided that the
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double atanhi[] = {
+#else
+static double atanhi[] = {
+#endif
+ 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
+ 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
+ 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
+ 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
+};
+
+#ifdef __STDC__
+static const double atanlo[] = {
+#else
+static double atanlo[] = {
+#endif
+ 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
+ 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
+ 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
+ 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
+};
+
+#ifdef __STDC__
+static const double aT[] = {
+#else
+static double aT[] = {
+#endif
+ 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
+ -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
+ 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
+ -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
+ 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
+ -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
+ 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
+ -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
+ 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
+ -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
+ 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
+};
+
+#ifdef __STDC__
+ static const double
+#else
+ static double
+#endif
+one = 1.0,
+huge = 1.0e300;
+
+#ifdef __STDC__
+ double atan(double x)
+#else
+ double atan(x)
+ double x;
+#endif
+{
+ double w,s1,s2,z;
+ int32_t ix,hx,id;
+
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x44100000) { /* if |x| >= 2^66 */
+ uint32_t low;
+ GET_LOW_WORD(low,x);
+ if(ix>0x7ff00000||
+ (ix==0x7ff00000&&(low!=0)))
+ return x+x; /* NaN */
+ if(hx>0) return atanhi[3]+atanlo[3];
+ else return -atanhi[3]-atanlo[3];
+ } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
+ if (ix < 0x3e200000) { /* |x| < 2^-29 */
+ if(huge+x>one) return x; /* raise inexact */
+ }
+ id = -1;
+ } else {
+ x = fabs(x);
+ if (ix < 0x3ff30000) { /* |x| < 1.1875 */
+ if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */
+ id = 0; x = (2.0*x-one)/(2.0+x);
+ } else { /* 11/16<=|x|< 19/16 */
+ id = 1; x = (x-one)/(x+one);
+ }
+ } else {
+ if (ix < 0x40038000) { /* |x| < 2.4375 */
+ id = 2; x = (x-1.5)/(one+1.5*x);
+ } else { /* 2.4375 <= |x| < 2^66 */
+ id = 3; x = -1.0/x;
+ }
+ }}
+ /* end of argument reduction */
+ z = x*x;
+ w = z*z;
+ /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+ s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
+ s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
+ if (id<0) return x - x*(s1+s2);
+ else {
+ z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+ return (hx<0)? -z:z;
+ }
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/libjava/classpath/native/fdlibm/s_ceil.c b/libjava/classpath/native/fdlibm/s_ceil.c
new file mode 100644
index 00000000000..250373b40d1
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_ceil.c
@@ -0,0 +1,80 @@
+
+/* @(#)s_ceil.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * ceil(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to ceil(x).
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double huge = 1.0e300;
+#else
+static double huge = 1.0e300;
+#endif
+
+#ifdef __STDC__
+ double ceil(double x)
+#else
+ double ceil(x)
+ double x;
+#endif
+{
+ int32_t i0,i1,j0;
+ uint32_t i,j;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0<0) {i0=0x80000000;i1=0;}
+ else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
+ }
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0>0) i0 += (0x00100000)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((uint32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0>0) {
+ if(j0==20) i0+=1;
+ else {
+ j = i1 + (1<<(52-j0));
+ if(j<(uint32_t)i1) i0+=1; /* got a carry */
+ i1 = j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ INSERT_WORDS(x,i0,i1);
+ return x;
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/libjava/classpath/native/fdlibm/s_copysign.c b/libjava/classpath/native/fdlibm/s_copysign.c
new file mode 100644
index 00000000000..4804df130dc
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_copysign.c
@@ -0,0 +1,82 @@
+
+/* @(#)s_copysign.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+<<copysign>>, <<copysignf>>---sign of <[y]>, magnitude of <[x]>
+
+INDEX
+ copysign
+INDEX
+ copysignf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double copysign (double <[x]>, double <[y]>);
+ float copysignf (float <[x]>, float <[y]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double copysign (<[x]>, <[y]>)
+ double <[x]>;
+ double <[y]>;
+
+ float copysignf (<[x]>, <[y]>)
+ float <[x]>;
+ float <[y]>;
+
+DESCRIPTION
+<<copysign>> constructs a number with the magnitude (absolute value)
+of its first argument, <[x]>, and the sign of its second argument,
+<[y]>.
+
+<<copysignf>> does the same thing; the two functions differ only in
+the type of their arguments and result.
+
+RETURNS
+<<copysign>> returns a <<double>> with the magnitude of
+<[x]> and the sign of <[y]>.
+<<copysignf>> returns a <<float>> with the magnitude of
+<[x]> and the sign of <[y]>.
+
+PORTABILITY
+<<copysign>> is not required by either ANSI C or the System V Interface
+Definition (Issue 2).
+
+*/
+
+/*
+ * copysign(double x, double y)
+ * copysign(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double copysign(double x, double y)
+#else
+ double copysign(x,y)
+ double x,y;
+#endif
+{
+ uint32_t hx,hy;
+ GET_HIGH_WORD(hx,x);
+ GET_HIGH_WORD(hy,y);
+ SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
+ return x;
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/libjava/classpath/native/fdlibm/s_cos.c b/libjava/classpath/native/fdlibm/s_cos.c
new file mode 100644
index 00000000000..be1538d4c0b
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_cos.c
@@ -0,0 +1,82 @@
+
+/* @(#)s_cos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* cos(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ * __kernel_sin ... sine function on [-pi/4,pi/4]
+ * __kernel_cos ... cosine function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2 ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double cos(double x)
+#else
+ double cos(x)
+ double x;
+#endif
+{
+ double y[2],z=0.0;
+ int32_t n,ix;
+
+ /* High word of x. */
+ GET_HIGH_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3fe921fb) return __kernel_cos(x,z);
+
+ /* cos(Inf or NaN) is NaN */
+ else if (ix>=0x7ff00000) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2(x,y);
+ switch(n&3) {
+ case 0: return __kernel_cos(y[0],y[1]);
+ case 1: return -__kernel_sin(y[0],y[1],1);
+ case 2: return -__kernel_cos(y[0],y[1]);
+ default:
+ return __kernel_sin(y[0],y[1],1);
+ }
+ }
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/libjava/classpath/native/fdlibm/s_fabs.c b/libjava/classpath/native/fdlibm/s_fabs.c
new file mode 100644
index 00000000000..dfee33fecdb
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_fabs.c
@@ -0,0 +1,73 @@
+
+/* @(#)s_fabs.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+ <<fabs>>, <<fabsf>>---absolute value (magnitude)
+INDEX
+ fabs
+INDEX
+ fabsf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double fabs(double <[x]>);
+ float fabsf(float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double fabs(<[x]>)
+ double <[x]>;
+
+ float fabsf(<[x]>)
+ float <[x]>;
+
+DESCRIPTION
+<<fabs>> and <<fabsf>> calculate
+@tex
+$|x|$,
+@end tex
+the absolute value (magnitude) of the argument <[x]>, by direct
+manipulation of the bit representation of <[x]>.
+
+RETURNS
+The calculated value is returned. No errors are detected.
+
+PORTABILITY
+<<fabs>> is ANSI.
+<<fabsf>> is an extension.
+
+*/
+
+/*
+ * fabs(x) returns the absolute value of x.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double fabs(double x)
+#else
+ double fabs(x)
+ double x;
+#endif
+{
+ uint32_t high;
+ GET_HIGH_WORD(high,x);
+ SET_HIGH_WORD(x,high&0x7fffffff);
+ return x;
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/libjava/classpath/native/fdlibm/s_finite.c b/libjava/classpath/native/fdlibm/s_finite.c
new file mode 100644
index 00000000000..3e6c8122b25
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_finite.c
@@ -0,0 +1,31 @@
+
+/* @(#)s_finite.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * finite(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+ int finite(double x)
+#else
+ int finite(x)
+ double x;
+#endif
+{
+ uint32_t high;
+ GET_HIGH_WORD(high,x);
+ return (unsigned)((high&0x7fffffff)-0x7ff00000)>>31;
+}
diff --git a/libjava/classpath/native/fdlibm/s_floor.c b/libjava/classpath/native/fdlibm/s_floor.c
new file mode 100644
index 00000000000..77e39cb7de0
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_floor.c
@@ -0,0 +1,134 @@
+
+/* @(#)s_floor.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+<<floor>>, <<floorf>>, <<ceil>>, <<ceilf>>---floor and ceiling
+INDEX
+ floor
+INDEX
+ floorf
+INDEX
+ ceil
+INDEX
+ ceilf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double floor(double <[x]>);
+ float floorf(float <[x]>);
+ double ceil(double <[x]>);
+ float ceilf(float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double floor(<[x]>)
+ double <[x]>;
+ float floorf(<[x]>)
+ float <[x]>;
+ double ceil(<[x]>)
+ double <[x]>;
+ float ceilf(<[x]>)
+ float <[x]>;
+
+DESCRIPTION
+<<floor>> and <<floorf>> find
+@tex
+$\lfloor x \rfloor$,
+@end tex
+the nearest integer less than or equal to <[x]>.
+<<ceil>> and <<ceilf>> find
+@tex
+$\lceil x\rceil$,
+@end tex
+the nearest integer greater than or equal to <[x]>.
+
+RETURNS
+<<floor>> and <<ceil>> return the integer result as a double.
+<<floorf>> and <<ceilf>> return the integer result as a float.
+
+PORTABILITY
+<<floor>> and <<ceil>> are ANSI.
+<<floorf>> and <<ceilf>> are extensions.
+
+
+*/
+
+/*
+ * floor(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ * Bit twiddling.
+ * Exception:
+ * Inexact flag raised if x not equal to floor(x).
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double huge = 1.0e300;
+#else
+static double huge = 1.0e300;
+#endif
+
+#ifdef __STDC__
+ double floor(double x)
+#else
+ double floor(x)
+ double x;
+#endif
+{
+ int32_t i0,i1,j0;
+ uint32_t i,j;
+ EXTRACT_WORDS(i0,i1,x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0>=0) {i0=i1=0;}
+ else if(((i0&0x7fffffff)|i1)!=0)
+ { i0=0xbff00000;i1=0;}
+ }
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0<0) i0 += (0x00100000)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((uint32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ if(huge+x>0.0) { /* raise inexact flag */
+ if(i0<0) {
+ if(j0==20) i0+=1;
+ else {
+ j = i1+(1<<(52-j0));
+ if(j<(uint32_t)i1) i0 +=1 ; /* got a carry */
+ i1=j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ INSERT_WORDS(x,i0,i1);
+ return x;
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/libjava/classpath/native/fdlibm/s_rint.c b/libjava/classpath/native/fdlibm/s_rint.c
new file mode 100644
index 00000000000..5d3f8114e2b
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_rint.c
@@ -0,0 +1,87 @@
+
+/* @(#)s_rint.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * rint(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ * Using floating addition.
+ * Exception:
+ * Inexact flag raised if x not equal to rint(x).
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+TWO52[2]={
+ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+};
+
+#ifdef __STDC__
+ double rint(double x)
+#else
+ double rint(x)
+ double x;
+#endif
+{
+ int32_t i0,j0,sx;
+ uint32_t i,i1;
+ double t;
+ volatile double w;
+ EXTRACT_WORDS(i0,i1,x);
+ sx = (i0>>31)&1;
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) {
+ if(((i0&0x7fffffff)|i1)==0) return x;
+ i1 |= (i0&0x0fffff);
+ i0 &= 0xfffe0000;
+ i0 |= ((i1|-i1)>>12)&0x80000;
+ SET_HIGH_WORD(x,i0);
+ w = TWO52[sx]+x;
+ t = w-TWO52[sx];
+ GET_HIGH_WORD(i0,t);
+ SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
+ return t;
+ } else {
+ i = (0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ i>>=1;
+ if(((i0&i)|i1)!=0) {
+ if(j0==19) i1 = 0x40000000; else
+ i0 = (i0&(~i))|((0x20000)>>j0);
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((uint32_t)(0xffffffff))>>(j0-20);
+ if((i1&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
+ }
+ INSERT_WORDS(x,i0,i1);
+ w = TWO52[sx]+x;
+ return w-TWO52[sx];
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/libjava/classpath/native/fdlibm/s_scalbn.c b/libjava/classpath/native/fdlibm/s_scalbn.c
new file mode 100644
index 00000000000..36ee88981ba
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_scalbn.c
@@ -0,0 +1,104 @@
+
+/* @(#)s_scalbn.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+<<scalbn>>, <<scalbnf>>---scale by integer
+INDEX
+ scalbn
+INDEX
+ scalbnf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double scalbn(double <[x]>, int <[y]>);
+ float scalbnf(float <[x]>, int <[y]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double scalbn(<[x]>,<[y]>)
+ double <[x]>;
+ int <[y]>;
+ float scalbnf(<[x]>,<[y]>)
+ float <[x]>;
+ int <[y]>;
+
+DESCRIPTION
+<<scalbn>> and <<scalbnf>> scale <[x]> by <[n]>, returning <[x]> times
+2 to the power <[n]>. The result is computed by manipulating the
+exponent, rather than by actually performing an exponentiation or
+multiplication.
+
+RETURNS
+<[x]> times 2 to the power <[n]>.
+
+PORTABILITY
+Neither <<scalbn>> nor <<scalbnf>> is required by ANSI C or by the System V
+Interface Definition (Issue 2).
+
+*/
+
+/*
+ * scalbn (double x, int n)
+ * scalbn(x,n) returns x* 2**n computed by exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+huge = 1.0e+300,
+tiny = 1.0e-300;
+
+#ifdef __STDC__
+ double scalbn (double x, int n)
+#else
+ double scalbn (x,n)
+ double x; int n;
+#endif
+{
+ int32_t k,hx,lx;
+ EXTRACT_WORDS(hx,lx,x);
+ k = (hx&0x7ff00000)>>20; /* extract exponent */
+ if (k==0) { /* 0 or subnormal x */
+ if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+ x *= two54;
+ GET_HIGH_WORD(hx,x);
+ k = ((hx&0x7ff00000)>>20) - 54;
+ if (n< -50000) return tiny*x; /*underflow*/
+ }
+ if (k==0x7ff) return x+x; /* NaN or Inf */
+ k = k+n;
+ if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */
+ if (k > 0) /* normal result */
+ {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
+ if (k <= -54) {
+ if (n > 50000) /* in case integer overflow in n+k */
+ return huge*copysign(huge,x); /*overflow*/
+ else return tiny*copysign(tiny,x); /*underflow*/
+ }
+ k += 54; /* subnormal result */
+ SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
+ return x*twom54;
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/libjava/classpath/native/fdlibm/s_sin.c b/libjava/classpath/native/fdlibm/s_sin.c
new file mode 100644
index 00000000000..d315455549c
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_sin.c
@@ -0,0 +1,132 @@
+
+/* @(#)s_sin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+ <<sin>>, <<sinf>>, <<cos>>, <<cosf>>---sine or cosine
+INDEX
+sin
+INDEX
+sinf
+INDEX
+cos
+INDEX
+cosf
+ANSI_SYNOPSIS
+ #include <math.h>
+ double sin(double <[x]>);
+ float sinf(float <[x]>);
+ double cos(double <[x]>);
+ float cosf(float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double sin(<[x]>)
+ double <[x]>;
+ float sinf(<[x]>)
+ float <[x]>;
+
+ double cos(<[x]>)
+ double <[x]>;
+ float cosf(<[x]>)
+ float <[x]>;
+
+DESCRIPTION
+ <<sin>> and <<cos>> compute (respectively) the sine and cosine
+ of the argument <[x]>. Angles are specified in radians.
+
+ <<sinf>> and <<cosf>> are identical, save that they take and
+ return <<float>> values.
+
+
+RETURNS
+ The sine or cosine of <[x]> is returned.
+
+PORTABILITY
+ <<sin>> and <<cos>> are ANSI C.
+ <<sinf>> and <<cosf>> are extensions.
+
+QUICKREF
+ sin ansi pure
+ sinf - pure
+*/
+
+/* sin(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ * __kernel_sin ... sine function on [-pi/4,pi/4]
+ * __kernel_cos ... cose function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2 ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double sin(double x)
+#else
+ double sin(x)
+ double x;
+#endif
+{
+ double y[2],z=0.0;
+ int32_t n,ix;
+
+ /* High word of x. */
+ GET_HIGH_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
+
+ /* sin(Inf or NaN) is NaN */
+ else if (ix>=0x7ff00000) return x-x;
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2(x,y);
+ switch(n&3) {
+ case 0: return __kernel_sin(y[0],y[1],1);
+ case 1: return __kernel_cos(y[0],y[1]);
+ case 2: return -__kernel_sin(y[0],y[1],1);
+ default:
+ return -__kernel_cos(y[0],y[1]);
+ }
+ }
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/libjava/classpath/native/fdlibm/s_tan.c b/libjava/classpath/native/fdlibm/s_tan.c
new file mode 100644
index 00000000000..20995fcbdee
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/s_tan.c
@@ -0,0 +1,114 @@
+
+/* @(#)s_tan.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+
+/*
+
+FUNCTION
+ <<tan>>, <<tanf>>---tangent
+
+INDEX
+tan
+INDEX
+tanf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double tan(double <[x]>);
+ float tanf(float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double tan(<[x]>)
+ double <[x]>;
+
+ float tanf(<[x]>)
+ float <[x]>;
+
+
+DESCRIPTION
+<<tan>> computes the tangent of the argument <[x]>.
+Angles are specified in radians.
+
+<<tanf>> is identical, save that it takes and returns <<float>> values.
+
+RETURNS
+The tangent of <[x]> is returned.
+
+PORTABILITY
+<<tan>> is ANSI. <<tanf>> is an extension.
+*/
+
+/* tan(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ * __kernel_tan ... tangent function on [-pi/4,pi/4]
+ * __ieee754_rem_pio2 ... argument reduction routine
+ *
+ * Method.
+ * Let S,C and T denote the sin, cos and tan respectively on
+ * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
+ * in [-pi/4 , +pi/4], and let n = k mod 4.
+ * We have
+ *
+ * n sin(x) cos(x) tan(x)
+ * ----------------------------------------------------------
+ * 0 S C T
+ * 1 C -S -1/T
+ * 2 -S -C T
+ * 3 -C S -1/T
+ * ----------------------------------------------------------
+ *
+ * Special cases:
+ * Let trig be any of sin, cos, or tan.
+ * trig(+-INF) is NaN, with signals;
+ * trig(NaN) is that NaN;
+ *
+ * Accuracy:
+ * TRIG(x) returns trig(x) nearly rounded
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double tan(double x)
+#else
+ double tan(x)
+ double x;
+#endif
+{
+ double y[2],z=0.0;
+ int32_t n,ix;
+
+ /* High word of x. */
+ GET_HIGH_WORD(ix,x);
+
+ /* |x| ~< pi/4 */
+ ix &= 0x7fffffff;
+ if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);
+
+ /* tan(Inf or NaN) is NaN */
+ else if (ix>=0x7ff00000) return x-x; /* NaN */
+
+ /* argument reduction needed */
+ else {
+ n = __ieee754_rem_pio2(x,y);
+ return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
+ -1 -- n odd */
+ }
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/libjava/classpath/native/fdlibm/sf_fabs.c b/libjava/classpath/native/fdlibm/sf_fabs.c
new file mode 100644
index 00000000000..34f88afc4e6
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/sf_fabs.c
@@ -0,0 +1,47 @@
+/* sf_fabs.c -- float version of s_fabs.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * fabsf(x) returns the absolute value of x.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+ float fabsf(float x)
+#else
+ float fabsf(x)
+ float x;
+#endif
+{
+ uint32_t ix;
+ GET_FLOAT_WORD(ix,x);
+ SET_FLOAT_WORD(x,ix&0x7fffffff);
+ return x;
+}
+
+#ifdef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double fabs(double x)
+#else
+ double fabs(x)
+ double x;
+#endif
+{
+ return (double) fabsf((float) x);
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/sf_rint.c b/libjava/classpath/native/fdlibm/sf_rint.c
new file mode 100644
index 00000000000..f442072874e
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/sf_rint.c
@@ -0,0 +1,80 @@
+/* sf_rint.c -- float version of s_rint.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const float
+#else
+static float
+#endif
+TWO23[2]={
+ 8.3886080000e+06, /* 0x4b000000 */
+ -8.3886080000e+06, /* 0xcb000000 */
+};
+
+#ifdef __STDC__
+ float rintf(float x)
+#else
+ float rintf(x)
+ float x;
+#endif
+{
+ int32_t i0,j0,sx;
+ uint32_t i,i1;
+ float w,t;
+ GET_FLOAT_WORD(i0,x);
+ sx = (i0>>31)&1;
+ j0 = ((i0>>23)&0xff)-0x7f;
+ if(j0<23) {
+ if(j0<0) {
+ if((i0&0x7fffffff)==0) return x;
+ i1 = (i0&0x07fffff);
+ i0 &= 0xfff00000;
+ i0 |= ((i1|-i1)>>9)&0x400000;
+ SET_FLOAT_WORD(x,i0);
+ w = TWO23[sx]+x;
+ t = w-TWO23[sx];
+ GET_FLOAT_WORD(i0,t);
+ SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
+ return t;
+ } else {
+ i = (0x007fffff)>>j0;
+ if((i0&i)==0) return x; /* x is integral */
+ i>>=1;
+ if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
+ }
+ } else {
+ if(j0==0x80) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ }
+ SET_FLOAT_WORD(x,i0);
+ w = TWO23[sx]+x;
+ return w-TWO23[sx];
+}
+
+#ifdef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double rint(double x)
+#else
+ double rint(x)
+ double x;
+#endif
+{
+ return (double) rintf((float) x);
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/strtod.c b/libjava/classpath/native/fdlibm/strtod.c
new file mode 100644
index 00000000000..b3e09124721
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/strtod.c
@@ -0,0 +1,719 @@
+/*
+FUNCTION
+ <<strtod>>, <<strtodf>>---string to double or float
+
+INDEX
+ strtod
+INDEX
+ _strtod_r
+INDEX
+ strtodf
+
+ANSI_SYNOPSIS
+ #include <stdlib.h>
+ double strtod(const char *<[str]>, char **<[tail]>);
+ float strtodf(const char *<[str]>, char **<[tail]>);
+
+ double _strtod_r(void *<[reent]>,
+ const char *<[str]>, char **<[tail]>);
+
+TRAD_SYNOPSIS
+ #include <stdlib.h>
+ double strtod(<[str]>,<[tail]>)
+ char *<[str]>;
+ char **<[tail]>;
+
+ float strtodf(<[str]>,<[tail]>)
+ char *<[str]>;
+ char **<[tail]>;
+
+ double _strtod_r(<[reent]>,<[str]>,<[tail]>)
+ char *<[reent]>;
+ char *<[str]>;
+ char **<[tail]>;
+
+DESCRIPTION
+ The function <<strtod>> parses the character string <[str]>,
+ producing a substring which can be converted to a double
+ value. The substring converted is the longest initial
+ subsequence of <[str]>, beginning with the first
+ non-whitespace character, that has the format:
+ .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>]
+ The substring contains no characters if <[str]> is empty, consists
+ entirely of whitespace, or if the first non-whitespace
+ character is something other than <<+>>, <<->>, <<.>>, or a
+ digit. If the substring is empty, no conversion is done, and
+ the value of <[str]> is stored in <<*<[tail]>>>. Otherwise,
+ the substring is converted, and a pointer to the final string
+ (which will contain at least the terminating null character of
+ <[str]>) is stored in <<*<[tail]>>>. If you want no
+ assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>.
+ <<strtodf>> is identical to <<strtod>> except for its return type.
+
+ This implementation returns the nearest machine number to the
+ input decimal string. Ties are broken by using the IEEE
+ round-even rule.
+
+ The alternate function <<_strtod_r>> is a reentrant version.
+ The extra argument <[reent]> is a pointer to a reentrancy structure.
+
+RETURNS
+ <<strtod>> returns the converted substring value, if any. If
+ no conversion could be performed, 0 is returned. If the
+ correct value is out of the range of representable values,
+ plus or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is
+ stored in errno. If the correct value would cause underflow, 0
+ is returned and <<ERANGE>> is stored in errno.
+
+Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
+<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
+*/
+
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991 by AT&T.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to
+ David M. Gay
+ AT&T Bell Laboratories, Room 2C-463
+ 600 Mountain Avenue
+ Murray Hill, NJ 07974-2070
+ U.S.A.
+ dmg@research.att.com or research!dmg
+ */
+
+#include <string.h>
+#include <float.h>
+#include <errno.h>
+#include "mprec.h"
+
+double
+_DEFUN (_strtod_r, (ptr, s00, se),
+ struct _Jv_reent *ptr _AND
+ _CONST char *s00 _AND
+ char **se)
+{
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, e1, esign, i, j,
+ k, nd, nd0, nf, nz, nz0, sign;
+ int digits = 0; /* Number of digits found in fraction part. */
+ long e;
+ _CONST char *s, *s0, *s1;
+ double aadj, aadj1, adj;
+ long L;
+ unsigned long y, z;
+ union double_union rv, rv0;
+
+ _Jv_Bigint *bb = NULL, *bb1, *bd = NULL, *bd0, *bs = NULL, *delta = NULL;
+ sign = nz0 = nz = 0;
+ rv.d = 0.;
+ for (s = s00;; s++)
+ switch (*s)
+ {
+ case '-':
+ sign = 1;
+ /* no break */
+ case '+':
+ if (*++s)
+ goto break2;
+ /* no break */
+ case 0:
+ s = s00;
+ goto ret;
+ case '\t':
+ case '\n':
+ case '\v':
+ case '\f':
+ case '\r':
+ case ' ':
+ continue;
+ default:
+ goto break2;
+ }
+break2:
+ if (*s == '0')
+ {
+ digits++;
+ nz0 = 1;
+ while (*++s == '0')
+ digits++;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ {
+ digits++;
+ if (nd < 9)
+ y = 10 * y + c - '0';
+ else if (nd < 16)
+ z = 10 * z + c - '0';
+ }
+ nd0 = nd;
+ if (c == '.')
+ {
+ c = *++s;
+ if (!nd)
+ {
+ for (; c == '0'; c = *++s)
+ {
+ digits++;
+ nz++;
+ }
+ if (c > '0' && c <= '9')
+ {
+ digits++;
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for (; c >= '0' && c <= '9'; c = *++s)
+ {
+ digits++;
+ have_dig:
+ nz++;
+ if (c -= '0')
+ {
+ nf += nz;
+ for (i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10 * y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10 * z + c;
+ nz = 0;
+ }
+ }
+ }
+dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E')
+ {
+ if (!nd && !nz && !nz0)
+ {
+ s = s00;
+ goto ret;
+ }
+ s00 = s;
+ esign = 0;
+ switch (c = *++s)
+ {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9')
+ {
+ while (c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9')
+ {
+ e = c - '0';
+ s1 = s;
+ while ((c = *++s) >= '0' && c <= '9')
+ e = 10 * e + c - '0';
+ if (s - s1 > 8)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 9999999L;
+ if (esign)
+ e = -e;
+ }
+ }
+ else
+ {
+ /* No exponent after an 'E' : that's an error. */
+ ptr->_errno = EINVAL;
+ e = 0;
+ s = s00;
+ goto ret;
+ }
+ }
+ if (!nd)
+ {
+ if (!nz && !nz0)
+ s = s00;
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ rv.d = y;
+ if (k > 9)
+ rv.d = tens[k - 9] * rv.d + z;
+ bd0 = 0;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+ && FLT_ROUNDS == 1
+#endif
+ )
+ {
+ if (!e)
+ goto ret;
+ if (e > 0)
+ {
+ if (e <= Ten_pmax)
+ {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+ /* rv.d = */ rounded_product (rv.d, tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i)
+ {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e -= i;
+ rv.d *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ word0 (rv) -= P * Exp_msk1;
+ /* rv.d = */ rounded_product (rv.d, tens[e]);
+ if ((word0 (rv) & Exp_mask)
+ > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
+ goto ovfl;
+ word0 (rv) += P * Exp_msk1;
+#else
+ /* rv.d = */ rounded_product (rv.d, tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax)
+ {
+ /* rv.d = */ rounded_quotient (rv.d, tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+ /* Get starting approximation = rv.d * 10**e1 */
+
+ if (e1 > 0)
+ {
+ if ((i = e1 & 15))
+ rv.d *= tens[i];
+
+ if (e1 &= ~15)
+ {
+ if (e1 > DBL_MAX_10_EXP)
+ {
+ ovfl:
+ ptr->_errno = ERANGE;
+
+ /* Force result to IEEE infinity. */
+ word0 (rv) = Exp_mask;
+ word1 (rv) = 0;
+
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+ if (e1 >>= 4)
+ {
+ for (j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv.d *= bigtens[j];
+ /* The last multiplication could overflow. */
+ word0 (rv) -= P * Exp_msk1;
+ rv.d *= bigtens[j];
+ if ((z = word0 (rv) & Exp_mask)
+ > Exp_msk1 * (DBL_MAX_EXP + Bias - P))
+ goto ovfl;
+ if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
+ {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ word0 (rv) = Big0;
+#ifndef _DOUBLE_IS_32BITS
+ word1 (rv) = Big1;
+#endif
+ }
+ else
+ word0 (rv) += P * Exp_msk1;
+ }
+
+ }
+ }
+ else if (e1 < 0)
+ {
+ e1 = -e1;
+ if ((i = e1 & 15))
+ rv.d /= tens[i];
+ if (e1 &= ~15)
+ {
+ e1 >>= 4;
+ if (e1 >= 1 << n_bigtens)
+ goto undfl;
+ for (j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv.d *= tinytens[j];
+ /* The last multiplication could underflow. */
+ rv0.d = rv.d;
+ rv.d *= tinytens[j];
+ if (!rv.d)
+ {
+ rv.d = 2. * rv0.d;
+ rv.d *= tinytens[j];
+ if (!rv.d)
+ {
+ undfl:
+ rv.d = 0.;
+ ptr->_errno = ERANGE;
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+#ifndef _DOUBLE_IS_32BITS
+ word0 (rv) = Tiny0;
+ word1 (rv) = Tiny1;
+#else
+ word0 (rv) = Tiny1;
+#endif
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b (ptr, s0, nd0, nd, y);
+
+ for (;;)
+ {
+ bd = Balloc (ptr, bd0->_k);
+ Bcopy (bd, bd0);
+ bb = d2b (ptr, rv.d, &bbe, &bbbits); /* rv.d = bb * 2^bbe */
+ bs = i2b (ptr, 1);
+
+ if (e >= 0)
+ {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else
+ {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4 * P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else
+ i = bbe + bbbits - 1; /* logb(rv.d) */
+ if (i < Emin) /* denormal */
+ j = bbe + (P - Emin);
+ else
+ j = P + 1 - bbbits;
+#endif
+ bb2 += j;
+ bd2 += j;
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0)
+ {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0)
+ {
+ bs = pow5mult (ptr, bs, bb5);
+ bb1 = mult (ptr, bs, bb);
+ Bfree (ptr, bb);
+ bb = bb1;
+ }
+ if (bb2 > 0)
+ bb = lshift (ptr, bb, bb2);
+ if (bd5 > 0)
+ bd = pow5mult (ptr, bd, bd5);
+ if (bd2 > 0)
+ bd = lshift (ptr, bd, bd2);
+ if (bs2 > 0)
+ bs = lshift (ptr, bs, bs2);
+ delta = diff (ptr, bb, bd);
+ dsign = delta->_sign;
+ delta->_sign = 0;
+ i = cmp (delta, bs);
+ if (i < 0)
+ {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || word1 (rv) || word0 (rv) & Bndry_mask)
+ break;
+ delta = lshift (ptr, delta, Log2P);
+ if (cmp (delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0)
+ {
+ /* exactly half-way between */
+ if (dsign)
+ {
+ if ((word0 (rv) & Bndry_mask1) == Bndry_mask1
+ && word1 (rv) == 0xffffffff)
+ {
+ /*boundary case -- increment exponent*/
+ word0 (rv) = (word0 (rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ ;
+#ifndef _DOUBLE_IS_32BITS
+ word1 (rv) = 0;
+#endif
+ break;
+ }
+ }
+ else if (!(word0 (rv) & Bndry_mask) && !word1 (rv))
+ {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow
+ L = word0 (rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+ if (L <= Exp_msk1)
+#endif
+ goto undfl;
+ L -= Exp_msk1;
+#else
+ L = (word0 (rv) & Exp_mask) - Exp_msk1;
+#endif
+ word0 (rv) = L | Bndry_mask1;
+#ifndef _DOUBLE_IS_32BITS
+ word1 (rv) = 0xffffffff;
+#endif
+#ifdef IBM
+ goto cont;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(word1 (rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ rv.d += ulp (rv.d);
+#ifndef ROUND_BIASED
+ else
+ {
+ rv.d -= ulp (rv.d);
+#ifndef Sudden_Underflow
+ if (!rv.d)
+ goto undfl;
+#endif
+ }
+#endif
+ break;
+ }
+ if ((aadj = ratio (delta, bs)) <= 2.)
+ {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (word1 (rv) || word0 (rv) & Bndry_mask)
+ {
+#ifndef Sudden_Underflow
+ if (word1 (rv) == Tiny1 && !word0 (rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else
+ {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2. / FLT_RADIX)
+ aadj = 1. / FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else
+ {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch (FLT_ROUNDS)
+ {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (FLT_ROUNDS == 0)
+ aadj1 += 0.5;
+#endif
+ }
+ y = word0 (rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1))
+ {
+ rv0.d = rv.d;
+ word0 (rv) -= P * Exp_msk1;
+ adj = aadj1 * ulp (rv.d);
+ rv.d += adj;
+ if ((word0 (rv) & Exp_mask) >=
+ Exp_msk1 * (DBL_MAX_EXP + Bias - P))
+ {
+ if (word0 (rv0) == Big0 && word1 (rv0) == Big1)
+ goto ovfl;
+#ifdef _DOUBLE_IS_32BITS
+ word0 (rv) = Big1;
+#else
+ word0 (rv) = Big0;
+ word1 (rv) = Big1;
+#endif
+ goto cont;
+ }
+ else
+ word0 (rv) += P * Exp_msk1;
+ }
+ else
+ {
+#ifdef Sudden_Underflow
+ if ((word0 (rv) & Exp_mask) <= P * Exp_msk1)
+ {
+ rv0.d = rv.d;
+ word0 (rv) += P * Exp_msk1;
+ adj = aadj1 * ulp (rv.d);
+ rv.d += adj;
+#ifdef IBM
+ if ((word0 (rv) & Exp_mask) < P * Exp_msk1)
+#else
+ if ((word0 (rv) & Exp_mask) <= P * Exp_msk1)
+#endif
+ {
+ if (word0 (rv0) == Tiny0
+ && word1 (rv0) == Tiny1)
+ goto undfl;
+ word0 (rv) = Tiny0;
+ word1 (rv) = Tiny1;
+ goto cont;
+ }
+ else
+ word0 (rv) -= P * Exp_msk1;
+ }
+ else
+ {
+ adj = aadj1 * ulp (rv.d);
+ rv.d += adj;
+ }
+#else
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv.d + adj in some half-way cases.
+ * If rv.d * ulp(rv.d) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P - 1) * Exp_msk1 && aadj >= 1.)
+ {
+ aadj1 = (double) (int) (aadj + 0.5);
+ if (!dsign)
+ aadj1 = -aadj1;
+ }
+ adj = aadj1 * ulp (rv.d);
+ rv.d += adj;
+#endif
+ }
+ z = word0 (rv) & Exp_mask;
+ if (y == z)
+ {
+ /* Can we stop now? */
+ L = aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || word1 (rv) || word0 (rv) & Bndry_mask)
+ {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999 / FLT_RADIX)
+ break;
+ }
+ cont:
+ Bfree (ptr, bb);
+ Bfree (ptr, bd);
+ Bfree (ptr, bs);
+ Bfree (ptr, delta);
+ }
+retfree:
+ Bfree (ptr, bb);
+ Bfree (ptr, bd);
+ Bfree (ptr, bs);
+ Bfree (ptr, bd0);
+ Bfree (ptr, delta);
+ret:
+ if (se)
+ *se = (char *) s;
+ if (digits == 0)
+ ptr->_errno = EINVAL;
+ return sign ? -rv.d : rv.d;
+}
+
diff --git a/libjava/classpath/native/fdlibm/w_acos.c b/libjava/classpath/native/fdlibm/w_acos.c
new file mode 100644
index 00000000000..c9ca99c4041
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/w_acos.c
@@ -0,0 +1,118 @@
+
+/* @(#)w_acos.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+ <<acos>>, <<acosf>>---arc cosine
+
+INDEX
+ acos
+INDEX
+ acosf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double acos(double <[x]>);
+ float acosf(float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double acos(<[x]>)
+ double <[x]>;
+
+ float acosf(<[x]>)
+ float <[x]>;
+
+
+
+DESCRIPTION
+
+ <<acos>> computes the inverse cosine (arc cosine) of the input value.
+ Arguments to <<acos>> must be in the range @minus{}1 to 1.
+
+ <<acosf>> is identical to <<acos>>, except that it performs
+ its calculations on <<floats>>.
+
+RETURNS
+ @ifinfo
+ <<acos>> and <<acosf>> return values in radians, in the range of 0 to pi.
+ @end ifinfo
+ @tex
+ <<acos>> and <<acosf>> return values in radians, in the range of <<0>> to $\pi$.
+ @end tex
+
+ If <[x]> is not between @minus{}1 and 1, the returned value is NaN
+ (not a number) the global variable <<errno>> is set to <<EDOM>>, and a
+ <<DOMAIN error>> message is sent as standard error output.
+
+ You can modify error handling for these functions using <<matherr>>.
+
+
+QUICKREF ANSI SVID POSIX RENTRANT
+ acos y,y,y,m
+ acosf n,n,n,m
+
+MATHREF
+ acos, [-1,1], acos(arg),,,
+ acos, NAN, arg,DOMAIN,EDOM
+
+MATHREF
+ acosf, [-1,1], acosf(arg),,,
+ acosf, NAN, argf,DOMAIN,EDOM
+
+*/
+
+/*
+ * wrap_acos(x)
+ */
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double acos(double x) /* wrapper acos */
+#else
+ double acos(x) /* wrapper acos */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_acos(x);
+#else
+ double z;
+ struct exception exc;
+ z = __ieee754_acos(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(fabs(x)>1.0) {
+ /* acos(|x|>1) */
+ exc.type = DOMAIN;
+ exc.name = "acos";
+ exc.err = 0;
+ exc.arg1 = exc.arg2 = x;
+ exc.retval = 0.0;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ } else
+ return z;
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/w_asin.c b/libjava/classpath/native/fdlibm/w_asin.c
new file mode 100644
index 00000000000..f6cb271d392
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/w_asin.c
@@ -0,0 +1,121 @@
+
+/* @(#)w_asin.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/*
+FUNCTION
+ <<asin>>, <<asinf>>---arc sine
+
+INDEX
+ asin
+INDEX
+ asinf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double asin(double <[x]>);
+ float asinf(float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double asin(<[x]>)
+ double <[x]>;
+
+ float asinf(<[x]>)
+ float <[x]>;
+
+
+DESCRIPTION
+
+<<asin>> computes the inverse sine (arc sine) of the argument <[x]>.
+Arguments to <<asin>> must be in the range @minus{}1 to 1.
+
+<<asinf>> is identical to <<asin>>, other than taking and
+returning floats.
+
+You can modify error handling for these routines using <<matherr>>.
+
+RETURNS
+@ifinfo
+<<asin>> returns values in radians, in the range of -pi/2 to pi/2.
+@end ifinfo
+@tex
+<<asin>> returns values in radians, in the range of $-\pi/2$ to $\pi/2$.
+@end tex
+
+If <[x]> is not in the range @minus{}1 to 1, <<asin>> and <<asinf>>
+return NaN (not a number), set the global variable <<errno>> to
+<<EDOM>>, and issue a <<DOMAIN error>> message.
+
+You can change this error treatment using <<matherr>>.
+
+QUICKREF ANSI SVID POSIX RENTRANT
+ asin y,y,y,m
+ asinf n,n,n,m
+
+MATHREF
+ asin, -1<=arg<=1, asin(arg),,,
+ asin, NAN, arg,EDOM, DOMAIN
+
+MATHREF
+ asinf, -1<=arg<=1, asin(arg),,,
+ asinf, NAN, arg,EDOM, DOMAIN
+
+
+*/
+
+/*
+ * wrapper asin(x)
+ */
+
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double asin(double x) /* wrapper asin */
+#else
+ double asin(x) /* wrapper asin */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_asin(x);
+#else
+ double z;
+ struct exception exc;
+ z = __ieee754_asin(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(fabs(x)>1.0) {
+ /* asin(|x|>1) */
+ exc.type = DOMAIN;
+ exc.name = "asin";
+ exc.err = 0;
+ exc.arg1 = exc.arg2 = x;
+ exc.retval = 0.0;
+ if(_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ } else
+ return z;
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/w_atan2.c b/libjava/classpath/native/fdlibm/w_atan2.c
new file mode 100644
index 00000000000..91742c72b91
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/w_atan2.c
@@ -0,0 +1,117 @@
+
+/* @(#)w_atan2.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/*
+FUNCTION
+ <<atan2>>, <<atan2f>>---arc tangent of y/x
+
+INDEX
+ atan2
+INDEX
+ atan2f
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double atan2(double <[y]>,double <[x]>);
+ float atan2f(float <[y]>,float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double atan2(<[y]>,<[x]>);
+ double <[y]>;
+ double <[x]>;
+
+ float atan2f(<[y]>,<[x]>);
+ float <[y]>;
+ float <[x]>;
+
+DESCRIPTION
+
+<<atan2>> computes the inverse tangent (arc tangent) of <[y]>/<[x]>.
+<<atan2>> produces the correct result even for angles near
+@ifinfo
+pi/2 or -pi/2
+@end ifinfo
+@tex
+$\pi/2$ or $-\pi/2$
+@end tex
+(that is, when <[x]> is near 0).
+
+<<atan2f>> is identical to <<atan2>>, save that it takes and returns
+<<float>>.
+
+RETURNS
+<<atan2>> and <<atan2f>> return a value in radians, in the range of
+@ifinfo
+-pi to pi.
+@end ifinfo
+@tex
+$-\pi$ to $\pi$.
+@end tex
+
+If both <[x]> and <[y]> are 0.0, <<atan2>> causes a <<DOMAIN>> error.
+
+You can modify error handling for these functions using <<matherr>>.
+
+PORTABILITY
+<<atan2>> is ANSI C. <<atan2f>> is an extension.
+
+
+*/
+
+/*
+ * wrapper atan2(y,x)
+ */
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double atan2(double y, double x) /* wrapper atan2 */
+#else
+ double atan2(y,x) /* wrapper atan2 */
+ double y,x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_atan2(y,x);
+#else
+ double z;
+ struct exception exc;
+ z = __ieee754_atan2(y,x);
+ if(_LIB_VERSION == _IEEE_||isnan(x)||isnan(y)) return z;
+ if(x==0.0&&y==0.0) {
+ /* atan2(+-0,+-0) */
+ exc.arg1 = y;
+ exc.arg2 = x;
+ exc.type = DOMAIN;
+ exc.name = "atan2";
+ exc.err = 0;
+ exc.retval = 0.0;
+ if(_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ } else
+ return z;
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/w_exp.c b/libjava/classpath/native/fdlibm/w_exp.c
new file mode 100644
index 00000000000..45e087b45f9
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/w_exp.c
@@ -0,0 +1,140 @@
+
+/* @(#)w_exp.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+ <<exp>>, <<expf>>---exponential
+INDEX
+ exp
+INDEX
+ expf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double exp(double <[x]>);
+ float expf(float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double exp(<[x]>);
+ double <[x]>;
+
+ float expf(<[x]>);
+ float <[x]>;
+
+DESCRIPTION
+ <<exp>> and <<expf>> calculate the exponential of <[x]>, that is,
+ @ifinfo
+ e raised to the power <[x]> (where e
+ @end ifinfo
+ @tex
+ $e^x$ (where $e$
+ @end tex
+ is the base of the natural system of logarithms, approximately 2.71828).
+
+ You can use the (non-ANSI) function <<matherr>> to specify
+ error handling for these functions.
+
+RETURNS
+ On success, <<exp>> and <<expf>> return the calculated value.
+ If the result underflows, the returned value is <<0>>. If the
+ result overflows, the returned value is <<HUGE_VAL>>. In
+ either case, <<errno>> is set to <<ERANGE>>.
+
+PORTABILITY
+ <<exp>> is ANSI C. <<expf>> is an extension.
+
+*/
+
+/*
+ * wrapper exp(x)
+ */
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifndef _IEEE_LIBM
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */
+
+#endif
+
+#ifdef __STDC__
+ double exp(double x) /* wrapper exp */
+#else
+ double exp(x) /* wrapper exp */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_exp(x);
+#else
+ double z;
+ struct exception exc;
+ z = __ieee754_exp(x);
+ if(_LIB_VERSION == _IEEE_) return z;
+ if(finite(x)) {
+ if(x>o_threshold) {
+ /* exp(finite) overflow */
+#ifndef HUGE_VAL
+#define HUGE_VAL inf
+ double inf = 0.0;
+
+ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
+#endif
+ exc.type = OVERFLOW;
+ exc.name = "exp";
+ exc.err = 0;
+ exc.arg1 = exc.arg2 = x;
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = HUGE;
+ else
+ exc.retval = HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ } else if(x<u_threshold) {
+ /* exp(finite) underflow */
+ exc.type = UNDERFLOW;
+ exc.name = "exp";
+ exc.err = 0;
+ exc.arg1 = exc.arg2 = x;
+ exc.retval = 0.0;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ }
+ }
+ return z;
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/w_fmod.c b/libjava/classpath/native/fdlibm/w_fmod.c
new file mode 100644
index 00000000000..b6b36cb76ab
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/w_fmod.c
@@ -0,0 +1,107 @@
+
+/* @(#)w_fmod.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+<<fmod>>, <<fmodf>>---floating-point remainder (modulo)
+
+INDEX
+fmod
+INDEX
+fmodf
+
+ANSI_SYNOPSIS
+#include <math.h>
+double fmod(double <[x]>, double <[y]>)
+float fmodf(float <[x]>, float <[y]>)
+
+TRAD_SYNOPSIS
+#include <math.h>
+double fmod(<[x]>, <[y]>)
+double (<[x]>, <[y]>);
+
+float fmodf(<[x]>, <[y]>)
+float (<[x]>, <[y]>);
+
+DESCRIPTION
+The <<fmod>> and <<fmodf>> functions compute the floating-point
+remainder of <[x]>/<[y]> (<[x]> modulo <[y]>).
+
+RETURNS
+The <<fmod>> function returns the value
+@ifinfo
+<[x]>-<[i]>*<[y]>,
+@end ifinfo
+@tex
+$x-i\times y$,
+@end tex
+for the largest integer <[i]> such that, if <[y]> is nonzero, the
+result has the same sign as <[x]> and magnitude less than the
+magnitude of <[y]>.
+
+<<fmod(<[x]>,0)>> returns NaN, and sets <<errno>> to <<EDOM>>.
+
+You can modify error treatment for these functions using <<matherr>>.
+
+PORTABILITY
+<<fmod>> is ANSI C. <<fmodf>> is an extension.
+*/
+
+/*
+ * wrapper fmod(x,y)
+ */
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double fmod(double x, double y) /* wrapper fmod */
+#else
+ double fmod(x,y) /* wrapper fmod */
+ double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_fmod(x,y);
+#else
+ double z;
+ struct exception exc;
+ z = __ieee754_fmod(x,y);
+ if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z;
+ if(y==0.0) {
+ /* fmod(x,0) */
+ exc.type = DOMAIN;
+ exc.name = "fmod";
+ exc.arg1 = x;
+ exc.arg2 = y;
+ exc.err = 0;
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = x;
+ else
+ exc.retval = 0.0/0.0;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ } else
+ return z;
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/w_log.c b/libjava/classpath/native/fdlibm/w_log.c
new file mode 100644
index 00000000000..dcc8b9762ec
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/w_log.c
@@ -0,0 +1,115 @@
+
+/* @(#)w_log.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+ <<log>>, <<logf>>---natural logarithms
+
+INDEX
+ log
+INDEX
+ logf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double log(double <[x]>);
+ float logf(float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double log(<[x]>);
+ double <[x]>;
+
+ float logf(<[x]>);
+ float <[x]>;
+
+DESCRIPTION
+Return the natural logarithm of <[x]>, that is, its logarithm base e
+(where e is the base of the natural system of logarithms, 2.71828@dots{}).
+<<log>> and <<logf>> are identical save for the return and argument types.
+
+You can use the (non-ANSI) function <<matherr>> to specify error
+handling for these functions.
+
+RETURNS
+Normally, returns the calculated value. When <[x]> is zero, the
+returned value is <<-HUGE_VAL>> and <<errno>> is set to <<ERANGE>>.
+When <[x]> is negative, the returned value is <<-HUGE_VAL>> and
+<<errno>> is set to <<EDOM>>. You can control the error behavior via
+<<matherr>>.
+
+PORTABILITY
+<<log>> is ANSI, <<logf>> is an extension.
+*/
+
+/*
+ * wrapper log(x)
+ */
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double log(double x) /* wrapper log */
+#else
+ double log(x) /* wrapper log */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_log(x);
+#else
+ double z;
+ struct exception exc;
+ z = __ieee754_log(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z;
+#ifndef HUGE_VAL
+#define HUGE_VAL inf
+ double inf = 0.0;
+
+ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
+#endif
+ exc.name = "log";
+ exc.err = 0;
+ exc.arg1 = x;
+ exc.arg2 = x;
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = -HUGE;
+ else
+ exc.retval = -HUGE_VAL;
+ if(x==0.0) {
+ /* log(0) */
+ exc.type = SING;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ } else {
+ /* log(x<0) */
+ exc.type = DOMAIN;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/fdlibm/w_pow.c b/libjava/classpath/native/fdlibm/w_pow.c
new file mode 100644
index 00000000000..3df099a1714
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/w_pow.c
@@ -0,0 +1,231 @@
+
+
+/* @(#)w_pow.c 5.2 93/10/01 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+ <<pow>>, <<powf>>---x to the power y
+INDEX
+ pow
+INDEX
+ powf
+
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double pow(double <[x]>, double <[y]>);
+ float pow(float <[x]>, float <[y]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double pow(<[x]>, <[y]>);
+ double <[x]>, <[y]>;
+
+ float pow(<[x]>, <[y]>);
+ float <[x]>, <[y]>;
+
+DESCRIPTION
+ <<pow>> and <<powf>> calculate <[x]> raised to the exp1.0nt <[y]>.
+ @tex
+ (That is, $x^y$.)
+ @end tex
+
+RETURNS
+ On success, <<pow>> and <<powf>> return the value calculated.
+
+ When the argument values would produce overflow, <<pow>>
+ returns <<HUGE_VAL>> and set <<errno>> to <<ERANGE>>. If the
+ argument <[x]> passed to <<pow>> or <<powf>> is a negative
+ noninteger, and <[y]> is also not an integer, then <<errno>>
+ is set to <<EDOM>>. If <[x]> and <[y]> are both 0, then
+ <<pow>> and <<powf>> return <<1>>.
+
+ You can modify error handling for these functions using <<matherr>>.
+
+PORTABILITY
+ <<pow>> is ANSI C. <<powf>> is an extension. */
+
+/*
+ * wrapper pow(x,y) return x**y
+ */
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double pow(double x, double y) /* wrapper pow */
+#else
+ double pow(x,y) /* wrapper pow */
+ double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_pow(x,y);
+#else
+ double z;
+#ifndef HUGE_VAL
+#define HUGE_VAL inf
+ double inf = 0.0;
+
+ SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
+#endif
+ struct exception exc;
+ z=__ieee754_pow(x,y);
+ if(_LIB_VERSION == _IEEE_|| isnan(y)) return z;
+ if(isnan(x)) {
+ if(y==0.0) {
+ /* pow(NaN,0.0) */
+ /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
+ exc.type = DOMAIN;
+ exc.name = "pow";
+ exc.err = 0;
+ exc.arg1 = x;
+ exc.arg2 = y;
+ exc.retval = x;
+ if (_LIB_VERSION == _IEEE_ ||
+ _LIB_VERSION == _POSIX_) exc.retval = 1.0;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ } else
+ return z;
+ }
+ if(x==0.0){
+ if(y==0.0) {
+ /* pow(0.0,0.0) */
+ /* error only if _LIB_VERSION == _SVID_ */
+ exc.type = DOMAIN;
+ exc.name = "pow";
+ exc.err = 0;
+ exc.arg1 = x;
+ exc.arg2 = y;
+ exc.retval = 0.0;
+ if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ }
+ if(finite(y)&&y<0.0) {
+ /* 0**neg */
+ exc.type = DOMAIN;
+ exc.name = "pow";
+ exc.err = 0;
+ exc.arg1 = x;
+ exc.arg2 = y;
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = 0.0;
+ else
+ exc.retval = -HUGE_VAL;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ }
+ return z;
+ }
+ if(!finite(z)) {
+ if(finite(x)&&finite(y)) {
+ if(isnan(z)) {
+ /* neg**non-integral */
+ exc.type = DOMAIN;
+ exc.name = "pow";
+ exc.err = 0;
+ exc.arg1 = x;
+ exc.arg2 = y;
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = 0.0;
+ else
+ exc.retval = 0.0/0.0; /* X/Open allow NaN */
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ } else {
+ /* pow(x,y) overflow */
+ exc.type = OVERFLOW;
+ exc.name = "pow";
+ exc.err = 0;
+ exc.arg1 = x;
+ exc.arg2 = y;
+ if (_LIB_VERSION == _SVID_) {
+ exc.retval = HUGE;
+ y *= 0.5;
+ if(x<0.0&&rint(y)!=y) exc.retval = -HUGE;
+ } else {
+ exc.retval = HUGE_VAL;
+ y *= 0.5;
+ if(x<0.0&&rint(y)!=y) exc.retval = -HUGE_VAL;
+ }
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ }
+ }
+ }
+ if(z==0.0&&finite(x)&&finite(y)) {
+ /* pow(x,y) underflow */
+ exc.type = UNDERFLOW;
+ exc.name = "pow";
+ exc.err = 0;
+ exc.arg1 = x;
+ exc.arg2 = y;
+ exc.retval = 0.0;
+ if (_LIB_VERSION == _POSIX_)
+ errno = ERANGE;
+ else if (!matherr(&exc)) {
+ errno = ERANGE;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ }
+ return z;
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libjava/classpath/native/fdlibm/w_remainder.c b/libjava/classpath/native/fdlibm/w_remainder.c
new file mode 100644
index 00000000000..a06be0e7b30
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/w_remainder.c
@@ -0,0 +1,119 @@
+
+/* @(#)w_remainder.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+<<rint>>, <<rintf>>, <<remainder>>, <<remainderf>>---round and remainder
+INDEX
+ rint
+INDEX
+ rintf
+INDEX
+ remainder
+INDEX
+ remainderf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double rint(double <[x]>);
+ float rintf(float <[x]>);
+ double remainder(double <[x]>, double <[y]>);
+ float remainderf(float <[x]>, float <[y]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double rint(<[x]>)
+ double <[x]>;
+ float rintf(<[x]>)
+ float <[x]>;
+ double remainder(<[x]>,<[y]>)
+ double <[x]>, <[y]>;
+ float remainderf(<[x]>,<[y]>)
+ float <[x]>, <[y]>;
+
+DESCRIPTION
+<<rint>> and <<rintf>> returns their argument rounded to the nearest
+integer. <<remainder>> and <<remainderf>> find the remainder of
+<[x]>/<[y]>; this value is in the range -<[y]>/2 .. +<[y]>/2.
+
+RETURNS
+<<rint>> and <<remainder>> return the integer result as a double.
+
+PORTABILITY
+<<rint>> and <<remainder>> are System V release 4. <<rintf>> and
+<<remainderf>> are extensions.
+
+*/
+
+/*
+ * wrapper remainder(x,p)
+ */
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double remainder(double x, double y) /* wrapper remainder */
+#else
+ double remainder(x,y) /* wrapper remainder */
+ double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_remainder(x,y);
+#else
+ double z;
+ struct exception exc;
+ z = __ieee754_remainder(x,y);
+ if(_LIB_VERSION == _IEEE_ || isnan(y)) return z;
+ if(y==0.0) {
+ /* remainder(x,0) */
+ exc.type = DOMAIN;
+ exc.name = "remainder";
+ exc.err = 0;
+ exc.arg1 = x;
+ exc.arg2 = y;
+ exc.retval = 0.0/0.0;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ } else
+ return z;
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libjava/classpath/native/fdlibm/w_sqrt.c b/libjava/classpath/native/fdlibm/w_sqrt.c
new file mode 100644
index 00000000000..23a793ce74a
--- /dev/null
+++ b/libjava/classpath/native/fdlibm/w_sqrt.c
@@ -0,0 +1,93 @@
+
+/* @(#)w_sqrt.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+ <<sqrt>>, <<sqrtf>>---positive square root
+
+INDEX
+ sqrt
+INDEX
+ sqrtf
+
+ANSI_SYNOPSIS
+ #include <math.h>
+ double sqrt(double <[x]>);
+ float sqrtf(float <[x]>);
+
+TRAD_SYNOPSIS
+ #include <math.h>
+ double sqrt(<[x]>);
+ float sqrtf(<[x]>);
+
+DESCRIPTION
+ <<sqrt>> computes the positive square root of the argument.
+ You can modify error handling for this function with
+ <<matherr>>.
+
+RETURNS
+ On success, the square root is returned. If <[x]> is real and
+ positive, then the result is positive. If <[x]> is real and
+ negative, the global value <<errno>> is set to <<EDOM>> (domain error).
+
+
+PORTABILITY
+ <<sqrt>> is ANSI C. <<sqrtf>> is an extension.
+*/
+
+/*
+ * wrapper sqrt(x)
+ */
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+ double sqrt(double x) /* wrapper sqrt */
+#else
+ double sqrt(x) /* wrapper sqrt */
+ double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+ return __ieee754_sqrt(x);
+#else
+ struct exception exc;
+ double z;
+ z = __ieee754_sqrt(x);
+ if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
+ if(x<0.0) {
+ exc.type = DOMAIN;
+ exc.name = "sqrt";
+ exc.err = 0;
+ exc.arg1 = exc.arg2 = x;
+ if (_LIB_VERSION == _SVID_)
+ exc.retval = 0.0;
+ else
+ exc.retval = 0.0/0.0;
+ if (_LIB_VERSION == _POSIX_)
+ errno = EDOM;
+ else if (!matherr(&exc)) {
+ errno = EDOM;
+ }
+ if (exc.err != 0)
+ errno = exc.err;
+ return exc.retval;
+ } else
+ return z;
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/classpath/native/jni/.cvsignore b/libjava/classpath/native/jni/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/jni/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/Makefile.am b/libjava/classpath/native/jni/Makefile.am
new file mode 100644
index 00000000000..41d9a913bd1
--- /dev/null
+++ b/libjava/classpath/native/jni/Makefile.am
@@ -0,0 +1,20 @@
+## Input file for automake to generate the Makefile.in used by configure
+
+if CREATE_CORE_JNI_LIBRARIES
+ JNIDIRS = java-io java-lang java-net java-nio java-util
+endif
+
+if CREATE_GTK_PEER_LIBRARIES
+ GTKDIR = gtk-peer
+endif
+
+if CREATE_XMLJ_LIBRARY
+ XMLJDIR = xmlj
+endif
+
+SUBDIRS = classpath $(JNIDIRS) $(GTKDIR) $(XMLJDIR)
+DIST_SUBDIRS = classpath java-io java-lang java-net java-nio java-util \
+ gtk-peer xmlj
+
+all-local:
+ cd $(top_srcdir) && scripts/check_jni_methods.sh
diff --git a/libjava/classpath/native/jni/classpath/.cvsignore b/libjava/classpath/native/jni/classpath/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/classpath/Makefile.am b/libjava/classpath/native/jni/classpath/Makefile.am
new file mode 100644
index 00000000000..0171d3728e0
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/Makefile.am
@@ -0,0 +1,10 @@
+noinst_LTLIBRARIES = libclasspath.la
+
+libclasspath_la_SOURCES = jcl.c jcl.h \
+ jnilink.c jnilink.h \
+ primlib.c primlib.h \
+ native_state.c native_state.h
+
+AM_LDFLAGS = @CLASSPATH_MODULE@
+AM_CPPFLAGS = @CLASSPATH_INCLUDES@
+AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
diff --git a/libjava/classpath/native/jni/classpath/classpath_jawt.h b/libjava/classpath/native/jni/classpath/classpath_jawt.h
new file mode 100644
index 00000000000..6ff5c53355e
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/classpath_jawt.h
@@ -0,0 +1,64 @@
+/* classpath_awt.h -- libjawt's interface to the peer library
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+/*
+ * libjawt.so is linked directly to the peer library with -l. This
+ * header declares all the functions that libjawt.so needs -- X-based
+ * peer libraries wanting to support libjawt.so must implement these
+ * functions.
+ */
+
+#ifndef __classpath_jawt_h__
+#define __classpath_jawt_h__
+
+#include <jni.h>
+#include <X11/Xlib.h>
+
+#define CLASSPATH_JAWT_VERSION 0x10004
+
+jint classpath_jawt_get_awt_version ();
+Display* classpath_jawt_get_default_display (JNIEnv* env, jobject canvas);
+Drawable classpath_jawt_get_drawable (JNIEnv* env, jobject canvas);
+VisualID classpath_jawt_get_visualID (JNIEnv* env, jobject canvas);
+jint classpath_jawt_object_lock (jobject lock);
+void classpath_jawt_object_unlock (jobject lock);
+jint classpath_jawt_lock ();
+void classpath_jawt_unlock ();
+jobject classpath_jawt_create_lock ();
+void classpath_jawt_destroy_lock (jobject lock);
+
+#endif /* __classpath_jawt_h__ */
diff --git a/libjava/classpath/native/jni/classpath/jcl.c b/libjava/classpath/native/jni/classpath/jcl.c
new file mode 100644
index 00000000000..03f9b3753cc
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/jcl.c
@@ -0,0 +1,180 @@
+/* jcl.c
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <jcl.h>
+
+#ifndef __GNUC__
+#define __attribute__(x) /* nothing */
+#endif
+
+JNIEXPORT void JNICALL
+JCL_ThrowException (JNIEnv * env, const char *className, const char *errMsg)
+{
+ jclass excClass;
+ if ((*env)->ExceptionOccurred (env))
+ {
+ (*env)->ExceptionClear (env);
+ }
+ excClass = (*env)->FindClass (env, className);
+ if (excClass == NULL)
+ {
+ jclass errExcClass;
+ errExcClass =
+ (*env)->FindClass (env, "java/lang/ClassNotFoundException");
+ if (errExcClass == NULL)
+ {
+ errExcClass = (*env)->FindClass (env, "java/lang/InternalError");
+ if (errExcClass == NULL)
+ {
+ fprintf (stderr, "JCL: Utterly failed to throw exeption ");
+ fprintf (stderr, className);
+ fprintf (stderr, " with message ");
+ fprintf (stderr, errMsg);
+ return;
+ }
+ }
+ /* Removed this (more comprehensive) error string to avoid the need for
+ * a static variable or allocation of a buffer for this message in this
+ * (unlikely) error case. --Fridi.
+ *
+ * sprintf(errstr,"JCL: Failed to throw exception %s with message %s: could not find exception class.", className, errMsg);
+ */
+ (*env)->ThrowNew (env, errExcClass, className);
+ }
+ (*env)->ThrowNew (env, excClass, errMsg);
+}
+
+JNIEXPORT void *JNICALL
+JCL_malloc (JNIEnv * env, size_t size)
+{
+ void *mem = malloc (size);
+ if (mem == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/OutOfMemoryError",
+ "malloc() failed.");
+ return NULL;
+ }
+ return mem;
+}
+
+JNIEXPORT void *JNICALL
+JCL_realloc (JNIEnv * env, void *ptr, size_t size)
+{
+ ptr = realloc (ptr, size);
+ if (ptr == 0)
+ {
+ JCL_ThrowException (env, "java/lang/OutOfMemoryError",
+ "malloc() failed.");
+ return NULL;
+ }
+ return (ptr);
+}
+
+JNIEXPORT void JNICALL
+JCL_free (JNIEnv * env __attribute__ ((unused)), void *p)
+{
+ if (p != NULL)
+ {
+ free (p);
+ }
+}
+
+JNIEXPORT const char *JNICALL
+JCL_jstring_to_cstring (JNIEnv * env, jstring s)
+{
+ const char *cstr;
+ if (s == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/NullPointerException",
+ "Null string");
+ return NULL;
+ }
+ cstr = (const char *) (*env)->GetStringUTFChars (env, s, NULL);
+ if (cstr == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "GetStringUTFChars() failed.");
+ return NULL;
+ }
+ return cstr;
+}
+
+JNIEXPORT void JNICALL
+JCL_free_cstring (JNIEnv * env, jstring s, const char *cstr)
+{
+ (*env)->ReleaseStringUTFChars (env, s, cstr);
+}
+
+JNIEXPORT jint JNICALL
+JCL_MonitorEnter (JNIEnv * env, jobject o)
+{
+ jint retval = (*env)->MonitorEnter (env, o);
+ if (retval != 0)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "MonitorEnter() failed.");
+ }
+ return retval;
+}
+
+JNIEXPORT jint JNICALL
+JCL_MonitorExit (JNIEnv * env, jobject o)
+{
+ jint retval = (*env)->MonitorExit (env, o);
+ if (retval != 0)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "MonitorExit() failed.");
+ }
+ return retval;
+}
+
+JNIEXPORT jclass JNICALL
+JCL_FindClass (JNIEnv * env, const char *className)
+{
+ jclass retval = (*env)->FindClass (env, className);
+ if (retval == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/ClassNotFoundException", className);
+ }
+ return retval;
+}
diff --git a/libjava/classpath/native/jni/classpath/jcl.h b/libjava/classpath/native/jni/classpath/jcl.h
new file mode 100644
index 00000000000..e526b293966
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/jcl.h
@@ -0,0 +1,68 @@
+/* jcl.h
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef __JCL_H__
+#define __JCL_H__
+
+#include <stddef.h>
+#include <jni.h>
+#include <config.h>
+
+JNIEXPORT jclass JNICALL JCL_FindClass (JNIEnv * env, const char *className);
+JNIEXPORT void JNICALL JCL_ThrowException (JNIEnv * env,
+ const char *className,
+ const char *errMsg);
+JNIEXPORT void *JNICALL JCL_malloc (JNIEnv * env, size_t size);
+JNIEXPORT void *JNICALL JCL_realloc (JNIEnv * env, void *ptr, size_t size);
+JNIEXPORT void JNICALL JCL_free (JNIEnv * env, void *p);
+JNIEXPORT const char *JNICALL JCL_jstring_to_cstring (JNIEnv * env,
+ jstring s);
+JNIEXPORT void JNICALL JCL_free_cstring (JNIEnv * env, jstring s,
+ const char *cstr);
+JNIEXPORT jint JNICALL JCL_MonitorEnter (JNIEnv * env, jobject o);
+JNIEXPORT jint JNICALL JCL_MonitorExit (JNIEnv * env, jobject o);
+
+#define JCL_RETHROW_EXCEPTION(env) if((*(env))->ExceptionOccurred((env)) != NULL) return NULL;
+
+/* Simple debug macro */
+#ifdef DEBUG
+#define DBG(x) fprintf(stderr, (x));
+#else
+#define DBG(x)
+#endif
+
+#endif
diff --git a/libjava/classpath/native/jni/classpath/jnilink.c b/libjava/classpath/native/jni/classpath/jnilink.c
new file mode 100644
index 00000000000..15e73a7210b
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/jnilink.c
@@ -0,0 +1,125 @@
+/* JNILINK 1.1: JNI version.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <jcl.h>
+
+#include "jnilink.h"
+
+#define GETCLASS(c) *(jclass*)(c)
+
+JNIEXPORT jclass JNICALL
+LINK_RelinkClass (JNIEnv * env, linkedClass * c, const char *name)
+{
+ jclass found;
+ LINK_UnlinkClass (env, *c);
+
+ found = (*env)->FindClass (env, name);
+ if (found == NULL)
+ return NULL;
+
+ *c = JCL_malloc (env, sizeof (jclass));
+ if (*c == NULL)
+ return NULL;
+
+ GETCLASS (*c) = (*env)->NewGlobalRef (env, found);
+ return GETCLASS (*c);
+}
+
+JNIEXPORT jclass JNICALL
+LINK_RelinkKnownClass (JNIEnv * env, linkedClass * c, jclass newClass)
+{
+ LINK_UnlinkClass (env, *c);
+
+ *c = JCL_malloc (env, sizeof (jclass));
+ if (*c == NULL)
+ return NULL;
+
+ GETCLASS (*c) = (*env)->NewGlobalRef (env, newClass);
+ return newClass;
+}
+
+JNIEXPORT jmethodID JNICALL
+LINK_RelinkMethod (JNIEnv * env, jmethodID * m, linkedClass c,
+ const char *name, const char *sig)
+{
+ *m = (*env)->GetMethodID (env, GETCLASS (c), name, sig);
+ return *m;
+}
+
+JNIEXPORT jmethodID JNICALL
+LINK_RelinkStaticMethod (JNIEnv * env, jmethodID * m, linkedClass c,
+ const char *name, const char *sig)
+{
+ *m = (*env)->GetStaticMethodID (env, GETCLASS (c), name, sig);
+ return *m;
+}
+
+JNIEXPORT jfieldID JNICALL
+LINK_RelinkField (JNIEnv * env, jfieldID * f, linkedClass c,
+ const char *name, const char *sig)
+{
+ *f = (*env)->GetFieldID (env, GETCLASS (c), name, sig);
+ return *f;
+}
+
+JNIEXPORT jfieldID JNICALL
+LINK_RelinkStaticField (JNIEnv * env, jfieldID * f, linkedClass c,
+ const char *name, const char *sig)
+{
+ *f = (*env)->GetStaticFieldID (env, GETCLASS (c), name, sig);
+ return *f;
+}
+
+
+/* These are for when the class referencing the symbols is unloaded; it
+destroys any object references
+ * the linker might have kept around.
+ */
+JNIEXPORT void JNICALL
+LINK_UnlinkClass (JNIEnv * env, linkedClass * c)
+{
+ if (*c != NULL)
+ {
+ if (GETCLASS (*c) != NULL)
+ (*env)->DeleteGlobalRef (env, GETCLASS (*c));
+ JCL_free (env, *c);
+ *c = NULL;
+ }
+}
diff --git a/libjava/classpath/native/jni/classpath/jnilink.h b/libjava/classpath/native/jni/classpath/jnilink.h
new file mode 100644
index 00000000000..dd94b3a7aed
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/jnilink.h
@@ -0,0 +1,82 @@
+/* JNILINK 1.1: JNI version.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#ifndef __JNILINK_H__
+#define __JNILINK_H__
+
+#include <jni.h>
+
+typedef void *linkedClass;
+
+#define LINK_LinkClass(env,c,name) ((c)==NULL ? LINK_ReallyLinkClass((env),&(c),(name)) : (c))
+#define LINK_LinkKnownClass(env,c,newClass) ((c)==NULL ? LINK_ReallyLinkKnownClass((env),&(c),(newClass)) : (c))
+#define LINK_LinkMethod(env,m,c,name,sig) ((m)==NULL ? LINK_RelinkMethod((env),&(m),(c),(name),(sig)) : (m))
+#define LINK_LinkStaticMethod(env,m,c,name,sig) ((m)==NULL ? LINK_RelinkStaticMethod((env),&(m),(c),(name),(sig)) : (m))
+#define LINK_LinkField(env,f,c,name,sig) ((m)==NULL ? LINK_RelinkField((env),&(f),(c),(name),(sig)) : (f))
+#define LINK_LinkStaticField(env,f,c,name,sig) ((m)==NULL ? LINK_RelinkStaticField((env),&(f),(c),(name),(sig)) : (f))
+
+#define LINK_LinkConstructor(env,m,c,sig) ((m)==NULL ? LINK_RelinkMethod((env),&(m),(c),"<init>",(sig)) : (m))
+
+JNIEXPORT jclass JNICALL
+LINK_ReallyLinkClass (JNIEnv * env, linkedClass * c, const char *name);
+JNIEXPORT jclass JNICALL
+LINK_ReallyLinkKnownClass (JNIEnv * env, linkedClass * c, jclass newClass);
+JNIEXPORT jclass JNICALL
+LINK_RelinkClass (JNIEnv * env, linkedClass * c, const char *name);
+JNIEXPORT jclass JNICALL
+LINK_RelinkKnownClass (JNIEnv * env, linkedClass * c, jclass newClass);
+JNIEXPORT jmethodID JNICALL
+LINK_RelinkMethod (JNIEnv * env, jmethodID * m, linkedClass c,
+ const char *name, const char *sig);
+JNIEXPORT jmethodID JNICALL
+LINK_RelinkStaticMethod (JNIEnv * env, jmethodID * m, linkedClass c,
+ const char *name, const char *sig);
+JNIEXPORT jfieldID JNICALL
+LINK_RelinkField (JNIEnv * env, jfieldID * f, linkedClass c,
+ const char *name, const char *sig);
+JNIEXPORT jfieldID JNICALL
+LINK_RelinkStaticField (JNIEnv * env, jfieldID * f, linkedClass c,
+ const char *name, const char *sig);
+
+/* These are for when the class referencing the symbols is unloaded; it
+destroys any object references
+ * the linker might have kept around.
+ */
+JNIEXPORT void JNICALL LINK_UnlinkClass (JNIEnv * env, linkedClass * c);
+
+#endif
diff --git a/libjava/classpath/native/jni/classpath/native_state.c b/libjava/classpath/native/jni/classpath/native_state.c
new file mode 100644
index 00000000000..3c11b8343de
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/native_state.c
@@ -0,0 +1,248 @@
+/* Magical NSA API -- Associate a C ptr with an instance of an object
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <stdlib.h>
+#include <jni.h>
+#include "native_state.h"
+
+#define DEFAULT_TABLE_SIZE 97
+
+struct state_table *
+cp_gtk_init_state_table_with_size (JNIEnv * env, jclass clazz, jint size)
+{
+ struct state_table *table;
+ jfieldID hash;
+ jclass clazz_g;
+
+ hash = (*env)->GetFieldID (env, clazz, "native_state", "I");
+ if (hash == NULL)
+ return NULL;
+
+ clazz_g = (*env)->NewGlobalRef (env, clazz);
+ if (clazz_g == NULL)
+ return NULL;
+
+ table = (struct state_table *) malloc (sizeof (struct state_table));
+ table->size = size;
+ table->head = (struct state_node **) calloc (sizeof (struct state_node *),
+ table->size);
+ table->hash = hash;
+ table->clazz = clazz_g;
+
+ return table;
+}
+
+struct state_table *
+cp_gtk_init_state_table (JNIEnv * env, jclass clazz)
+{
+ return cp_gtk_init_state_table_with_size (env, clazz, DEFAULT_TABLE_SIZE);
+}
+
+static void *
+remove_node (struct state_node **head, jint obj_id)
+{
+ struct state_node *back_ptr = NULL;
+ struct state_node *node = *head;
+
+ while (node != NULL)
+ {
+ if (node->key == obj_id)
+ {
+ void *return_value;
+ if (back_ptr == NULL)
+ *head = node->next;
+ else
+ back_ptr->next = node->next;
+ return_value = node->c_state;
+ free (node);
+ return return_value;
+ }
+ back_ptr = node;
+ node = node->next;
+ }
+
+ return NULL;
+}
+
+static void *
+get_node (struct state_node **head, jint obj_id)
+{
+ struct state_node *back_ptr = NULL;
+ struct state_node *node = *head;
+
+ while (node != NULL)
+ {
+ if (node->key == obj_id)
+ {
+ /* Move the node we found to the front of the list. */
+ if (back_ptr != NULL)
+ {
+ back_ptr->next = node->next;
+ node->next = *head;
+ *head = node;
+ }
+
+ /* Return the match. */
+ return node->c_state;
+ }
+
+ back_ptr = node;
+ node = node->next;
+ }
+
+ return NULL;
+}
+
+static void
+add_node (struct state_node **head, jint obj_id, void *state)
+{
+ struct state_node *node = *head;
+ struct state_node *back_ptr = NULL;
+
+ struct state_node *new_node;
+
+ if (node != NULL)
+ {
+ while (node->next != NULL && obj_id != node->key)
+ {
+ back_ptr = node;
+ node = node->next;
+ }
+
+ if (node->key == obj_id)
+ {
+ /* If we're updating a node, move it to the front of the
+ list. */
+ if (back_ptr != NULL)
+ {
+ back_ptr->next = node->next;
+ node->next = *head;
+ *head = node;
+ }
+ node->c_state = state;
+ return;
+ }
+ }
+
+ new_node = (struct state_node *) malloc (sizeof (struct state_node));
+ new_node->key = obj_id;
+ new_node->c_state = state;
+ new_node->next = *head;
+ *head = new_node;
+}
+
+void
+cp_gtk_set_state_oid (JNIEnv * env, jobject lock, struct state_table *table,
+ jint obj_id, void *state)
+{
+ jint hash;
+
+ hash = obj_id % table->size;
+
+ (*env)->MonitorEnter (env, lock);
+ add_node (&table->head[hash], obj_id, state);
+ (*env)->MonitorExit (env, lock);
+}
+
+void *
+cp_gtk_get_state_oid (JNIEnv * env, jobject lock, struct state_table *table,
+ jint obj_id)
+{
+ jint hash;
+ void *return_value;
+
+ hash = obj_id % table->size;
+
+ (*env)->MonitorEnter (env, lock);
+ return_value = get_node (&table->head[hash], obj_id);
+ (*env)->MonitorExit (env, lock);
+
+ return return_value;
+}
+
+void *
+cp_gtk_remove_state_oid (JNIEnv * env, jobject lock, struct state_table *table,
+ jint obj_id)
+{
+ jint hash;
+ void *return_value;
+
+ hash = obj_id % table->size;
+
+ (*env)->MonitorEnter (env, lock);
+ return_value = remove_node (&table->head[hash], obj_id);
+ (*env)->MonitorExit (env, lock);
+
+ return return_value;
+}
+
+int
+cp_gtk_set_state (JNIEnv * env, jobject obj, struct state_table *table, void *state)
+{
+ jint obj_id;
+ obj_id = (*env)->GetIntField (env, obj, table->hash);
+
+ if ((*env)->ExceptionOccurred (env) != NULL)
+ return -1;
+
+ cp_gtk_set_state_oid (env, table->clazz, table, obj_id, state);
+ return 0;
+}
+
+void *
+cp_gtk_get_state (JNIEnv * env, jobject obj, struct state_table *table)
+{
+ jint obj_id;
+ obj_id = (*env)->GetIntField (env, obj, table->hash);
+
+ if ((*env)->ExceptionOccurred (env) != NULL)
+ return NULL;
+
+ return cp_gtk_get_state_oid (env, table->clazz, table, obj_id);
+}
+
+void *
+cp_gtk_remove_state_slot (JNIEnv * env, jobject obj, struct state_table *table)
+{
+ jint obj_id;
+ obj_id = (*env)->GetIntField (env, obj, table->hash);
+
+ if ((*env)->ExceptionOccurred (env) != NULL)
+ return NULL;
+
+ return cp_gtk_remove_state_oid (env, table->clazz, table, obj_id);
+}
diff --git a/libjava/classpath/native/jni/classpath/native_state.h b/libjava/classpath/native/jni/classpath/native_state.h
new file mode 100644
index 00000000000..641e588827d
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/native_state.h
@@ -0,0 +1,71 @@
+/* Magical NSA API -- Associate a C ptr with an instance of an object
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef JCL_NATIVE_STATE
+#define JCL_NATIVE_STATE
+
+#include <jni.h>
+
+struct state_table
+{
+ jint size; /* number of slots, should be prime */
+ jfieldID hash; /* field containing System.identityHashCode(this) */
+ jclass clazz; /* lock aquired for reading/writing nodes */
+ struct state_node **head;
+};
+
+struct state_node
+{
+ jint key;
+ void *c_state;
+ struct state_node *next;
+};
+
+struct state_table *cp_gtk_init_state_table_with_size (JNIEnv *, jclass, jint);
+struct state_table *cp_gtk_init_state_table (JNIEnv *, jclass);
+
+/* lowlevel api */
+void cp_gtk_set_state_oid (JNIEnv *, jobject, struct state_table *, jint, void *);
+void *cp_gtk_get_state_oid (JNIEnv *, jobject, struct state_table *, jint);
+void *cp_gtk_remove_state_oid (JNIEnv *, jobject, struct state_table *, jint);
+
+/* highlevel api */
+int cp_gtk_set_state (JNIEnv *, jobject, struct state_table *, void *);
+void *cp_gtk_get_state (JNIEnv *, jobject, struct state_table *);
+void *cp_gtk_remove_state_slot (JNIEnv *, jobject, struct state_table *);
+
+#endif
diff --git a/libjava/classpath/native/jni/classpath/primlib.c b/libjava/classpath/native/jni/classpath/primlib.c
new file mode 100644
index 00000000000..e6773ba5353
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/primlib.c
@@ -0,0 +1,724 @@
+/* primlib.c
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <jnilink.h>
+#include <primlib.h>
+#include <jcl.h>
+
+static jclass nativeWrapClass[PRIMLIB_NUMTYPES] =
+ { NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+static jclass nativeTypeClass[PRIMLIB_NUMTYPES] =
+ { NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+static jmethodID nativeWrapClassConstructor[PRIMLIB_NUMTYPES] =
+ { NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+static jmethodID nativeWrapClassAccessor[PRIMLIB_NUMTYPES] =
+ { NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+static const char *nativeWrapClassName[PRIMLIB_NUMTYPES] = {
+ NULL,
+ NULL,
+ "java/lang/Boolean",
+ "java/lang/Byte",
+ "java/lang/Character",
+ "java/lang/Short",
+ "java/lang/Integer",
+ "java/lang/Long",
+ "java/lang/Float",
+ "java/lang/Double",
+ "java/lang/Void",
+ NULL
+};
+
+static const char *nativeWrapClassConstructorSig[PRIMLIB_NUMTYPES] = {
+ NULL,
+ NULL,
+ "(Z)V",
+ "(B)V",
+ "(C)V",
+ "(S)V",
+ "(I)V",
+ "(J)V",
+ "(F)V",
+ "(D)V",
+ "()V",
+ NULL
+};
+
+static const char *nativeWrapClassAccessorName[PRIMLIB_NUMTYPES] = {
+ NULL,
+ NULL,
+ "booleanValue",
+ "byteValue",
+ "charValue",
+ "shortValue",
+ "intValue",
+ "longValue",
+ "floatValue",
+ "doubleValue",
+ NULL,
+ NULL
+};
+
+static const char *nativeWrapClassAccessorSig[PRIMLIB_NUMTYPES] = {
+ NULL,
+ NULL,
+ "()Z",
+ "()B",
+ "()C",
+ "()S",
+ "()I",
+ "()J",
+ "()F",
+ "()D",
+ NULL,
+ NULL
+};
+
+
+JNIEXPORT jclass JNICALL
+PRIMLIB_GetNativeWrapClass (JNIEnv * env, int reflectType)
+{
+ return LINK_LinkClass (env, nativeWrapClass[reflectType],
+ nativeWrapClassName[reflectType]);
+}
+
+static jclass
+ActuallyGetNativeTypeClass (JNIEnv * env, int reflectType)
+{
+ jclass wrapClass;
+ jfieldID typeField;
+
+ wrapClass = PRIMLIB_GetNativeWrapClass (env, reflectType);
+ if (wrapClass == NULL)
+ return NULL;
+ typeField =
+ (*env)->GetStaticFieldID (env, wrapClass, "TYPE", "Ljava/lang/Class");
+ if (typeField == NULL)
+ return NULL;
+ return (*env)->GetStaticObjectField (env, wrapClass, typeField);
+}
+
+JNIEXPORT jclass JNICALL
+PRIMLIB_GetNativeTypeClass (JNIEnv * env, int reflectType)
+{
+ return LINK_LinkKnownClass (env, nativeTypeClass[reflectType],
+ ActuallyGetNativeTypeClass (env, reflectType));
+}
+
+JNIEXPORT jmethodID JNICALL
+PRIMLIB_GetNativeWrapClassConstructor (JNIEnv * env, int reflectType)
+{
+ PRIMLIB_GetNativeWrapClass (env, reflectType);
+ return LINK_LinkConstructor (env, nativeWrapClassConstructor[reflectType],
+ nativeWrapClass[reflectType],
+ nativeWrapClassConstructorSig[reflectType]);
+}
+
+JNIEXPORT jmethodID JNICALL
+PRIMLIB_GetNativeWrapClassAccessor (JNIEnv * env, int reflectType)
+{
+ PRIMLIB_GetNativeWrapClass (env, reflectType);
+ return LINK_LinkMethod (env, nativeWrapClassAccessor[reflectType],
+ nativeWrapClass[reflectType],
+ nativeWrapClassAccessorName[reflectType],
+ nativeWrapClassAccessorSig[reflectType]);
+}
+
+
+
+JNIEXPORT jobject JNICALL
+PRIMLIB_WrapBoolean (JNIEnv * env, jboolean b)
+{
+ jmethodID construct =
+ PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_BOOLEAN);
+ JCL_RETHROW_EXCEPTION (env);
+ return (*env)->NewObject (env,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BOOLEAN),
+ construct, b);
+}
+
+JNIEXPORT jobject JNICALL
+PRIMLIB_WrapByte (JNIEnv * env, jbyte b)
+{
+ jmethodID construct =
+ PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_BYTE);
+ JCL_RETHROW_EXCEPTION (env);
+ return (*env)->NewObject (env,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE),
+ construct, b);
+}
+
+JNIEXPORT jobject JNICALL
+PRIMLIB_WrapChar (JNIEnv * env, jchar c)
+{
+ jmethodID construct =
+ PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_CHAR);
+ JCL_RETHROW_EXCEPTION (env);
+ return (*env)->NewObject (env,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR),
+ construct, c);
+}
+
+JNIEXPORT jobject JNICALL
+PRIMLIB_WrapShort (JNIEnv * env, jshort s)
+{
+ jmethodID construct =
+ PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_SHORT);
+ JCL_RETHROW_EXCEPTION (env);
+ return (*env)->NewObject (env,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT),
+ construct, s);
+}
+
+JNIEXPORT jobject JNICALL
+PRIMLIB_WrapInt (JNIEnv * env, jint i)
+{
+ jmethodID construct =
+ PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_INT);
+ JCL_RETHROW_EXCEPTION (env);
+ return (*env)->NewObject (env,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT),
+ construct, i);
+}
+
+JNIEXPORT jobject JNICALL
+PRIMLIB_WrapLong (JNIEnv * env, jlong l)
+{
+ jmethodID construct =
+ PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_LONG);
+ JCL_RETHROW_EXCEPTION (env);
+ return (*env)->NewObject (env,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_LONG),
+ construct, l);
+}
+
+JNIEXPORT jobject JNICALL
+PRIMLIB_WrapFloat (JNIEnv * env, jfloat f)
+{
+ jmethodID construct =
+ PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_FLOAT);
+ JCL_RETHROW_EXCEPTION (env);
+ return (*env)->NewObject (env,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_FLOAT),
+ construct, f);
+}
+
+JNIEXPORT jobject JNICALL
+PRIMLIB_WrapDouble (JNIEnv * env, jdouble d)
+{
+ jmethodID construct =
+ PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_DOUBLE);
+ JCL_RETHROW_EXCEPTION (env);
+ return (*env)->NewObject (env,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_DOUBLE),
+ construct, d);
+}
+
+
+JNIEXPORT jboolean JNICALL
+PRIMLIB_UnwrapBoolean (JNIEnv * env, jobject obj)
+{
+ if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BOOLEAN)))
+ {
+ return PRIMLIB_GetBooleanObjectValue (env, obj);
+ }
+ else
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Argument not of correct type.");
+ return JNI_FALSE;
+ }
+}
+
+JNIEXPORT jbyte JNICALL
+PRIMLIB_UnwrapByte (JNIEnv * env, jobject obj)
+{
+ if ((*env)->
+ IsInstanceOf (env, obj, PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
+ {
+ return PRIMLIB_GetByteObjectValue (env, obj);
+ }
+ else
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Argument not of correct type.");
+ return 0;
+ }
+}
+
+JNIEXPORT jshort JNICALL
+PRIMLIB_UnwrapShort (JNIEnv * env, jobject obj)
+{
+ if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT)))
+ {
+ return PRIMLIB_GetShortObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
+ {
+ return (jshort) PRIMLIB_GetByteObjectValue (env, obj);
+ }
+ else
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Argument not of correct type.");
+ return 0;
+ }
+}
+
+JNIEXPORT jchar JNICALL
+PRIMLIB_UnwrapChar (JNIEnv * env, jobject obj)
+{
+ if ((*env)->
+ IsInstanceOf (env, obj, PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR)))
+ {
+ return PRIMLIB_GetCharObjectValue (env, obj);
+ }
+ else
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Argument not of correct type.");
+ return 0;
+ }
+}
+
+JNIEXPORT jint JNICALL
+PRIMLIB_UnwrapInt (JNIEnv * env, jobject obj)
+{
+ if ((*env)->
+ IsInstanceOf (env, obj, PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT)))
+ {
+ return PRIMLIB_GetIntObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT)))
+ {
+ return (jint) PRIMLIB_GetShortObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR)))
+ {
+ return (jint) PRIMLIB_GetCharObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
+ {
+ return (jint) PRIMLIB_GetByteObjectValue (env, obj);
+ }
+ else
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Argument not of correct type.");
+ return 0;
+ }
+}
+
+JNIEXPORT jlong JNICALL
+PRIMLIB_UnwrapLong (JNIEnv * env, jobject obj)
+{
+ if ((*env)->
+ IsInstanceOf (env, obj, PRIMLIB_GetNativeWrapClass (env, PRIMLIB_LONG)))
+ {
+ return PRIMLIB_GetLongObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT)))
+ {
+ return (jlong) PRIMLIB_GetIntObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT)))
+ {
+ return (jlong) PRIMLIB_GetShortObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR)))
+ {
+ return (jlong) PRIMLIB_GetCharObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
+ {
+ return (jlong) PRIMLIB_GetByteObjectValue (env, obj);
+ }
+ else
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Argument not of correct type.");
+ return 0;
+ }
+}
+
+JNIEXPORT jfloat JNICALL
+PRIMLIB_UnwrapFloat (JNIEnv * env, jobject obj)
+{
+ if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_FLOAT)))
+ {
+ return PRIMLIB_GetFloatObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_LONG)))
+ {
+ return (jfloat) PRIMLIB_GetLongObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT)))
+ {
+ return (jfloat) PRIMLIB_GetIntObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT)))
+ {
+ return (jfloat) PRIMLIB_GetShortObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR)))
+ {
+ return (jfloat) PRIMLIB_GetCharObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
+ {
+ return (jfloat) PRIMLIB_GetByteObjectValue (env, obj);
+ }
+ else
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Argument not of correct type.");
+ return 0;
+ }
+}
+
+JNIEXPORT jdouble JNICALL
+PRIMLIB_UnwrapDouble (JNIEnv * env, jobject obj)
+{
+ if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_DOUBLE)))
+ {
+ return PRIMLIB_GetDoubleObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_FLOAT)))
+ {
+ return (jdouble) PRIMLIB_GetFloatObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_LONG)))
+ {
+ return (jdouble) PRIMLIB_GetLongObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT)))
+ {
+ return (jdouble) PRIMLIB_GetIntObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT)))
+ {
+ return (jdouble) PRIMLIB_GetShortObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR)))
+ {
+ return (jdouble) PRIMLIB_GetCharObjectValue (env, obj);
+ }
+ else if ((*env)->
+ IsInstanceOf (env, obj,
+ PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
+ {
+ return (jdouble) PRIMLIB_GetByteObjectValue (env, obj);
+ }
+ else
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Argument not of correct type.");
+ return 0;
+ }
+}
+
+JNIEXPORT jint JNICALL
+PRIMLIB_GetReflectiveWrapperType (JNIEnv * env, jobject obj)
+{
+ jclass typeClass;
+ if (obj == NULL)
+ {
+ return PRIMLIB_NULL;
+ }
+
+ typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_DOUBLE);
+ if ((*env)->IsInstanceOf (env, obj, typeClass))
+ {
+ return PRIMLIB_DOUBLE;
+ }
+ typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_FLOAT);
+ if ((*env)->IsInstanceOf (env, obj, typeClass))
+ {
+ return PRIMLIB_FLOAT;
+ }
+ typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_LONG);
+ if ((*env)->IsInstanceOf (env, obj, typeClass))
+ {
+ return PRIMLIB_LONG;
+ }
+ typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT);
+ if ((*env)->IsInstanceOf (env, obj, typeClass))
+ {
+ return PRIMLIB_INT;
+ }
+ typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR);
+ if ((*env)->IsInstanceOf (env, obj, typeClass))
+ {
+ return PRIMLIB_CHAR;
+ }
+ typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT);
+ if ((*env)->IsInstanceOf (env, obj, typeClass))
+ {
+ return PRIMLIB_SHORT;
+ }
+ typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE);
+ if ((*env)->IsInstanceOf (env, obj, typeClass))
+ {
+ return PRIMLIB_BYTE;
+ }
+ typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BOOLEAN);
+ if ((*env)->IsInstanceOf (env, obj, typeClass))
+ {
+ return PRIMLIB_BOOLEAN;
+ }
+ typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_VOID);
+ if ((*env)->IsInstanceOf (env, obj, typeClass))
+ {
+ return PRIMLIB_VOID;
+ }
+ return PRIMLIB_OBJECT;
+}
+
+JNIEXPORT jint JNICALL
+PRIMLIB_GetReflectiveType (JNIEnv * env, jclass returnType)
+{
+ jclass typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_DOUBLE);
+ if ((*env)->IsAssignableFrom (env, returnType, typeClass))
+ {
+ return PRIMLIB_DOUBLE;
+ }
+ typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_FLOAT);
+ if ((*env)->IsAssignableFrom (env, returnType, typeClass))
+ {
+ return PRIMLIB_FLOAT;
+ }
+ typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_LONG);
+ if ((*env)->IsAssignableFrom (env, returnType, typeClass))
+ {
+ return PRIMLIB_LONG;
+ }
+ typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_INT);
+ if ((*env)->IsAssignableFrom (env, returnType, typeClass))
+ {
+ return PRIMLIB_INT;
+ }
+ typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_CHAR);
+ if ((*env)->IsAssignableFrom (env, returnType, typeClass))
+ {
+ return PRIMLIB_CHAR;
+ }
+ typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_SHORT);
+ if ((*env)->IsAssignableFrom (env, returnType, typeClass))
+ {
+ return PRIMLIB_SHORT;
+ }
+ typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_BYTE);
+ if ((*env)->IsAssignableFrom (env, returnType, typeClass))
+ {
+ return PRIMLIB_BYTE;
+ }
+ typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_BOOLEAN);
+ if ((*env)->IsAssignableFrom (env, returnType, typeClass))
+ {
+ return PRIMLIB_BOOLEAN;
+ }
+ typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_VOID);
+ if ((*env)->IsAssignableFrom (env, returnType, typeClass))
+ {
+ return PRIMLIB_VOID;
+ }
+ return PRIMLIB_OBJECT;
+}
+
+
+JNIEXPORT jboolean JNICALL
+PRIMLIB_GetBooleanObjectValue (JNIEnv * env, jobject obj)
+{
+ jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_BOOLEAN);
+ return (*env)->CallBooleanMethod (env, obj, acc);
+}
+
+JNIEXPORT jbyte JNICALL
+PRIMLIB_GetByteObjectValue (JNIEnv * env, jobject obj)
+{
+ jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_BYTE);
+ return (*env)->CallByteMethod (env, obj, acc);
+}
+
+JNIEXPORT jshort JNICALL
+PRIMLIB_GetShortObjectValue (JNIEnv * env, jobject obj)
+{
+ jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_SHORT);
+ return (*env)->CallShortMethod (env, obj, acc);
+}
+
+JNIEXPORT jchar JNICALL
+PRIMLIB_GetCharObjectValue (JNIEnv * env, jobject obj)
+{
+ jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_CHAR);
+ return (*env)->CallCharMethod (env, obj, acc);
+}
+
+JNIEXPORT jint JNICALL
+PRIMLIB_GetIntObjectValue (JNIEnv * env, jobject obj)
+{
+ jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_INT);
+ return (*env)->CallIntMethod (env, obj, acc);
+}
+
+JNIEXPORT jlong JNICALL
+PRIMLIB_GetLongObjectValue (JNIEnv * env, jobject obj)
+{
+ jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_LONG);
+ return (*env)->CallLongMethod (env, obj, acc);
+}
+
+JNIEXPORT jfloat JNICALL
+PRIMLIB_GetFloatObjectValue (JNIEnv * env, jobject obj)
+{
+ jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_FLOAT);
+ return (*env)->CallFloatMethod (env, obj, acc);
+}
+
+JNIEXPORT jdouble JNICALL
+PRIMLIB_GetDoubleObjectValue (JNIEnv * env, jobject obj)
+{
+ jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_DOUBLE);
+ return (*env)->CallDoubleMethod (env, obj, acc);
+}
+
+
+
+JNIEXPORT jvalue JNICALL
+PRIMLIB_UnwrapJValue (JNIEnv * env, jobject obj, jclass classType)
+{
+ jvalue retval;
+ jint objType = PRIMLIB_GetReflectiveType (env, classType);
+ if (objType == PRIMLIB_BOOLEAN)
+ {
+ retval.z = PRIMLIB_UnwrapBoolean (env, obj);
+ }
+ else if (objType == PRIMLIB_BYTE)
+ {
+ retval.b = PRIMLIB_UnwrapByte (env, obj);
+ }
+ else if (objType == PRIMLIB_CHAR)
+ {
+ retval.c = PRIMLIB_UnwrapChar (env, obj);
+ }
+ else if (objType == PRIMLIB_SHORT)
+ {
+ retval.s = PRIMLIB_UnwrapShort (env, obj);
+ }
+ else if (objType == PRIMLIB_INT)
+ {
+ retval.i = PRIMLIB_UnwrapInt (env, obj);
+ }
+ else if (objType == PRIMLIB_LONG)
+ {
+ retval.j = PRIMLIB_UnwrapLong (env, obj);
+ }
+ else if (objType == PRIMLIB_FLOAT)
+ {
+ retval.f = PRIMLIB_UnwrapFloat (env, obj);
+ }
+ else if (objType == PRIMLIB_DOUBLE)
+ {
+ retval.d = PRIMLIB_UnwrapDouble (env, obj);
+ }
+ else
+ {
+ if (obj != NULL && !(*env)->IsInstanceOf (env, obj, classType))
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Argument not of correct object type.");
+ return retval;
+ }
+ retval.l = obj;
+ }
+ return retval;
+}
diff --git a/libjava/classpath/native/jni/classpath/primlib.h b/libjava/classpath/native/jni/classpath/primlib.h
new file mode 100644
index 00000000000..3cdaaa4a148
--- /dev/null
+++ b/libjava/classpath/native/jni/classpath/primlib.h
@@ -0,0 +1,119 @@
+/* primlib.h
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef __PRIMLIB_H__
+#define __PRIMLIB_H__
+
+#include <jni.h>
+
+#define PRIMLIB_UNKNOWN 0
+#define PRIMLIB_OBJECT 1
+#define PRIMLIB_BOOLEAN 2
+#define PRIMLIB_BYTE 3
+#define PRIMLIB_CHAR 4
+#define PRIMLIB_SHORT 5
+#define PRIMLIB_INT 6
+#define PRIMLIB_LONG 7
+#define PRIMLIB_FLOAT 8
+#define PRIMLIB_DOUBLE 9
+#define PRIMLIB_VOID 10
+#define PRIMLIB_NULL 11
+#define PRIMLIB_NUMTYPES 12
+
+/* Low-level primitive class accessor functions. */
+JNIEXPORT jclass JNICALL PRIMLIB_GetNativeWrapClass (JNIEnv * env,
+ int reflectType);
+JNIEXPORT jclass JNICALL PRIMLIB_GetNativeTypeClass (JNIEnv * env,
+ int reflectType);
+JNIEXPORT jmethodID JNICALL PRIMLIB_GetNativeWrapClassConstructor (JNIEnv *
+ env,
+ int
+ reflectType);
+JNIEXPORT jmethodID JNICALL PRIMLIB_GetNativeWrapClassAccessor (JNIEnv * env,
+ int
+ reflectType);
+
+/* Type discovery functions: WrapperType finds out j.l.Boolean/Byte/etc., and
+ Type finds out j.l.Boolean.TYPE, etc.
+*/
+JNIEXPORT jint JNICALL PRIMLIB_GetReflectiveWrapperType (JNIEnv * env,
+ jobject obj);
+JNIEXPORT jint JNICALL PRIMLIB_GetReflectiveType (JNIEnv * env,
+ jclass returnType);
+
+/* Constructor functions. */
+JNIEXPORT jobject JNICALL PRIMLIB_WrapBoolean (JNIEnv * env, jboolean b);
+JNIEXPORT jobject JNICALL PRIMLIB_WrapByte (JNIEnv * env, jbyte b);
+JNIEXPORT jobject JNICALL PRIMLIB_WrapChar (JNIEnv * env, jchar c);
+JNIEXPORT jobject JNICALL PRIMLIB_WrapShort (JNIEnv * env, jshort s);
+JNIEXPORT jobject JNICALL PRIMLIB_WrapInt (JNIEnv * env, jint i);
+JNIEXPORT jobject JNICALL PRIMLIB_WrapLong (JNIEnv * env, jlong l);
+JNIEXPORT jobject JNICALL PRIMLIB_WrapFloat (JNIEnv * env, jfloat f);
+JNIEXPORT jobject JNICALL PRIMLIB_WrapDouble (JNIEnv * env, jdouble d);
+
+/* Widening conversion unwrapping functions. */
+JNIEXPORT jboolean JNICALL PRIMLIB_UnwrapBoolean (JNIEnv * env, jobject obj);
+JNIEXPORT jbyte JNICALL PRIMLIB_UnwrapByte (JNIEnv * env, jobject obj);
+JNIEXPORT jshort JNICALL PRIMLIB_UnwrapShort (JNIEnv * env, jobject obj);
+JNIEXPORT jchar JNICALL PRIMLIB_UnwrapChar (JNIEnv * env, jobject obj);
+JNIEXPORT jint JNICALL PRIMLIB_UnwrapInt (JNIEnv * env, jobject obj);
+JNIEXPORT jlong JNICALL PRIMLIB_UnwrapLong (JNIEnv * env, jobject obj);
+JNIEXPORT jfloat JNICALL PRIMLIB_UnwrapFloat (JNIEnv * env, jobject obj);
+JNIEXPORT jdouble JNICALL PRIMLIB_UnwrapDouble (JNIEnv * env, jobject obj);
+
+/* Simple unwrapping functions. Objects *must* be of correct type. */
+JNIEXPORT jboolean JNICALL PRIMLIB_GetBooleanObjectValue (JNIEnv * env,
+ jobject obj);
+JNIEXPORT jbyte JNICALL PRIMLIB_GetByteObjectValue (JNIEnv * env,
+ jobject obj);
+JNIEXPORT jshort JNICALL PRIMLIB_GetShortObjectValue (JNIEnv * env,
+ jobject obj);
+JNIEXPORT jchar JNICALL PRIMLIB_GetCharObjectValue (JNIEnv * env,
+ jobject obj);
+JNIEXPORT jint JNICALL PRIMLIB_GetIntObjectValue (JNIEnv * env, jobject obj);
+JNIEXPORT jlong JNICALL PRIMLIB_GetLongObjectValue (JNIEnv * env,
+ jobject obj);
+JNIEXPORT jfloat JNICALL PRIMLIB_GetFloatObjectValue (JNIEnv * env,
+ jobject obj);
+JNIEXPORT jdouble JNICALL PRIMLIB_GetDoubleObjectValue (JNIEnv * env,
+ jobject obj);
+
+/* jvalue conversion: Unwrap obj to the type of classType, with widening conversion. */
+JNIEXPORT jvalue JNICALL PRIMLIB_UnwrapJValue (JNIEnv * env, jobject obj,
+ jclass classType);
+
+#endif
diff --git a/libjava/classpath/native/jni/gtk-peer/.cvsignore b/libjava/classpath/native/jni/gtk-peer/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/gtk-peer/Makefile.am b/libjava/classpath/native/jni/gtk-peer/Makefile.am
new file mode 100644
index 00000000000..f4e7bdfcce1
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/Makefile.am
@@ -0,0 +1,61 @@
+pkglib_LTLIBRARIES = libgtkpeer.la
+
+# Gtk/Cairo JNI sources.
+if GTK_CAIRO
+ gtk_cairo_c_source_files = \
+ gnu_java_awt_peer_gtk_GdkGraphics2D.c
+else
+ gtk_cairo_c_source_files =
+endif
+
+libgtkpeer_la_SOURCES = $(gtk_cairo_c_source_files) \
+ gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c \
+ gnu_java_awt_peer_gtk_GdkFontPeer.c \
+ gnu_java_awt_peer_gtk_GdkGraphics.c \
+ gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c \
+ gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \
+ gnu_java_awt_peer_gtk_GdkRobotPeer.c \
+ gnu_java_awt_peer_gtk_GdkTextLayout.c \
+ gnu_java_awt_peer_gtk_GtkButtonPeer.c \
+ gnu_java_awt_peer_gtk_GtkCanvasPeer.c \
+ gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c \
+ gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c \
+ gnu_java_awt_peer_gtk_GtkCheckboxPeer.c \
+ gnu_java_awt_peer_gtk_GtkChoicePeer.c \
+ gnu_java_awt_peer_gtk_GtkClipboard.c \
+ gnu_java_awt_peer_gtk_GtkComponentPeer.c \
+ gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c \
+ gnu_java_awt_peer_gtk_GtkFileDialogPeer.c \
+ gnu_java_awt_peer_gtk_GtkFramePeer.c \
+ gnu_java_awt_peer_gtk_GtkGenericPeer.c \
+ gnu_java_awt_peer_gtk_GtkImage.c \
+ gnu_java_awt_peer_gtk_GtkLabelPeer.c \
+ gnu_java_awt_peer_gtk_GtkListPeer.c \
+ gnu_java_awt_peer_gtk_GtkMenuBarPeer.c \
+ gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c \
+ gnu_java_awt_peer_gtk_GtkMenuItemPeer.c \
+ gnu_java_awt_peer_gtk_GtkMenuPeer.c \
+ gnu_java_awt_peer_gtk_GtkPanelPeer.c \
+ gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c \
+ gnu_java_awt_peer_gtk_GtkScrollbarPeer.c \
+ gnu_java_awt_peer_gtk_GtkScrollPanePeer.c \
+ gnu_java_awt_peer_gtk_GtkTextAreaPeer.c \
+ gnu_java_awt_peer_gtk_GtkTextFieldPeer.c \
+ gnu_java_awt_peer_gtk_GtkToolkit.c \
+ gnu_java_awt_peer_gtk_GtkWindowPeer.c \
+ gthread-jni.c \
+ gdkfont.h \
+ gthread-jni.h \
+ gtkcairopeer.h \
+ gtkpeer.h
+
+libgtkpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/native_state.lo \
+ $(top_builddir)/native/jni/classpath/jcl.lo
+
+AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @CAIRO_LIBS@ @PANGOFT2_LIBS@ @X_LIBS@ -lXtst
+AM_CPPFLAGS = @CLASSPATH_INCLUDES@
+
+# Just the WARNING_CFLAGS. We cannot use the strict flags since the gtk
+# headers contain broken prototypes (by design, see gtkitemfactory.h).
+AM_CFLAGS = @WARNING_CFLAGS@ @ERROR_CFLAGS@ \
+ @GTK_CFLAGS@ @CAIRO_CFLAGS@ @PANGOFT2_CFLAGS@
diff --git a/libjava/classpath/native/jni/gtk-peer/gdkfont.h b/libjava/classpath/native/jni/gtk-peer/gdkfont.h
new file mode 100644
index 00000000000..cf233301547
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gdkfont.h
@@ -0,0 +1,142 @@
+#ifndef __GDKFONT_H__
+#define __GDKFONT_H__
+
+/* gdkfont.h -- Some global stuff related to fonts and glyphs
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+#include "gtkpeer.h"
+
+#include <pango/pango.h>
+#include <pango/pango-context.h>
+#include <pango/pango-fontmap.h>
+#include <pango/pangoft2.h>
+
+extern struct state_table *cp_gtk_native_font_state_table;
+extern struct state_table *native_glyphvector_state_table;
+extern struct state_table *cp_gtk_native_text_layout_state_table;
+
+#define NSA_FONT_INIT(env, clazz) \
+ cp_gtk_native_font_state_table = cp_gtk_init_state_table (env, clazz)
+
+#define NSA_GET_FONT_PTR(env, obj) \
+ cp_gtk_get_state (env, obj, cp_gtk_native_font_state_table)
+
+#define NSA_SET_FONT_PTR(env, obj, ptr) \
+ cp_gtk_set_state (env, obj, cp_gtk_native_font_state_table, (void *)ptr)
+
+#define NSA_DEL_FONT_PTR(env, obj) \
+ cp_gtk_remove_state_slot (env, obj, cp_gtk_native_font_state_table)
+
+
+#define NSA_GV_INIT(env, clazz) \
+ native_glyphvector_state_table = cp_gtk_init_state_table (env, clazz)
+
+#define NSA_GET_GV_PTR(env, obj) \
+ cp_gtk_get_state (env, obj, native_glyphvector_state_table)
+
+#define NSA_SET_GV_PTR(env, obj, ptr) \
+ cp_gtk_set_state (env, obj, native_glyphvector_state_table, (void *)ptr)
+
+#define NSA_DEL_GV_PTR(env, obj) \
+ cp_gtk_remove_state_slot (env, obj, native_glyphvector_state_table)
+
+
+#define NSA_TEXT_LAYOUT_INIT(env, clazz) \
+ cp_gtk_native_text_layout_state_table = cp_gtk_init_state_table (env, clazz)
+
+#define NSA_GET_TEXT_LAYOUT_PTR(env, obj) \
+ cp_gtk_get_state (env, obj, cp_gtk_native_text_layout_state_table)
+
+#define NSA_SET_TEXT_LAYOUT_PTR(env, obj, ptr) \
+ cp_gtk_set_state (env, obj, cp_gtk_native_text_layout_state_table, (void *)ptr)
+
+#define NSA_DEL_TEXT_LAYOUT_PTR(env, obj) \
+ cp_gtk_remove_state_slot (env, obj, cp_gtk_native_text_layout_state_table)
+
+#define FONT_METRICS_ASCENT 0
+#define FONT_METRICS_MAX_ASCENT 1
+#define FONT_METRICS_DESCENT 2
+#define FONT_METRICS_MAX_DESCENT 3
+#define FONT_METRICS_MAX_ADVANCE 4
+#define NUM_FONT_METRICS 5
+
+#define TEXT_METRICS_X_BEARING 0
+#define TEXT_METRICS_Y_BEARING 1
+#define TEXT_METRICS_WIDTH 2
+#define TEXT_METRICS_HEIGHT 3
+#define TEXT_METRICS_X_ADVANCE 4
+#define TEXT_METRICS_Y_ADVANCE 5
+#define NUM_TEXT_METRICS 6
+
+#define NUM_GLYPH_METRICS 10
+
+#define GLYPH_LOG_X(i) (NUM_GLYPH_METRICS * (i) )
+#define GLYPH_LOG_Y(i) (NUM_GLYPH_METRICS * (i) + 1)
+#define GLYPH_LOG_WIDTH(i) (NUM_GLYPH_METRICS * (i) + 2)
+#define GLYPH_LOG_HEIGHT(i) (NUM_GLYPH_METRICS * (i) + 3)
+
+#define GLYPH_INK_X(i) (NUM_GLYPH_METRICS * (i) + 4)
+#define GLYPH_INK_Y(i) (NUM_GLYPH_METRICS * (i) + 5)
+#define GLYPH_INK_WIDTH(i) (NUM_GLYPH_METRICS * (i) + 6)
+#define GLYPH_INK_HEIGHT(i) (NUM_GLYPH_METRICS * (i) + 7)
+
+#define GLYPH_POS_X(i) (NUM_GLYPH_METRICS * (i) + 8)
+#define GLYPH_POS_Y(i) (NUM_GLYPH_METRICS * (i) + 9)
+
+struct peerfont
+{
+ PangoFont *font;
+ PangoFontDescription *desc;
+ PangoContext *ctx;
+ PangoLayout *layout;
+ /*
+ * The GdkGraphics2D (using cairo) may store a pointer to a
+ * cairo_font_t here; since we want to work equally well with
+ * the GdkGraphics class (using GDK) we do not explicitly mention
+ * cairo types here; it is up to the higher level driver routine
+ * in GdkClasspathFontPeer.java to decide which backend functions
+ * to invoke.
+ */
+ void *graphics_resource;
+};
+
+struct textlayout
+{
+ PangoLayout *pango_layout;
+};
+
+#endif /* __GDKFONT_H__ */
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c
new file mode 100644
index 00000000000..595c1a28a6e
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c
@@ -0,0 +1,70 @@
+/* Native implementation of functions in GThreadNativeMethodRunner
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.h"
+#include "gthread-jni.h"
+
+/*
+ * Class: GThreadNativeMethodRunner
+ * Method: nativeRun
+ * Signature: (J)V
+ *
+ * Purpose: Run the C function whose function pointer is
+ *
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_nativeRun
+ (JNIEnv *env __attribute__((unused)),
+ jobject lcl_obj __attribute__((unused)),
+ jlong funcAddr, jlong funcArg)
+{
+ /* Convert the function's address back into a pointer to a C function. */
+ void *(*funcPtr)(void *) = (void *(*)(void *)) (size_t)funcAddr;
+
+ /* We do not need to worry about the return value from funcPtr(); it's
+ just thrown away. That is part of the g_threads spec, so no reason
+ to worry about returning it. */
+ (void) funcPtr((void *) (size_t)funcArg);
+ /* Fall off the end and terminate the thread of control. */
+}
+
+/* Local Variables: */
+/* c-file-style: "gnu" */
+/* End: */
+
+
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c
new file mode 100644
index 00000000000..401d62337b3
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c
@@ -0,0 +1,418 @@
+/* gnu_java_awt_GdkFont.c
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+#include "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_GdkFontPeer.h"
+
+struct state_table *cp_gtk_native_font_state_table;
+
+enum java_awt_font_style {
+ java_awt_font_PLAIN = 0,
+ java_awt_font_BOLD = 1,
+ java_awt_font_ITALIC = 2
+};
+
+enum java_awt_font_baseline {
+ java_awt_font_ROMAN_BASELINE = 0,
+ java_awt_font_CENTER_BASELINE = 1,
+ java_awt_font_HANGING_BASELINE = 2
+};
+
+static jmethodID glyphVector_ctor;
+static jclass glyphVector_class;
+static PangoAttrList *attrs = NULL;
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkFontPeer_initStaticState
+ (JNIEnv *env, jclass clazz)
+{
+ NSA_FONT_INIT (env, clazz);
+
+ glyphVector_class = (*env)->FindClass
+ (env, "gnu/java/awt/peer/gtk/GdkGlyphVector");
+
+ glyphVector_ctor = (*env)->GetMethodID
+ (env, glyphVector_class, "<init>",
+ "([D[ILjava/awt/Font;Ljava/awt/font/FontRenderContext;)V");
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState
+ (JNIEnv *env, jobject self)
+{
+ struct peerfont *pfont = NULL;
+
+ gdk_threads_enter ();
+
+ g_assert (self != NULL);
+ pfont = (struct peerfont *) g_malloc0 (sizeof (struct peerfont));
+ g_assert (pfont != NULL);
+ NSA_SET_FONT_PTR (env, self, pfont);
+
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose
+ (JNIEnv *env, jobject self)
+{
+ struct peerfont *pfont = NULL;
+
+ gdk_threads_enter ();
+
+ pfont = (struct peerfont *)NSA_DEL_FONT_PTR (env, self);
+ g_assert (pfont != NULL);
+ if (pfont->layout != NULL)
+ g_object_unref (pfont->font);
+ if (pfont->font != NULL)
+ g_object_unref (pfont->font);
+ if (pfont->ctx != NULL)
+ g_object_unref (pfont->ctx);
+ if (pfont->desc != NULL)
+ pango_font_description_free (pfont->desc);
+ g_free (pfont);
+
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT jobject JNICALL
+Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector
+ (JNIEnv *env, jobject self,
+ jstring chars,
+ jobject font,
+ jobject fontRenderContext)
+{
+ struct peerfont *pfont = NULL;
+ GList *items = NULL;
+ GList *i = NULL;
+ gchar *str = NULL;
+ int len = 0;
+ int j = 0;
+ double *native_extents = NULL;
+ int *native_codes = NULL;
+ jintArray java_codes = NULL;
+ jdoubleArray java_extents = NULL;
+
+ gdk_threads_enter ();
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
+ g_assert (pfont != NULL);
+
+ len = (*cp_gtk_gdk_env())->GetStringUTFLength (env, chars);
+ str = (gchar *)(*env)->GetStringUTFChars (env, chars, NULL);
+ g_assert (str != NULL);
+
+ if (attrs == NULL)
+ attrs = pango_attr_list_new ();
+
+ if (len > 0 && str[len-1] == '\0')
+ len--;
+
+ items = pango_itemize (pfont->ctx, str, 0, len, attrs, NULL);
+
+ i = g_list_first (items);
+
+ if (i == NULL)
+ {
+ gdk_threads_leave ();
+
+ java_extents = (*env)->NewDoubleArray (env, 0);
+ java_codes = (*env)->NewIntArray (env, 0);
+
+ gdk_threads_enter ();
+ }
+ else
+ {
+ PangoGlyphString *glyphs;
+ PangoItem *item = (PangoItem *)i->data;
+
+ pango_context_set_font_description (pfont->ctx, pfont->desc);
+ pango_context_set_language (pfont->ctx, gtk_get_default_language());
+ pango_context_load_font (pfont->ctx, pfont->desc);
+
+ glyphs = pango_glyph_string_new ();
+ g_assert (glyphs != NULL);
+
+ pango_shape (str + item->offset, item->length,
+ &(item->analysis), glyphs);
+
+ if (glyphs->num_glyphs > 0)
+ {
+ int x = 0;
+ double scale = ((double) PANGO_SCALE);
+
+ gdk_threads_leave ();
+
+ java_extents = (*env)->NewDoubleArray (env, glyphs->num_glyphs * NUM_GLYPH_METRICS);
+ java_codes = (*env)->NewIntArray (env, glyphs->num_glyphs);
+
+ gdk_threads_enter ();
+
+ native_extents = (*env)->GetDoubleArrayElements (env, java_extents, NULL);
+ native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
+
+ for (j = 0; j < glyphs->num_glyphs; ++j)
+ {
+ PangoRectangle ink;
+ PangoRectangle logical;
+ PangoGlyphGeometry *geom = &glyphs->glyphs[j].geometry;
+
+ pango_font_get_glyph_extents (pfont->font,
+ glyphs->glyphs[j].glyph,
+ &ink, &logical);
+
+ native_codes[j] = glyphs->glyphs[j].glyph;
+
+ native_extents[ GLYPH_LOG_X(j) ] = (logical.x) / scale;
+ native_extents[ GLYPH_LOG_Y(j) ] = (- logical.y) / scale;
+ native_extents[ GLYPH_LOG_WIDTH(j) ] = (logical.width) / scale;
+ native_extents[ GLYPH_LOG_HEIGHT(j) ] = (logical.height) / scale;
+
+ native_extents[ GLYPH_INK_X(j) ] = (ink.x) / scale;
+ native_extents[ GLYPH_INK_Y(j) ] = (- ink.y) / scale;
+ native_extents[ GLYPH_INK_WIDTH(j) ] = (ink.width) / scale;
+ native_extents[ GLYPH_INK_HEIGHT(j) ] = (ink.height) / scale;
+
+ native_extents[ GLYPH_POS_X(j) ] = (x + geom->x_offset) / scale;
+ native_extents[ GLYPH_POS_Y(j) ] = ( - geom->y_offset) / scale;
+
+ x += geom->width;
+ }
+ (*env)->ReleaseDoubleArrayElements (env, java_extents, native_extents, 0);
+ (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
+ }
+
+ pango_glyph_string_free (glyphs);
+ }
+
+ (*env)->ReleaseStringUTFChars (env, chars, str);
+
+ for (i = g_list_first (items); i != NULL; i = g_list_next (i))
+ g_free (i->data);
+
+ g_list_free (items);
+
+ gdk_threads_leave ();
+
+ return (*env)->NewObject (env,
+ glyphVector_class,
+ glyphVector_ctor,
+ java_extents, java_codes,
+ font, fontRenderContext);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics
+ (JNIEnv *env, jobject java_font, jdoubleArray java_metrics)
+{
+ struct peerfont *pfont = NULL;
+ jdouble *native_metrics = NULL;
+ PangoFontMetrics *pango_metrics = NULL;
+
+ gdk_threads_enter();
+
+ pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
+ g_assert (pfont != NULL);
+
+ pango_metrics
+ = pango_context_get_metrics (pfont->ctx, pfont->desc,
+ gtk_get_default_language ());
+
+ native_metrics
+ = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
+
+ g_assert (native_metrics != NULL);
+
+ native_metrics[FONT_METRICS_ASCENT]
+ = PANGO_PIXELS (pango_font_metrics_get_ascent (pango_metrics));
+
+ native_metrics[FONT_METRICS_MAX_ASCENT]
+ = native_metrics[FONT_METRICS_ASCENT];
+
+ native_metrics[FONT_METRICS_DESCENT]
+ = PANGO_PIXELS (pango_font_metrics_get_descent (pango_metrics));
+
+ if (native_metrics[FONT_METRICS_DESCENT] < 0)
+ native_metrics[FONT_METRICS_DESCENT]
+ = - native_metrics[FONT_METRICS_DESCENT];
+
+ native_metrics[FONT_METRICS_MAX_DESCENT]
+ = native_metrics[FONT_METRICS_DESCENT];
+
+ native_metrics[FONT_METRICS_MAX_ADVANCE]
+ = PANGO_PIXELS (pango_font_metrics_get_approximate_char_width
+ (pango_metrics));
+
+ (*env)->ReleaseDoubleArrayElements (env,
+ java_metrics,
+ native_metrics, 0);
+
+ pango_font_metrics_unref (pango_metrics);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics
+ (JNIEnv *env, jobject java_font, jstring str, jdoubleArray java_metrics)
+{
+ struct peerfont *pfont = NULL;
+ const char *cstr = NULL;
+ jdouble *native_metrics = NULL;
+ PangoRectangle log;
+
+ gdk_threads_enter();
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, java_font);
+ g_assert (pfont != NULL);
+
+ cstr = (*env)->GetStringUTFChars (env, str, NULL);
+ g_assert(cstr != NULL);
+
+ pango_layout_set_text (pfont->layout, cstr, -1);
+ pango_layout_get_extents (pfont->layout, NULL, &log);
+
+ (*env)->ReleaseStringUTFChars (env, str, cstr);
+ pango_layout_set_text (pfont->layout, "", -1);
+
+ native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
+ g_assert (native_metrics != NULL);
+
+ native_metrics[TEXT_METRICS_X_BEARING]
+ = PANGO_PIXELS( ((double)log.x) );
+
+ native_metrics[TEXT_METRICS_Y_BEARING]
+ = PANGO_PIXELS( ((double)log.y) );
+
+ native_metrics[TEXT_METRICS_WIDTH]
+ = PANGO_PIXELS( ((double)log.width) );
+
+ native_metrics[TEXT_METRICS_HEIGHT]
+ = PANGO_PIXELS( ((double)log.height) );
+
+ native_metrics[TEXT_METRICS_X_ADVANCE]
+ = PANGO_PIXELS( ((double) (log.x + log.width)) );
+
+ native_metrics[TEXT_METRICS_Y_ADVANCE]
+ = PANGO_PIXELS( ((double) (log.y + log.height)) );
+
+ (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0);
+
+ gdk_threads_leave();
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
+ (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size, jboolean useGraphics2D)
+{
+ struct peerfont *pfont = NULL;
+ char const *family_name = NULL;
+ enum java_awt_font_style style;
+ PangoFT2FontMap *ft2_map = NULL;
+
+ gdk_threads_enter ();
+
+ style = (enum java_awt_font_style) style_int;
+
+ g_assert (self != NULL);
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
+ g_assert (pfont != NULL);
+
+ if (pfont->ctx != NULL)
+ g_object_unref (pfont->ctx);
+ if (pfont->font != NULL)
+ g_object_unref (pfont->font);
+ if (pfont->desc != NULL)
+ pango_font_description_free (pfont->desc);
+
+ pfont->desc = pango_font_description_new ();
+ g_assert (pfont->desc != NULL);
+
+ family_name = (*env)->GetStringUTFChars(env, family_name_str, 0);
+ g_assert (family_name != NULL);
+ pango_font_description_set_family (pfont->desc, family_name);
+ (*env)->ReleaseStringUTFChars(env, family_name_str, family_name);
+
+
+ if (style & java_awt_font_BOLD)
+ pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD);
+
+ if (style & java_awt_font_ITALIC)
+ pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC);
+
+ if (useGraphics2D)
+ {
+ pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
+ if (pfont->ctx == NULL)
+ {
+ ft2_map = PANGO_FT2_FONT_MAP(pango_ft2_font_map_for_display ());
+ pfont->ctx = pango_ft2_font_map_create_context (ft2_map);
+ }
+ }
+ else
+ {
+ /* GDK uses a slightly different DPI setting. */
+ pango_font_description_set_size (pfont->desc,
+ size * cp_gtk_dpi_conversion_factor);
+ if (pfont->ctx == NULL)
+ pfont->ctx = gdk_pango_context_get();
+ }
+
+ g_assert (pfont->ctx != NULL);
+
+ if (pfont->font != NULL)
+ {
+ g_object_unref (pfont->font);
+ pfont->font = NULL;
+ }
+
+ pango_context_set_font_description (pfont->ctx, pfont->desc);
+ pango_context_set_language (pfont->ctx, gtk_get_default_language());
+ pfont->font = pango_context_load_font (pfont->ctx, pfont->desc);
+ g_assert (pfont->font != NULL);
+
+ if (pfont->layout == NULL)
+ pfont->layout = pango_layout_new (pfont->ctx);
+ g_assert (pfont->layout != NULL);
+
+ gdk_threads_leave ();
+}
+
+
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c
new file mode 100644
index 00000000000..9b2f16e7145
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c
@@ -0,0 +1,642 @@
+/* gdkgraphics.c
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "gtkpeer.h"
+#include "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_GdkGraphics.h"
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+
+static jmethodID initComponentGraphicsID;
+
+void
+cp_gtk_graphics_init_jni (void)
+{
+ jclass gdkgraphics;
+
+ gdkgraphics = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GdkGraphics");
+
+ initComponentGraphicsID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gdkgraphics,
+ "initComponentGraphics",
+ "()V");
+}
+
+#define GDK_STABLE_IS_PIXMAP(d) (GDK_IS_PIXMAP(d))
+
+static GdkPoint *translate_points (JNIEnv *env, jintArray xpoints,
+ jintArray ypoints, jint npoints,
+ jint x_offset, jint y_offset);
+static void realize_cb (GtkWidget *widget, jobject jgraphics);
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_copyState
+ (JNIEnv *env, jobject obj, jobject old)
+{
+ struct graphics *g = NULL;
+ struct graphics *g_old = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) g_malloc (sizeof (struct graphics));
+ g_old = (struct graphics *) NSA_GET_PTR (env, old);
+
+ *g = *g_old;
+
+ g->gc = gdk_gc_new (g->drawable);
+ gdk_gc_copy (g->gc, g_old->gc);
+
+ if (GDK_STABLE_IS_PIXMAP (g->drawable))
+ gdk_pixmap_ref (g->drawable);
+ else /* GDK_IS_WINDOW (g->drawable) */
+ gdk_window_ref (g->drawable);
+
+ gdk_colormap_ref (g->cm);
+
+ NSA_SET_PTR (env, obj, g);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__II
+ (JNIEnv *env, jobject obj, jint width, jint height)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) g_malloc (sizeof (struct graphics));
+ g->x_offset = g->y_offset = 0;
+
+ g->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
+ gdk_rgb_get_visual ()->depth);
+ g->cm = gdk_rgb_get_cmap ();
+ gdk_colormap_ref (g->cm);
+ g->gc = gdk_gc_new (g->drawable);
+
+ NSA_SET_PTR (env, obj, g);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_initFromImage
+ (JNIEnv *env, jobject obj, jobject source)
+{
+ struct graphics *g = NULL;
+ GdkPixmap *pixmap = NULL;
+
+ gdk_threads_enter ();
+
+ pixmap = cp_gtk_image_get_pixmap (env, source);
+ g_assert(pixmap != NULL);
+ gdk_pixmap_ref (pixmap);
+
+ g = (struct graphics *) g_malloc (sizeof (struct graphics));
+ g->x_offset = g->y_offset = 0;
+
+ g->drawable = (GdkDrawable *)pixmap;
+
+ g->cm = gdk_drawable_get_colormap (g->drawable);
+ gdk_colormap_ref (g->cm);
+ g->gc = gdk_gc_new (g->drawable);
+
+ NSA_SET_PTR (env, obj, g);
+
+ gdk_threads_leave ();
+}
+
+/* copy the native state of the peer (GtkWidget *) to the native state
+ of the graphics object */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
+ (JNIEnv *env, jobject obj, jobject peer)
+{
+ struct graphics *g = NULL;
+ void *ptr = NULL;
+ GtkWidget *widget = NULL;
+ GdkColor color;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) g_malloc (sizeof (struct graphics));
+ ptr = NSA_GET_PTR (env, peer);
+ g->x_offset = 0;
+ g->y_offset = 0;
+
+ widget = GTK_WIDGET (ptr);
+ g->drawable = (GdkDrawable *) widget->window;
+
+ gdk_window_ref (g->drawable);
+ g->cm = gtk_widget_get_colormap (widget);
+ gdk_colormap_ref (g->cm);
+ g->gc = gdk_gc_new (g->drawable);
+ gdk_gc_copy (g->gc, widget->style->fg_gc[GTK_STATE_NORMAL]);
+ color = widget->style->fg[GTK_STATE_NORMAL];
+
+ NSA_SET_PTR (env, obj, g);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_connectSignals
+ (JNIEnv *env, jobject obj, jobject peer)
+{
+ void *ptr = NULL;
+ jobject *gref = NULL;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ ptr = NSA_GET_PTR (env, peer);
+
+ g_signal_connect_after (G_OBJECT (ptr), "realize",
+ G_CALLBACK (realize_cb), *gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_dispose
+ (JNIEnv *env, jobject obj)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_DEL_PTR (env, obj);
+
+ /* check if dispose has been called already */
+ if (!g)
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ XFlush (GDK_DISPLAY ());
+
+ gdk_gc_destroy (g->gc);
+
+ if (GDK_STABLE_IS_PIXMAP (g->drawable))
+ gdk_pixmap_unref (g->drawable);
+ else /* GDK_IS_WINDOW (g->drawable) */
+ gdk_window_unref (g->drawable);
+
+ gdk_colormap_unref (g->cm);
+
+ g_free (g);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative
+ (JNIEnv *env, jobject obj, jint x, jint y)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ g->x_offset += x;
+ g->y_offset += y;
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString
+ (JNIEnv *env, jobject obj, jobject font, jstring str, jint x, jint y)
+{
+ struct peerfont *pfont = NULL;
+ struct graphics *g = NULL;
+ const char *cstr = NULL;
+ int baseline_y = 0;
+ PangoLayoutIter *iter = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+ g_assert (g != NULL);
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert (pfont != NULL);
+
+ cstr = (*env)->GetStringUTFChars (env, str, NULL);
+
+ pango_layout_set_font_description (pfont->layout, pfont->desc);
+ pango_layout_set_text (pfont->layout, cstr, -1);
+ iter = pango_layout_get_iter (pfont->layout);
+
+ baseline_y = pango_layout_iter_get_baseline (iter);
+
+ gdk_draw_layout (g->drawable, g->gc,
+ x + g->x_offset,
+ y + g->y_offset - PANGO_PIXELS (baseline_y),
+ pfont->layout);
+
+ pango_layout_iter_free (iter);
+ pango_layout_set_text (pfont->layout, "", -1);
+
+ gdk_flush ();
+
+ (*env)->ReleaseStringUTFChars (env, str, cstr);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine
+ (JNIEnv *env, jobject obj, jint x, jint y, jint x2, jint y2)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ gdk_draw_line (g->drawable, g->gc,
+ x + g->x_offset, y + g->y_offset,
+ x2 + g->x_offset, y2 + g->y_offset);
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_fillRect
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ gdk_draw_rectangle (g->drawable, g->gc, TRUE,
+ x + g->x_offset, y + g->y_offset, width, height);
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_drawRect
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ gdk_draw_rectangle (g->drawable, g->gc, FALSE,
+ x + g->x_offset, y + g->y_offset, width, height);
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea
+ (JNIEnv *env, jobject obj, jint x, jint y,
+ jint width, jint height, jint dx, jint dy)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ gdk_window_copy_area ((GdkWindow *)g->drawable,
+ g->gc,
+ x + g->x_offset + dx, y + g->y_offset + dy,
+ (GdkWindow *)g->drawable,
+ x + g->x_offset, y + g->y_offset,
+ width, height);
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+ struct graphics *g = NULL;
+ GdkGCValues saved;
+ GtkWidget *widget = NULL;
+ union widget_union w;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ if (!g)
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ if (GDK_IS_WINDOW (g->drawable))
+ {
+ w.widget = &widget;
+ gdk_window_get_user_data (GDK_WINDOW (g->drawable), w.void_widget);
+ if (widget == NULL || !GTK_IS_EVENT_BOX (widget))
+ gdk_window_clear_area ((GdkWindow *) g->drawable,
+ x + g->x_offset, y + g->y_offset,
+ width, height);
+ }
+ else
+ {
+ gdk_gc_get_values (g->gc, &saved);
+ gdk_gc_set_foreground (g->gc, &(saved.background));
+ gdk_draw_rectangle (g->drawable, g->gc, TRUE,
+ x + g->x_offset, y + g->y_offset, width, height);
+ gdk_gc_set_foreground (g->gc, &(saved.foreground));
+ }
+
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_setFunction
+ (JNIEnv *env, jobject obj, jint func)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ gdk_gc_set_function (g->gc, func);
+
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_setFGColor
+ (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
+{
+ GdkColor color;
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ color.red = red << 8;
+ color.green = green << 8;
+ color.blue = blue << 8;
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ gdk_color_alloc (g->cm, &color);
+ gdk_gc_set_foreground (g->gc, &color);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_drawArc
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height,
+ jint angle1, jint angle2)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ gdk_draw_arc (g->drawable, g->gc, FALSE,
+ x + g->x_offset, y + g->y_offset,
+ width, height, angle1 << 6, angle2 << 6);
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+static GdkPoint *
+translate_points (JNIEnv *env, jintArray xpoints, jintArray ypoints,
+ jint npoints, jint x_offset, jint y_offset)
+{
+ GdkPoint *points;
+ jint *x, *y;
+ int i;
+
+ /* allocate one more point than necessary, in case we need to tack
+ on an extra due to the semantics of Java polygons. */
+ points = g_malloc (sizeof (GdkPoint) * (npoints + 1));
+
+ x = (*env)->GetIntArrayElements (env, xpoints, NULL);
+ y = (*env)->GetIntArrayElements (env, ypoints, NULL);
+
+ for (i = 0; i < npoints; i++)
+ {
+ points[i].x = x[i] + x_offset;
+ points[i].y = y[i] + y_offset;
+ }
+
+ (*env)->ReleaseIntArrayElements (env, xpoints, x, JNI_ABORT);
+ (*env)->ReleaseIntArrayElements (env, ypoints, y, JNI_ABORT);
+
+ return points;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline
+ (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
+ jint npoints)
+{
+ struct graphics *g = NULL;
+ GdkPoint *points = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+ points = translate_points (env, xpoints, ypoints, npoints,
+ g->x_offset, g->y_offset);
+
+ gdk_draw_lines (g->drawable, g->gc, points, npoints);
+ gdk_flush ();
+
+ g_free (points);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon
+ (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
+ jint npoints)
+{
+ struct graphics *g = NULL;
+ GdkPoint *points = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+ points = translate_points (env, xpoints, ypoints, npoints,
+ g->x_offset, g->y_offset);
+
+ /* make sure the polygon is closed, per Java semantics.
+ if it's not, we close it. */
+ if (points[0].x != points[npoints-1].x || points[0].y != points[npoints-1].y)
+ points[npoints++] = points[0];
+
+ gdk_draw_lines (g->drawable, g->gc, points, npoints);
+ gdk_flush ();
+
+ g_free (points);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon
+ (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
+ jint npoints)
+{
+ struct graphics *g = NULL;
+ GdkPoint *points = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+ points = translate_points (env, xpoints, ypoints, npoints,
+ g->x_offset, g->y_offset);
+ gdk_draw_polygon (g->drawable, g->gc, TRUE, points, npoints);
+ gdk_flush ();
+
+ g_free (points);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height,
+ jint angle1, jint angle2)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ gdk_draw_arc (g->drawable, g->gc, TRUE,
+ x + g->x_offset, y + g->y_offset,
+ width, height, angle1 << 6, angle2 << 6);
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_drawOval
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ gdk_draw_arc (g->drawable, g->gc, FALSE,
+ x + g->x_offset, y + g->y_offset,
+ width, height, 0, 23040);
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_fillOval
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+ struct graphics *g = NULL;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ gdk_draw_arc (g->drawable, g->gc, TRUE,
+ x + g->x_offset, y + g->y_offset,
+ width, height, 0, 23040);
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics_setClipRectangle
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+ struct graphics *g = NULL;
+ GdkRectangle rectangle;
+
+ gdk_threads_enter ();
+
+ g = (struct graphics *) NSA_GET_PTR (env, obj);
+
+ rectangle.x = x + g->x_offset;
+ rectangle.y = y + g->y_offset;
+ rectangle.width = width;
+ rectangle.height = height;
+
+ gdk_gc_set_clip_rectangle (g->gc, &rectangle);
+
+ gdk_threads_leave ();
+}
+
+static void
+realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject jgraphics)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), jgraphics, initComponentGraphicsID);
+
+ NSA_DEL_GLOBAL_REF (cp_gtk_gdk_env(), jgraphics);
+
+ gdk_threads_enter ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
new file mode 100644
index 00000000000..b4bd676e7b9
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
@@ -0,0 +1,1881 @@
+/* gnu_java_awt_peer_gtk_GdkGraphics2d.c
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+#include "gtkcairopeer.h"
+#include "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_GdkGraphics2D.h"
+#include <gdk/gdktypes.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+#include <X11/extensions/Xrender.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixdata.h>
+
+#include <cairo-ft.h>
+#include <cairo-xlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static jmethodID initComponentGraphics2DID;
+
+void
+cp_gtk_graphics2d_init_jni (void)
+{
+ jclass gdkgraphics2d;
+
+ gdkgraphics2d = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GdkGraphics2D");
+
+ initComponentGraphics2DID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gdkgraphics2d,
+ "initComponentGraphics2D",
+ "()V");
+}
+
+static struct state_table *native_graphics2d_state_table;
+
+#define NSA_G2D_INIT(env, clazz) \
+ native_graphics2d_state_table = cp_gtk_init_state_table (env, clazz)
+
+#define NSA_GET_G2D_PTR(env, obj) \
+ cp_gtk_get_state (env, obj, native_graphics2d_state_table)
+
+#define NSA_SET_G2D_PTR(env, obj, ptr) \
+ cp_gtk_set_state (env, obj, native_graphics2d_state_table, (void *)ptr)
+
+#define NSA_DEL_G2D_PTR(env, obj) \
+ cp_gtk_remove_state_slot (env, obj, native_graphics2d_state_table)
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState
+ (JNIEnv *env, jclass clazz)
+{
+ gdk_threads_enter();
+
+ NSA_G2D_INIT (env, clazz);
+
+ gdk_threads_leave();
+}
+
+/* these public final constants are part of the java2d public API, so we
+ write them explicitly here to save fetching them from the constant pool
+ all the time. */
+
+#ifndef min
+#define min(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
+enum java_awt_alpha_composite_rule
+ {
+ java_awt_alpha_composite_CLEAR = 1,
+ java_awt_alpha_composite_SRC = 2,
+ java_awt_alpha_composite_SRC_OVER = 3,
+ java_awt_alpha_composite_DST_OVER = 4,
+ java_awt_alpha_composite_SRC_IN = 5,
+ java_awt_alpha_composite_DST_IN = 6,
+ java_awt_alpha_composite_SRC_OUT = 7,
+ java_awt_alpha_composite_DST_OUT = 8,
+ java_awt_alpha_composite_DST = 9,
+ java_awt_alpha_composite_SRC_ATOP = 10,
+ java_awt_alpha_composite_DST_ATOP = 11,
+ java_awt_alpha_composite_XOR = 12
+ };
+
+enum java_awt_basic_stroke_join_rule
+ {
+ java_awt_basic_stroke_JOIN_MITER = 0,
+ java_awt_basic_stroke_JOIN_ROUND = 1,
+ java_awt_basic_stroke_JOIN_BEVEL = 2
+ };
+
+enum java_awt_basic_stroke_cap_rule
+ {
+ java_awt_basic_stroke_CAP_BUTT = 0,
+ java_awt_basic_stroke_CAP_ROUND = 1,
+ java_awt_basic_stroke_CAP_SQUARE = 2
+ };
+
+enum java_awt_geom_path_iterator_winding_rule
+ {
+ java_awt_geom_path_iterator_WIND_EVEN_ODD = 0,
+ java_awt_geom_path_iterator_WIND_NON_ZERO = 1
+ };
+
+enum java_awt_rendering_hints_filter
+ {
+ java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0,
+ java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
+ java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
+ java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
+ java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
+
+ };
+
+static int
+peer_is_disposed(JNIEnv *env, jobject obj)
+{
+ static jfieldID fid = NULL;
+ jclass cls;
+ jobject peer;
+
+ return 0;
+
+ if (fid == NULL)
+ {
+ cls = (*env)->GetObjectClass(env, obj);
+ fid = (*env)->GetFieldID(env, cls, "component",
+ "Lgnu/java/awt/peer/gtk/GtkComponentPeer;");
+ }
+ g_assert(fid != NULL);
+ peer = (*env)->GetObjectField(env, obj, fid);
+ if (peer == NULL || NSA_GET_PTR (env, peer) != NULL)
+ return 0;
+ else
+ {
+ return 1;
+ }
+}
+
+
+static void
+grab_current_drawable (GtkWidget *widget, GdkDrawable **draw, GdkWindow **win)
+{
+ g_assert (widget != NULL);
+ g_assert (draw != NULL);
+ g_assert (win != NULL);
+
+ *win = widget->window;
+
+ *draw = *win;
+ gdk_window_get_internal_paint_info (*win, draw, 0, 0);
+ g_object_ref (*draw);
+}
+
+
+static int
+x_server_has_render_extension (void)
+{
+ int ev = 0, err = 0;
+ return (int) XRenderQueryExtension (GDK_DISPLAY (), &ev, &err);
+}
+
+static void
+init_graphics2d_as_pixbuf (struct graphics2d *gr)
+{
+ gint width, height;
+ gint bits_per_sample = 8;
+ gint total_channels = 4;
+ gboolean has_alpha = TRUE;
+
+ g_assert (gr != NULL);
+ g_assert (gr->drawable != NULL);
+
+ if (gr->debug) printf ("initializing graphics2d as pixbuf\n");
+ gdk_drawable_get_size (gr->drawable, &width, &height);
+ gr->drawbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ has_alpha, bits_per_sample,
+ width, height);
+ g_assert (gr->drawbuf != NULL);
+ g_assert (gdk_pixbuf_get_bits_per_sample (gr->drawbuf) == bits_per_sample);
+ g_assert (gdk_pixbuf_get_n_channels (gr->drawbuf) == total_channels);
+
+ gr->surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (gr->drawbuf),
+ CAIRO_FORMAT_ARGB32,
+ gdk_pixbuf_get_width (gr->drawbuf),
+ gdk_pixbuf_get_height (gr->drawbuf),
+ gdk_pixbuf_get_rowstride (gr->drawbuf));
+ g_assert (gr->surface != NULL);
+ gr->mode = MODE_DRAWABLE_NO_RENDER;
+ if (gr->cr != NULL)
+ cairo_destroy (gr->cr);
+ gr->cr = cairo_create (gr->surface);
+}
+
+static void
+init_graphics2d_as_renderable (struct graphics2d *gr)
+{
+ Drawable draw;
+ Display * dpy;
+ Visual * vis;
+
+ g_assert (gr != NULL);
+ g_assert (gr->drawable != NULL);
+
+ gr->drawbuf = NULL;
+
+ if (gr->debug) printf ("initializing graphics2d as renderable\n");
+ draw = gdk_x11_drawable_get_xid (gr->drawable);
+
+ dpy = gdk_x11_drawable_get_xdisplay (gr->drawable);
+ g_assert (dpy != NULL);
+
+ vis = gdk_x11_visual_get_xvisual (gdk_drawable_get_visual (gr->drawable));
+ g_assert (vis != NULL);
+
+ gr->surface = cairo_xlib_surface_create (dpy, draw, vis, gr->width, gr->height);
+ g_assert (gr->surface != NULL);
+ gr->mode = MODE_DRAWABLE_WITH_RENDER;
+ if (gr->cr != NULL)
+ cairo_destroy (gr->cr);
+ gr->cr = cairo_create (gr->surface);
+}
+
+static void
+begin_drawing_operation (JNIEnv *env, struct graphics2d * gr)
+{
+ g_assert(cairo_status (gr->cr) == CAIRO_STATUS_SUCCESS);
+
+ switch (gr->mode)
+ {
+ case MODE_DRAWABLE_WITH_RENDER:
+ break;
+
+ case MODE_DRAWABLE_NO_RENDER:
+ {
+
+ gint drawable_width, drawable_height;
+ gint pixbuf_width, pixbuf_height;
+ gint width, height;
+
+ gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
+ pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
+ pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
+ width = min (drawable_width, pixbuf_width);
+ height = min (drawable_height, pixbuf_height);
+
+ gdk_pixbuf_get_from_drawable (gr->drawbuf, /* destination pixbuf */
+ gr->drawable,
+ NULL, /* colormap */
+ 0, 0, 0, 0,
+ width, height);
+
+ if (gr->debug) printf ("copied (%d, %d) pixels from GDK drawable to pixbuf\n",
+ width, height);
+ }
+ break;
+
+ case MODE_JAVA_ARRAY:
+ {
+ jboolean isCopy;
+ gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &isCopy);
+ gr->isCopy |= isCopy;
+ if (gr->isCopy)
+ {
+ /* Make sure that the pixel buffer copy is already initalized,
+ i.e. we already failed to get direct access in initState. */
+ g_assert (gr->javabuf_copy != NULL);
+ memcpy (gr->javabuf_copy, gr->javabuf, gr->width * gr->height * 4);
+ }
+ }
+ break;
+ }
+}
+
+static void
+end_drawing_operation (JNIEnv *env, struct graphics2d * gr)
+{
+ g_assert(cairo_status (gr->cr) == CAIRO_STATUS_SUCCESS);
+
+ switch (gr->mode)
+ {
+ case MODE_DRAWABLE_WITH_RENDER:
+ break;
+
+ case MODE_DRAWABLE_NO_RENDER:
+ {
+
+ gint drawable_width, drawable_height;
+ gint pixbuf_width, pixbuf_height;
+ gint width, height;
+
+ gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
+ pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
+ pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
+ width = min (drawable_width, pixbuf_width);
+ height = min (drawable_height, pixbuf_height);
+
+ gdk_draw_pixbuf (gr->drawable, NULL, gr->drawbuf,
+ 0, 0, 0, 0,
+ width, height,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+
+ if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n",
+ width, height);
+ }
+ break;
+
+ case MODE_JAVA_ARRAY:
+ if (gr->isCopy)
+ memcpy (gr->javabuf, gr->javabuf_copy, gr->width * gr->height * 4);
+ (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT);
+ }
+}
+
+
+static void
+update_pattern_transform (struct graphics2d *gr)
+{
+ cairo_matrix_t mat;
+
+ g_assert (gr != NULL);
+ if (gr->pattern == NULL)
+ return;
+
+ cairo_get_matrix (gr->cr, &mat);
+ cairo_pattern_set_matrix (gr->pattern, &mat);
+}
+
+static void
+check_for_debug (struct graphics2d *gr)
+{
+ gr->debug = (gboolean)(getenv("DEBUGJ2D") != NULL);
+}
+
+static void
+realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer, initComponentGraphics2DID);
+
+ gdk_threads_enter ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
+ (JNIEnv *env, jobject obj, jobject old)
+{
+ struct graphics2d *g = NULL, *g_old = NULL;
+
+ gdk_threads_enter();
+
+ g = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
+ g_assert (g != NULL);
+ memset (g, 0, sizeof(struct graphics2d));
+
+ g_old = (struct graphics2d *) NSA_GET_G2D_PTR (env, old);
+ g_assert (g_old != NULL);
+
+ if (g_old->debug) printf ("copying state from existing graphics2d\n");
+
+ g->debug = g_old->debug;
+ g->mode = g_old->mode;
+
+ g->width = g_old->width;
+ g->height = g_old->height;
+
+ if (g_old->mode == MODE_JAVA_ARRAY)
+ {
+ jint size = g->width * g->height * 4;
+
+ g->jarray = (*env)->NewGlobalRef (env, g_old->jarray);
+ g->javabuf = (*env)->GetIntArrayElements (env, g->jarray, &g->isCopy);
+ g->isCopy = JNI_TRUE;
+ g->javabuf_copy = (jint *) g_malloc (size);
+ memcpy (g->javabuf_copy, g->javabuf, size);
+ g->surface = cairo_image_surface_create_for_data ((unsigned char *) g->javabuf,
+ CAIRO_FORMAT_ARGB32,
+ g->width,
+ g->height,
+ g->width * 4);
+ g_assert (g->surface != NULL);
+ g->cr = cairo_create (g->surface);
+ g_assert (g->cr != NULL);
+ (*env)->ReleaseIntArrayElements (env, g->jarray, g->javabuf, JNI_ABORT);
+ }
+ else
+ {
+ g->drawable = g_old->drawable;
+ g_object_ref (g->drawable);
+
+ if (x_server_has_render_extension ())
+ init_graphics2d_as_renderable (g);
+ else
+ init_graphics2d_as_pixbuf (g);
+ }
+
+ if (g->pattern)
+ cairo_pattern_set_filter (g->pattern, CAIRO_FILTER_FAST);
+
+ NSA_SET_G2D_PTR (env, obj, g);
+
+ gdk_threads_leave();
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState___3III
+(JNIEnv *env, jobject obj, jintArray jarr, jint width, jint height)
+{
+ struct graphics2d *gr = NULL;
+ jint *cairobuf = NULL;
+
+ gdk_threads_enter();
+
+ gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
+ g_assert (gr != NULL);
+ memset (gr, 0, sizeof(struct graphics2d));
+
+ check_for_debug (gr);
+
+ if (gr->debug) printf ("constructing java-backed image of size (%d,%d)\n",
+ width, height);
+
+ gr->width = width;
+ gr->height = height;
+ gr->jarray = (*env)->NewGlobalRef(env, jarr);
+ gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &gr->isCopy);
+ if (gr->isCopy)
+ {
+ /* We didn't get direct access to the pixel buffer, so we'll have to
+ maintain a separate copy for Cairo. */
+ jint size = gr->width * gr->height * 4;
+ gr->javabuf_copy = (jint *) g_malloc (size);
+ memcpy (gr->javabuf_copy, gr->javabuf, size);
+ cairobuf = gr->javabuf_copy;
+ }
+ else
+ {
+ /* Have Cairo write directly to the Java array. */
+ cairobuf = gr->javabuf;
+ }
+ gr->surface = cairo_image_surface_create_for_data ((unsigned char *) cairobuf,
+ CAIRO_FORMAT_ARGB32,
+ gr->width,
+ gr->height,
+ gr->width * 4);
+ g_assert (gr->surface != NULL);
+ gr->cr = cairo_create (gr->surface);
+ g_assert (gr->cr != NULL);
+ (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT);
+
+ gr->mode = MODE_JAVA_ARRAY;
+
+ if (gr->debug) printf ("constructed java-backed image of size (%d,%d)\n",
+ width, height);
+
+ NSA_SET_G2D_PTR (env, obj, gr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II
+ (JNIEnv *env, jobject obj, jint width, jint height)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
+ g_assert (gr != NULL);
+ memset (gr, 0, sizeof(struct graphics2d));
+
+ check_for_debug (gr);
+
+ if (gr->debug) printf ("constructing offscreen drawable of size (%d,%d)\n",
+ width, height);
+
+ gr->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
+ gdk_rgb_get_visual ()->depth);
+ g_assert (gr->drawable != NULL);
+
+ gr->width = width;
+ gr->height = height;
+
+ if (x_server_has_render_extension ())
+ init_graphics2d_as_renderable (gr);
+ else
+ init_graphics2d_as_pixbuf (gr);
+
+ if (gr->debug) printf ("constructed offscreen drawable of size (%d,%d)\n",
+ width, height);
+ NSA_SET_G2D_PTR (env, obj, gr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
+ (JNIEnv *env, jobject self, jobject other, jint x, jint y)
+{
+ struct graphics2d *src = NULL;
+ struct graphics2d *dst = NULL;
+ gint s_height;
+ gint s_width;
+ gint d_height;
+ gint d_width;
+ gint height;
+ gint width;
+ cairo_matrix_t matrix;
+ cairo_operator_t tmp_op;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, self))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ src = (struct graphics2d *)NSA_GET_G2D_PTR (env, other);
+ dst = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
+ g_assert (src != NULL);
+ g_assert (dst != NULL);
+
+ if (src->debug) printf ("copying from offscreen drawable\n");
+
+ begin_drawing_operation(env, dst);
+
+ /* gdk_flush(); */
+
+ gdk_drawable_get_size (src->drawable, &s_width, &s_height);
+ gdk_drawable_get_size (dst->drawable, &d_width, &d_height);
+ width = min (s_width, d_width);
+ height = min (s_height, d_height);
+
+ cairo_get_matrix (src->cr, &matrix);
+ cairo_matrix_translate (&matrix, (double)-x, (double)-y);
+ if (src->pattern)
+ cairo_pattern_set_matrix (src->pattern, &matrix);
+ tmp_op = cairo_get_operator (dst->cr);
+ cairo_set_operator(dst->cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface (dst->cr, src->surface, 0, 0);
+ cairo_paint (dst->cr);
+ cairo_set_operator(dst->cr, tmp_op);
+
+ cairo_matrix_translate (&matrix, (double)x, (double)y);
+ if (src->pattern)
+ cairo_pattern_set_matrix (src->pattern, &matrix);
+
+ gdk_flush();
+
+ end_drawing_operation(env, dst);
+
+ if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
+ (JNIEnv *env, jobject obj, jobject peer)
+{
+ struct graphics2d *gr = NULL;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
+ g_assert (gr != NULL);
+ memset (gr, 0, sizeof(struct graphics2d));
+
+ check_for_debug (gr);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ grab_current_drawable (widget, &(gr->drawable), &(gr->win));
+ g_assert (gr->drawable != NULL);
+
+ gr->width = widget->allocation.width;
+ gr->height = widget->allocation.height;
+
+ if (x_server_has_render_extension ())
+ init_graphics2d_as_renderable (gr);
+ else
+ init_graphics2d_as_pixbuf (gr);
+
+ NSA_SET_G2D_PTR (env, obj, gr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_connectSignals
+ (JNIEnv *env, jobject obj, jobject peer)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, peer);
+
+ g_signal_connect_after (G_OBJECT (ptr), "realize",
+ G_CALLBACK (realize_cb), obj);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
+ (JNIEnv *env, jobject obj)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ gr = (struct graphics2d *) NSA_DEL_G2D_PTR (env, obj);
+
+ if (gr == NULL)
+ {
+ gdk_threads_leave();
+ return; /* dispose has been called more than once */
+ }
+
+ if (gr->surface)
+ cairo_surface_destroy (gr->surface);
+
+ cairo_destroy (gr->cr);
+
+ if (gr->drawbuf)
+ g_object_unref (gr->drawbuf);
+
+ if (gr->drawable)
+ g_object_unref (gr->drawable);
+
+ if (gr->pattern)
+ cairo_pattern_destroy (gr->pattern);
+
+ if (gr->pattern_surface)
+ cairo_surface_destroy (gr->pattern_surface);
+
+ if (gr->pattern_pixels)
+ g_free (gr->pattern_pixels);
+
+ if (gr->mode == MODE_JAVA_ARRAY)
+ {
+ (*env)->DeleteGlobalRef (env, gr->jarray);
+ if (gr->javabuf_copy)
+ g_free (gr->javabuf_copy);
+ }
+
+ if (gr->debug) printf ("disposed of graphics2d\n");
+
+ g_free (gr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradient
+ (JNIEnv *env, jobject obj,
+ jdouble x1, jdouble y1,
+ jdouble x2, jdouble y2,
+ jint r1, jint g1, jint b1, jint a1,
+ jint r2, jint g2, jint b2, jint a2,
+ jboolean cyclic)
+{
+ struct graphics2d *gr = NULL;
+ cairo_surface_t *surf = NULL;
+ cairo_t *cr2 = NULL;
+ cairo_matrix_t mat;
+
+ gdk_threads_enter();
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ if (gr->debug) printf ("setGradient (%f,%f) -> (%f,%f); (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n",
+ x1, y1,
+ x2, y2,
+ r1, g1, b1, a1,
+ r2, g2, b2, a2);
+
+ if (cyclic)
+ surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 3, 2);
+ else
+ surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 2, 2);
+ g_assert (surf != NULL);
+
+ cr2 = cairo_create (surf);
+
+ cairo_identity_matrix (cr2);
+
+ cairo_set_source_rgba (cr2, r1 / 255.0, g1 / 255.0, b1 / 255.0, a1 / 255.0);
+ cairo_rectangle (cr2, 0, 0, 1, 2);
+ cairo_fill (cr2);
+
+ cairo_set_source_rgba (cr2, r2 / 255.0, g2 / 255.0, b2 / 255.0, a2 / 255.0);
+ cairo_rectangle (cr2, 1, 0, 1, 2);
+ cairo_fill (cr2);
+
+ if (cyclic)
+ {
+ cairo_set_source_rgba (cr2, r1 / 255.0, g1 / 255.0, b1 / 255.0, a1 / 255.0);
+ cairo_rectangle (cr2, 2, 0, 1, 2);
+ cairo_fill (cr2);
+ }
+
+ cairo_matrix_init_identity (&mat);
+
+ /*
+ consider the vector [x2 - x1, y2 - y1] = [p,q]
+
+ this is a line in space starting at an 'origin' x1, y1.
+
+ it can also be thought of as a "transformed" unit vector in either the
+ x or y directions. we have just *drawn* our gradient as a unit vector
+ (well, a 2-3x unit vector) in the x dimension. so what we want to know
+ is which transformation turns our existing unit vector into [p,q].
+
+ which means solving for M in
+
+ [p,q] = M[1,0]
+
+ [p,q] = |a b| [1,0]
+ |c d|
+
+ [p,q] = [a,c], with b = d = 0.
+
+ what does this mean? it means that our gradient is 1-dimensional; as
+ you move through the x axis of our 2 or 3 pixel gradient from logical
+ x positions 0 to 1, the transformation of your x coordinate under the
+ matrix M causes you to accumulate both x and y values in fill
+ space. the y value of a gradient coordinate is ignored, since the
+ gradient is one dimensional. which is correct.
+
+ unfortunately we want the opposite transformation, it seems, because of
+ the way cairo is going to use this transformation. I'm a bit confused by
+ that, but it seems to work right, so we take reciprocals of values and
+ negate offsets. oh well.
+
+ */
+ {
+ double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1));
+ double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1));
+ double dx = (x1 == 0.) ? 0. : 1. / x1;
+ double dy = (y1 == 0.) ? 0. : 1. / y1;
+ cairo_pattern_t *p;
+
+ cairo_matrix_init (&mat,
+ a, 0.,
+ c, 0.,
+ dx, dy);
+
+ p = cairo_pattern_create_for_surface (surf);
+ cairo_pattern_set_matrix (p, &mat);
+ cairo_pattern_set_filter (p, CAIRO_FILTER_BILINEAR);
+ }
+
+ /* FIXME: repeating gradients (not to mention hold gradients) don't seem to work. */
+ /* cairo_surface_set_repeat (surf, cyclic ? 1 : 0); */
+
+ if (gr->pattern)
+ cairo_pattern_destroy (gr->pattern);
+
+ if (gr->pattern_surface)
+ cairo_surface_destroy (gr->pattern_surface);
+
+ if (gr->pattern_pixels)
+ g_free (gr->pattern_pixels);
+
+ gr->pattern_pixels = NULL;
+ gr->pattern_surface = surf;
+ gr->pattern = cairo_pattern_create_for_surface(surf);
+
+ cairo_set_source (gr->cr, gr->pattern);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels
+ (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
+{
+ struct graphics2d *gr = NULL;
+ jint *jpixels = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+
+ if (gr->debug) printf ("setTexturePixels (%d pixels, %dx%d, stride: %d)\n",
+ (*env)->GetArrayLength (env, jarr), w, h, stride);
+
+ if (gr->pattern)
+ cairo_pattern_destroy (gr->pattern);
+
+ if (gr->pattern_surface)
+ cairo_surface_destroy (gr->pattern_surface);
+
+ if (gr->pattern_pixels)
+ g_free (gr->pattern_pixels);
+
+ gr->pattern = NULL;
+ gr->pattern_surface = NULL;
+ gr->pattern_pixels = NULL;
+
+ gr->pattern_pixels = (char *) g_malloc (h * stride * 4);
+ g_assert (gr->pattern_pixels != NULL);
+
+ jpixels = (*env)->GetIntArrayElements (env, jarr, NULL);
+ g_assert (jpixels != NULL);
+ memcpy (gr->pattern_pixels, jpixels, h * stride * 4);
+ (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
+
+ gr->pattern_surface = cairo_image_surface_create_for_data ((unsigned char *)gr->pattern_pixels,
+ CAIRO_FORMAT_ARGB32,
+ w, h, stride * 4);
+ g_assert (gr->pattern_surface != NULL);
+ cairo_pattern_set_extend (gr->pattern, 1);
+ gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
+ g_assert (gr->pattern != NULL);
+ cairo_set_source (gr->cr, gr->pattern);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
+ (JNIEnv *env, jobject obj, jintArray java_pixels,
+ jint w, jint h, jint stride, jdoubleArray java_matrix)
+{
+ struct graphics2d *gr = NULL;
+ jint *native_pixels = NULL;
+ jdouble *native_matrix = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+
+ if (gr->debug) printf ("drawPixels (%d pixels, %dx%d, stride: %d)\n",
+ (*env)->GetArrayLength (env, java_pixels), w, h, stride);
+
+ native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL);
+ native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
+ g_assert (native_pixels != NULL);
+ g_assert (native_matrix != NULL);
+ g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
+
+ begin_drawing_operation (env, gr);
+
+ {
+ cairo_matrix_t mat;
+ cairo_pattern_t *p;
+ cairo_surface_t *surf = cairo_image_surface_create_for_data ((unsigned char *)native_pixels,
+ CAIRO_FORMAT_ARGB32,
+ w, h, stride * 4);
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_init (&mat,
+ native_matrix[0], native_matrix[1],
+ native_matrix[2], native_matrix[3],
+ native_matrix[4], native_matrix[5]);
+
+ p = cairo_pattern_create_for_surface (surf);
+ cairo_pattern_set_matrix (p, &mat);
+ if (gr->pattern)
+ cairo_pattern_set_filter (p, cairo_pattern_get_filter (gr->pattern));
+ cairo_set_source (gr->cr, p);
+ cairo_paint (gr->cr);
+ cairo_pattern_destroy (p);
+ cairo_surface_destroy (surf);
+ }
+
+ end_drawing_operation (env, gr);
+
+ (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
+ (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
+
+ gdk_threads_leave();
+}
+
+/* passthrough methods to cairo */
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSave
+ (JNIEnv *env, jobject obj)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_save\n");
+ cairo_save (gr->cr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore
+ (JNIEnv *env, jobject obj)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_restore\n");
+ cairo_restore (gr->cr);
+ update_pattern_transform (gr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix
+ (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
+{
+ struct graphics2d *gr = NULL;
+ jdouble *native_matrix = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+
+ /* cairoSetMatrix was called before this graphics object's component
+ was realized. */
+ if (gr == NULL)
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
+ g_assert (native_matrix != NULL);
+ g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
+
+ if (gr->debug) printf ("cairo_set_matrix [ %f, %f, %f, %f, %f, %f ]\n",
+ native_matrix[0], native_matrix[1],
+ native_matrix[2], native_matrix[3],
+ native_matrix[4], native_matrix[5]);
+
+ {
+ cairo_matrix_t mat;
+
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_init (&mat,
+ native_matrix[0], native_matrix[1],
+ native_matrix[2], native_matrix[3],
+ native_matrix[4], native_matrix[5]);
+ cairo_set_matrix (gr->cr, &mat);
+ }
+
+ (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
+ update_pattern_transform (gr);
+
+ gdk_threads_leave();
+}
+
+static void
+install_font_peer(cairo_t *cr,
+ struct peerfont *pfont,
+ int debug)
+{
+ cairo_font_face_t *ft;
+ FT_Face face = NULL;
+
+ g_assert(cr != NULL);
+ g_assert(pfont != NULL);
+
+ if (pfont->graphics_resource == NULL)
+ {
+ face = pango_ft2_font_get_face (pfont->font);
+ g_assert (face != NULL);
+
+ ft = cairo_ft_font_face_create_for_ft_face (face, 0);
+ g_assert (ft != NULL);
+
+ if (debug) printf ("install_font_peer made new cairo font for '%s' at %f\n",
+ face->family_name,
+ (pango_font_description_get_size (pfont->desc) /
+ (double)PANGO_SCALE));
+
+ cairo_set_font_face (cr, ft);
+ cairo_font_face_destroy (ft);
+ cairo_set_font_size (cr,
+ (pango_font_description_get_size (pfont->desc) /
+ (double)PANGO_SCALE));
+ ft = cairo_get_font_face (cr);
+ pfont->graphics_resource = ft;
+ }
+ else
+ {
+ if (debug) printf ("install_font_peer reused existing font resource\n");
+ ft = (cairo_font_face_t *) pfont->graphics_resource;
+ cairo_set_font_face (cr, ft);
+ }
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource
+ (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject java_font)
+{
+ struct peerfont *pfont = NULL;
+
+ gdk_threads_enter();
+
+ g_assert(java_font != NULL);
+
+ pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
+ g_assert (pfont != NULL);
+ if (pfont->graphics_resource != NULL)
+ {
+ cairo_font_face_destroy ((cairo_font_face_t *) pfont->graphics_resource);
+ pfont->graphics_resource = NULL;
+ }
+
+ gdk_threads_leave();
+}
+
+static void
+paint_glyph_run(JNIEnv *env,
+ struct graphics2d *gr,
+ cairo_glyph_t **glyphs,
+ gint *n_glyphs,
+ PangoLayoutRun *run)
+{
+ gint i = 0;
+ gint x = 0, y = 0;
+
+ g_assert (gr != NULL);
+ g_assert (glyphs != NULL);
+ g_assert (n_glyphs != NULL);
+ g_assert (run != NULL);
+
+ if (run->glyphs != NULL && run->glyphs->num_glyphs > 0)
+ {
+ if (*n_glyphs < run->glyphs->num_glyphs)
+ {
+ *glyphs = g_realloc(*glyphs,
+ (sizeof(cairo_glyph_t)
+ * run->glyphs->num_glyphs));
+ *n_glyphs = run->glyphs->num_glyphs;
+ }
+
+ g_assert (*glyphs != NULL);
+
+ if (gr->debug) printf ("painting %d glyphs: ", run->glyphs->num_glyphs);
+
+ for (i = 0; i < run->glyphs->num_glyphs; ++i)
+ {
+ (*glyphs)[i].index = run->glyphs->glyphs[i].glyph;
+
+ (*glyphs)[i].x =
+ ((double) (x + run->glyphs->glyphs[i].geometry.x_offset))
+ / ((double) PANGO_SCALE);
+
+ (*glyphs)[i].y =
+ ((double) (y + run->glyphs->glyphs[i].geometry.y_offset))
+ / ((double) PANGO_SCALE);
+
+ if (gr->debug) printf(" (%ld @ %f,%f)",
+ (*glyphs)[i].index,
+ (*glyphs)[i].x,
+ (*glyphs)[i].y);
+
+ x += run->glyphs->glyphs[i].geometry.width;
+ }
+
+ if (gr->debug) printf("\n");
+ begin_drawing_operation (env, gr);
+ cairo_show_glyphs (gr->cr, *glyphs, run->glyphs->num_glyphs);
+ end_drawing_operation (env, gr);
+ }
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGlyphVector
+ (JNIEnv *env, jobject self,
+ jobject font,
+ jfloat x, jfloat y, jint n,
+ jintArray java_codes,
+ jfloatArray java_positions)
+{
+
+ struct graphics2d *gr = NULL;
+ struct peerfont *pfont = NULL;
+ cairo_glyph_t *glyphs = NULL;
+ int *native_codes;
+ float *native_positions;
+ jint i = 0;
+
+ gdk_threads_enter ();
+
+ g_assert (self != NULL);
+ g_assert (java_codes != NULL);
+ g_assert (java_positions != NULL);
+
+ if (peer_is_disposed(env, self))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
+ g_assert (gr != NULL);
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert (pfont != NULL);
+
+ install_font_peer(gr->cr, pfont, gr->debug);
+
+ glyphs = g_malloc( sizeof(cairo_glyph_t) * n);
+ g_assert (glyphs != NULL);
+
+ native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
+ native_positions = (*env)->GetFloatArrayElements (env, java_positions, NULL);
+
+ for (i = 0; i < n; ++i)
+ {
+ glyphs[i].index = native_codes[i];
+ glyphs[i].x = x + native_positions[ 2*i ];
+ glyphs[i].y = y + native_positions[ 2*i + 1];
+ }
+
+ (*env)->ReleaseFloatArrayElements (env, java_positions, native_positions, 0);
+ (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
+
+ begin_drawing_operation (env, gr);
+ cairo_show_glyphs (gr->cr, glyphs, n);
+ end_drawing_operation (env, gr);
+
+ g_free(glyphs);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkTextLayout
+ (JNIEnv *env, jobject self, jobject java_layout, jfloat x, jfloat y)
+{
+ /*
+ * FIXME: Some day we expect either cairo or pango will know how to make
+ * a pango layout paint to a cairo surface. that day is not yet here.
+ */
+
+ struct graphics2d *gr = NULL;
+ struct textlayout *tl = NULL;
+ PangoLayoutIter *i = NULL;
+ PangoLayoutRun *run = NULL;
+ cairo_glyph_t *glyphs = NULL;
+ gint n_glyphs = 0;
+
+ gdk_threads_enter ();
+
+ g_assert (self != NULL);
+ g_assert (java_layout != NULL);
+
+ gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
+ tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, java_layout);
+
+ g_assert (gr != NULL);
+ g_assert (tl != NULL);
+ g_assert (tl->pango_layout != NULL);
+
+ if (gr->debug) printf ("painting pango layout\n");
+
+ if (peer_is_disposed(env, self))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ i = pango_layout_get_iter (tl->pango_layout);
+ g_assert (i != NULL);
+
+ cairo_translate (gr->cr, x, y);
+
+ do
+ {
+ run = pango_layout_iter_get_run (i);
+ if (run != NULL)
+ paint_glyph_run (env, gr, &glyphs, &n_glyphs, run);
+ }
+ while (pango_layout_iter_next_run (i));
+
+ if (glyphs != NULL)
+ g_free (glyphs);
+
+ cairo_translate (gr->cr, -x, -y);
+
+ pango_layout_iter_free (i);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator
+ (JNIEnv *env, jobject obj, jint op)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_set_operator %d\n", op);
+ switch ((enum java_awt_alpha_composite_rule) op)
+ {
+ case java_awt_alpha_composite_CLEAR:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR);
+ break;
+
+ case java_awt_alpha_composite_SRC:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_SOURCE);
+ break;
+
+ case java_awt_alpha_composite_SRC_OVER:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER);
+ break;
+
+ case java_awt_alpha_composite_DST_OVER:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OVER);
+ break;
+
+ case java_awt_alpha_composite_SRC_IN:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN);
+ break;
+
+ case java_awt_alpha_composite_DST_IN:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_IN);
+ break;
+
+ case java_awt_alpha_composite_SRC_OUT:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT);
+ break;
+
+ case java_awt_alpha_composite_DST_OUT:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OUT);
+ break;
+
+ case java_awt_alpha_composite_DST:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST);
+ break;
+
+ case java_awt_alpha_composite_SRC_ATOP:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP);
+ break;
+
+ case java_awt_alpha_composite_DST_ATOP:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_ATOP);
+ break;
+
+ case java_awt_alpha_composite_XOR:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR);
+ break;
+ }
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColor
+ (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b, jdouble a)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+
+ /* this is a very weird fact: GDK Pixbufs and RENDER drawables consider
+ colors in opposite pixel order. I have no idea why. thus when you
+ draw to a PixBuf, you must exchange the R and B components of your
+ color. */
+
+ if (gr->debug) printf ("cairo_set_source_rgb (%f, %f, %f)\n", r, g, b);
+
+ if (gr->drawbuf)
+ cairo_set_source_rgba (gr->cr, b, g, r, a);
+ else
+ cairo_set_source_rgba (gr->cr, r, g, b, a);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFillRule
+ (JNIEnv *env, jobject obj, jint rule)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ if (gr->debug) printf ("cairo_set_fill_rule %d\n", rule);
+ g_assert (gr != NULL);
+ switch ((enum java_awt_geom_path_iterator_winding_rule) rule)
+ {
+ case java_awt_geom_path_iterator_WIND_NON_ZERO:
+ cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING);
+ break;
+ case java_awt_geom_path_iterator_WIND_EVEN_ODD:
+ cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD);
+ break;
+ }
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidth
+ (JNIEnv *env, jobject obj, jdouble width)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ return;
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_set_line_width %f\n", width);
+ cairo_set_line_width (gr->cr, width);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCap
+ (JNIEnv *env, jobject obj, jint cap)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_set_line_cap %d\n", cap);
+ switch ((enum java_awt_basic_stroke_cap_rule) cap)
+ {
+ case java_awt_basic_stroke_CAP_BUTT:
+ cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT);
+ break;
+
+ case java_awt_basic_stroke_CAP_ROUND:
+ cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND);
+ break;
+
+ case java_awt_basic_stroke_CAP_SQUARE:
+ cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE);
+ break;
+ }
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoin
+ (JNIEnv *env, jobject obj, jint join)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_set_line_join %d\n", join);
+ switch ((enum java_awt_basic_stroke_join_rule) join)
+ {
+ case java_awt_basic_stroke_JOIN_MITER:
+ cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER);
+ break;
+
+ case java_awt_basic_stroke_JOIN_ROUND:
+ cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND);
+ break;
+
+ case java_awt_basic_stroke_JOIN_BEVEL:
+ cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL);
+ break;
+ }
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDash
+ (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset)
+{
+ struct graphics2d *gr = NULL;
+ jdouble *dasharr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_set_dash\n");
+ dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL);
+ g_assert (dasharr != NULL);
+ cairo_set_dash (gr->cr, dasharr, ndash, offset);
+ (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimit
+ (JNIEnv *env, jobject obj, jdouble miter)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_set_miter_limit %f\n", miter);
+ cairo_set_miter_limit (gr->cr, miter);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoNewPath
+ (JNIEnv *env, jobject obj)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+
+ if (gr == NULL)
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ if (gr->debug) printf ("cairo_new_path\n");
+ cairo_new_path (gr->cr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoMoveTo
+ (JNIEnv *env, jobject obj, jdouble x, jdouble y)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_move_to (%f, %f)\n", x, y);
+ cairo_move_to (gr->cr, x, y);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoLineTo
+ (JNIEnv *env, jobject obj, jdouble x, jdouble y)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_line_to (%f, %f)\n", x, y);
+ cairo_line_to (gr->cr, x, y);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoCurveTo
+ (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_curve_to (%f, %f), (%f, %f), (%f, %f)\n", x1, y1, x2, y2, x3, y3);
+ cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelMoveTo
+ (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_rel_move_to (%f, %f)\n", dx, dy);
+ cairo_rel_move_to (gr->cr, dx, dy);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelLineTo
+ (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_rel_line_to (%f, %f)\n", dx, dy);
+ cairo_rel_line_to (gr->cr, dx, dy);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelCurveTo
+ (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_rel_curve_to (%f, %f), (%f, %f), (%f, %f)\n", dx1, dy1, dx2, dy2, dx3, dy3);
+ cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRectangle
+ (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+
+ if (gr == NULL)
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ if (gr->debug) printf ("cairo_rectangle (%f, %f) (%f, %f)\n", x, y, width, height);
+ cairo_rectangle (gr->cr, x, y, width, height);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClosePath
+ (JNIEnv *env, jobject obj)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_close_path\n");
+ cairo_close_path (gr->cr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke
+ (JNIEnv *env, jobject obj)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_stroke\n");
+ begin_drawing_operation (env, gr);
+ cairo_stroke (gr->cr);
+ end_drawing_operation (env, gr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill
+ (JNIEnv *env, jobject obj)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_fill\n");
+ begin_drawing_operation (env, gr);
+ cairo_fill (gr->cr);
+ end_drawing_operation (env, gr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip
+ (JNIEnv *env, jobject obj)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+
+ if (gr == NULL)
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ if (gr->debug) printf ("cairo_clip\n");
+ begin_drawing_operation (env, gr);
+ cairo_reset_clip (gr->cr);
+ cairo_clip (gr->cr);
+ end_drawing_operation (env, gr);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter
+ (JNIEnv *env, jobject obj, jint filter)
+{
+ struct graphics2d *gr = NULL;
+
+ gdk_threads_enter();
+
+ if (peer_is_disposed(env, obj))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+ if (gr->debug) printf ("cairo_surface_set_filter %d\n", filter);
+ switch ((enum java_awt_rendering_hints_filter) filter)
+ {
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
+ break;
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BILINEAR);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_FAST);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BEST);
+ break;
+ }
+
+ gdk_threads_leave();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
new file mode 100644
index 00000000000..0467c3c7acd
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
@@ -0,0 +1,102 @@
+/* gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+#include "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h"
+
+
+static gint
+cmp_families (const void *a, const void *b)
+{
+ const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
+ const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
+
+ return g_utf8_collate (a_name, b_name);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nativeGetFontFamilies
+(JNIEnv *env, jobject self __attribute__((unused)), jobjectArray family_name)
+{
+ PangoContext *context = NULL;
+ PangoFontFamily **families = NULL;
+ int n_families = 0;
+ int idx = 0;
+
+ gdk_threads_enter ();
+
+ context = gdk_pango_context_get();
+ g_assert (context != NULL);
+
+ pango_context_list_families (context, &families, &n_families);
+
+ qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
+
+ for (idx = 0; idx < n_families; idx++)
+ {
+ const char *name_tmp = pango_font_family_get_name (families[idx]);
+ jstring name = (*env)->NewStringUTF (env, name_tmp);
+ (*env)->SetObjectArrayElement (env, family_name, idx, name);
+ }
+ g_free (families);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nativeGetNumFontFamilies
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
+{
+ PangoContext *context = NULL;
+ PangoFontFamily **families = NULL;
+ gint n_families = 0;
+ gint num = 0;
+
+ gdk_threads_enter ();
+
+ context = gdk_pango_context_get();
+ g_assert (context != NULL);
+
+ pango_context_list_families (context, &families, &n_families);
+
+ num = n_families;
+ g_free (families);
+
+ gdk_threads_leave ();
+
+ return num;
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c
new file mode 100644
index 00000000000..648cd6603d1
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c
@@ -0,0 +1,515 @@
+/* gdkpixbufdecoder.c
+ Copyright (C) 1999, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+#include <gtkpeer.h>
+#include <gdk/gdk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixbuf-loader.h>
+
+#include <jni.h>
+#include <jcl.h>
+#include "native_state.h"
+#include "gnu_java_awt_peer_gtk_GdkPixbufDecoder.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+static struct state_table *native_pixbufdecoder_state_table;
+
+#define NSA_PB_INIT(env, clazz) \
+ native_pixbufdecoder_state_table = cp_gtk_init_state_table (env, clazz)
+
+#define NSA_GET_PB_PTR(env, obj) \
+ cp_gtk_get_state (env, obj, native_pixbufdecoder_state_table)
+
+#define NSA_SET_PB_PTR(env, obj, ptr) \
+ cp_gtk_set_state (env, obj, native_pixbufdecoder_state_table, (void *)ptr)
+
+#define NSA_DEL_PB_PTR(env, obj) \
+ cp_gtk_remove_state_slot (env, obj, native_pixbufdecoder_state_table)
+
+/* Union used for type punning. */
+union env_union
+{
+ void **void_env;
+ JNIEnv **jni_env;
+};
+
+static JavaVM *vm;
+
+static jmethodID areaPreparedID;
+static jmethodID areaUpdatedID;
+static jmethodID dataOutputWriteID;
+static jmethodID registerFormatID;
+
+static void
+area_prepared_cb (GdkPixbufLoader *loader,
+ jobject *decoder)
+{
+ JNIEnv *env = NULL;
+ union env_union e;
+ jint width = 0;
+ jint height = 0;
+ GdkPixbuf *pixbuf = NULL;
+
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ g_assert (pixbuf != NULL);
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+
+ g_assert (decoder != NULL);
+
+ e.jni_env = &env;
+ (*vm)->GetEnv (vm, e.void_env, JNI_VERSION_1_1);
+
+ gdk_threads_leave ();
+
+ (*env)->CallVoidMethod (env,
+ *decoder,
+ areaPreparedID,
+ width, height);
+
+ gdk_threads_enter ();
+}
+
+static void
+area_updated_cb (GdkPixbufLoader *loader,
+ gint x, gint y,
+ gint width, gint height,
+ jobject *decoder)
+{
+ JNIEnv *env;
+ union env_union e;
+ jint stride_bytes, stride_pixels, n_channels, n_pixels;
+ jintArray jpixels;
+ jint *java_pixels;
+ guchar *gdk_pixels;
+
+ GdkPixbuf *pixbuf_no_alpha = NULL;
+ GdkPixbuf *pixbuf = NULL;
+
+#ifndef WORDS_BIGENDIAN
+ int i;
+#endif
+
+ pixbuf_no_alpha = gdk_pixbuf_loader_get_pixbuf (loader);
+ if (pixbuf_no_alpha == NULL)
+ return;
+
+ pixbuf = gdk_pixbuf_add_alpha(pixbuf_no_alpha, FALSE, 0, 0, 0);
+ g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
+
+ stride_bytes = gdk_pixbuf_get_rowstride (pixbuf);
+ n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+ stride_pixels = stride_bytes / n_channels;
+ n_pixels = height * stride_pixels;
+ gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+ e.jni_env = &env;
+ (*vm)->GetEnv (vm, e.void_env, JNI_VERSION_1_1);
+
+ gdk_threads_leave ();
+
+ jpixels = (*env)->NewIntArray (env, n_pixels);
+
+ gdk_threads_enter ();
+
+ java_pixels = (*env)->GetIntArrayElements (env, jpixels, NULL);
+
+ memcpy (java_pixels,
+ gdk_pixels + (y * stride_bytes),
+ (height * stride_bytes));
+
+#ifndef WORDS_BIGENDIAN
+ /* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */
+ for (i = 0; i < n_pixels; ++i)
+ {
+ java_pixels[i] = SWAPU32 ((unsigned)java_pixels[i]);
+ }
+#endif
+
+ g_object_unref (pixbuf);
+
+ gdk_threads_leave ();
+
+ (*env)->ReleaseIntArrayElements (env, jpixels, java_pixels, 0);
+
+ (*env)->CallVoidMethod (env,
+ *decoder,
+ areaUpdatedID,
+ (jint) x, (jint) y,
+ (jint) width, (jint) height,
+ jpixels,
+ stride_pixels);
+
+ (*env)->DeleteLocalRef(env, jpixels);
+
+ gdk_threads_enter ();
+}
+
+static void
+closed_cb (GdkPixbufLoader *loader __attribute__((unused)), jobject *decoder)
+{
+ JNIEnv *env;
+ union env_union e;
+ e.jni_env = &env;
+ (*vm)->GetEnv (vm, e.void_env, JNI_VERSION_1_1);
+
+ gdk_threads_leave ();
+
+ (*env)->DeleteGlobalRef (env, *decoder);
+ g_free (decoder);
+
+ gdk_threads_enter ();
+}
+
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_initState
+ (JNIEnv *env, jobject obj)
+{
+ GdkPixbufLoader *loader = NULL;
+ jobject *decoder = NULL;
+
+ gdk_threads_enter ();
+
+ decoder = (jobject *) g_malloc (sizeof (jobject));
+ g_assert (decoder != NULL);
+ *decoder = (*env)->NewGlobalRef (env, obj);
+
+ loader = gdk_pixbuf_loader_new ();
+ g_assert (loader != NULL);
+ g_signal_connect (loader, "area-prepared", G_CALLBACK (area_prepared_cb), decoder);
+ g_signal_connect (loader, "area-updated", G_CALLBACK (area_updated_cb), decoder);
+ g_signal_connect (loader, "closed", G_CALLBACK (closed_cb), decoder);
+
+ NSA_SET_PB_PTR (env, obj, loader);
+
+ gdk_threads_leave ();
+}
+
+static void
+query_formats (JNIEnv *env, jclass clazz)
+{
+ jobject jformat;
+ GSList *formats, *f;
+ GdkPixbufFormat *format;
+ char **ch, *name;
+
+ jclass formatClass;
+ jmethodID addExtensionID;
+ jmethodID addMimeTypeID;
+ jobject string;
+
+ formatClass = (*env)->FindClass
+ (env, "gnu/java/awt/peer/gtk/GdkPixbufDecoder$ImageFormatSpec");
+
+ g_assert(formatClass != NULL);
+
+ addExtensionID = (*env)->GetMethodID (env, formatClass,
+ "addExtension",
+ "(Ljava/lang/String;)V");
+
+ addMimeTypeID = (*env)->GetMethodID (env, formatClass,
+ "addMimeType",
+ "(Ljava/lang/String;)V");
+
+ formats = gdk_pixbuf_get_formats ();
+
+ for (f = formats; f; f = f->next)
+ {
+ format = (GdkPixbufFormat *) f->data;
+ name = gdk_pixbuf_format_get_name(format);
+
+ string = (*env)->NewStringUTF(env, name);
+ g_assert(string != NULL);
+
+ jformat = (*env)->CallStaticObjectMethod
+ (env, clazz, registerFormatID, string,
+ (jboolean) gdk_pixbuf_format_is_writable(format));
+ (*env)->DeleteLocalRef(env, string);
+
+ g_assert(jformat != NULL);
+
+ ch = gdk_pixbuf_format_get_extensions(format);
+ while (*ch)
+ {
+ string = (*env)->NewStringUTF(env, *ch);
+ g_assert(string != NULL);
+ (*env)->CallVoidMethod (env, jformat, addExtensionID, string);
+ (*env)->DeleteLocalRef(env, string);
+ ++ch;
+ }
+
+ ch = gdk_pixbuf_format_get_mime_types(format);
+ while (*ch)
+ {
+ string = (*env)->NewStringUTF(env, *ch);
+ g_assert(string != NULL);
+ (*env)->CallVoidMethod (env, jformat, addMimeTypeID, string);
+ (*env)->DeleteLocalRef(env, string);
+ ++ch;
+ }
+ }
+
+ g_slist_free(formats);
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_initStaticState
+ (JNIEnv *env, jclass clazz)
+{
+ jclass dataOutputClass;
+
+ (*env)->GetJavaVM(env, &vm);
+
+ areaPreparedID = (*env)->GetMethodID (env, clazz,
+ "areaPrepared",
+ "(II)V");
+
+ areaUpdatedID = (*env)->GetMethodID (env, clazz,
+ "areaUpdated",
+ "(IIII[II)V");
+
+ registerFormatID = (*env)->GetStaticMethodID
+ (env, clazz,
+ "registerFormat",
+ "(Ljava/lang/String;Z)"
+ "Lgnu/java/awt/peer/gtk/GdkPixbufDecoder$ImageFormatSpec;");
+
+
+ dataOutputClass = (*env)->FindClass(env, "java/io/DataOutput");
+ dataOutputWriteID = (*env)->GetMethodID (env, dataOutputClass,
+ "write", "([B)V");
+
+ query_formats (env, clazz);
+
+ NSA_PB_INIT (env, clazz);
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_finish
+(JNIEnv *env, jobject obj, jboolean needs_close)
+{
+ GdkPixbufLoader *loader = NULL;
+
+ gdk_threads_enter ();
+
+ loader = (GdkPixbufLoader *)NSA_DEL_PB_PTR (env, obj);
+ if (loader == NULL)
+ return;
+
+ if (needs_close)
+ gdk_pixbuf_loader_close (loader, NULL);
+ g_object_unref (loader);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_pumpDone
+(JNIEnv *env, jobject obj)
+{
+ GError *err = NULL;
+ GdkPixbufLoader *loader = NULL;
+
+ gdk_threads_enter ();
+
+ loader = (GdkPixbufLoader *)NSA_GET_PB_PTR (env, obj);
+ g_assert (loader != NULL);
+
+ gdk_pixbuf_loader_close (loader, &err);
+
+ if (err != NULL)
+ {
+ JCL_ThrowException (env, "java/io/IOException", err->message);
+ g_error_free (err);
+ }
+
+ gdk_threads_leave ();
+}
+
+struct stream_save_request
+{
+ JNIEnv *env;
+ jobject *stream;
+};
+
+static gboolean
+save_to_stream(const gchar *buf,
+ gsize count,
+ GError **error __attribute__((unused)),
+ gpointer data)
+{
+ struct stream_save_request *ssr = (struct stream_save_request *)data;
+
+ jbyteArray jbuf;
+ jbyte *cbuf;
+
+ gdk_threads_leave ();
+
+ jbuf = (*(ssr->env))->NewByteArray ((ssr->env), count);
+ cbuf = (*(ssr->env))->GetByteArrayElements ((ssr->env), jbuf, NULL);
+ memcpy (cbuf, buf, count);
+ (*(ssr->env))->ReleaseByteArrayElements ((ssr->env), jbuf, cbuf, 0);
+ (*(ssr->env))->CallVoidMethod ((ssr->env), *(ssr->stream),
+ dataOutputWriteID, jbuf);
+
+ gdk_threads_enter ();
+
+ return TRUE;
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_streamImage
+(JNIEnv *env, jclass clazz __attribute__((unused)),
+ jintArray jarr, jstring jenctype, jint width, jint height,
+ jboolean hasAlpha, jobject stream)
+{
+ GdkPixbuf* pixbuf;
+ jint *ints;
+ guchar a, r, g, b, *pix, *p;
+ GError *err = NULL;
+ const char *enctype;
+ int i;
+ struct stream_save_request ssr;
+
+ gdk_threads_enter ();
+
+ ssr.stream = &stream;
+ ssr.env = env;
+
+ ints = (*env)->GetIntArrayElements (env, jarr, NULL);
+ pix = g_malloc(width * height * (hasAlpha ? 4 : 3));
+
+ enctype = (*env)->GetStringUTFChars (env, jenctype, NULL);
+ g_assert(enctype != NULL);
+
+ g_assert (pix != NULL);
+ g_assert (ints != NULL);
+
+ p = pix;
+ for (i = 0; i < width*height; ++i)
+ {
+ /*
+ * Java encodes pixels as integers in a predictable arithmetic order:
+ * 0xAARRGGBB. Since these are jints, JNI has already byte-swapped
+ * them for us if necessary, so they're in "our" endianness, whatever
+ * that is. It uses 4 bytes per pixel whether or not there's an alpha
+ * channel.
+ */
+
+ a = 0xff & (ints[i] >> 24);
+ r = 0xff & (ints[i] >> 16);
+ g = 0xff & (ints[i] >> 8);
+ b = 0xff & ints[i];
+
+ /*
+ * GDK-pixbuf has a very different storage model:
+ *
+ * - A different alpha order (alpha after colors).
+ * - A different packing model (no alpha -> 3-bytes-per-pixel).
+ * - A different "RGB" order (host memory order, not endian-neutral).
+ */
+
+ *p++ = r;
+ *p++ = g;
+ *p++ = b;
+ if (hasAlpha)
+ *p++ = a;
+ }
+
+ pixbuf = gdk_pixbuf_new_from_data (pix,
+ GDK_COLORSPACE_RGB,
+ (gboolean) hasAlpha,
+ 8, width, height,
+ width * (hasAlpha ? 4 : 3), /* rowstride */
+ NULL, NULL);
+ g_assert (pixbuf != NULL);
+
+ g_assert(gdk_pixbuf_save_to_callback (pixbuf,
+ &save_to_stream,
+ &ssr,
+ enctype,
+ &err, NULL));
+
+ g_object_unref (pixbuf);
+
+ g_free(pix);
+
+ (*env)->ReleaseStringUTFChars (env, jenctype, enctype);
+ (*env)->ReleaseIntArrayElements (env, jarr, ints, 0);
+
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_pumpBytes
+ (JNIEnv *env, jobject obj, jbyteArray jarr, jint len)
+{
+ GdkPixbufLoader *loader = NULL;
+ jbyte *bytes = NULL;
+ GError *err = NULL;
+
+ gdk_threads_enter ();
+
+ g_assert (len >= 1);
+ g_assert (jarr != NULL);
+
+ bytes = (*env)->GetByteArrayElements (env, jarr, NULL);
+ g_assert (bytes != NULL);
+ loader = (GdkPixbufLoader *)NSA_GET_PB_PTR (env, obj);
+ g_assert (loader != NULL);
+
+ gdk_pixbuf_loader_write (loader, (const guchar *) bytes, len, &err);
+
+ (*env)->ReleaseByteArrayElements (env, jarr, bytes, 0);
+
+ if (err != NULL)
+ {
+ JCL_ThrowException (env, "java/io/IOException", err->message);
+ g_error_free (err);
+ }
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c
new file mode 100644
index 00000000000..8c0ac6ce35f
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkRobotPeer.c
@@ -0,0 +1,341 @@
+/* gdkrobotpeer.c
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GdkRobotPeer.h"
+#include <gdk/gdkx.h>
+#include <X11/extensions/XTest.h>
+
+static int
+awt_button_mask_to_num (int buttons)
+{
+ switch (buttons)
+ {
+ case AWT_BUTTON1_MASK:
+ return 1;
+ case AWT_BUTTON2_MASK:
+ return 2;
+ case AWT_BUTTON3_MASK:
+ return 3;
+ }
+
+ return 0;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_GdkRobotPeer_initXTest
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
+{
+ GdkDisplay *display;
+ Display *xdisplay;
+ int event_basep;
+ int error_basep;
+ int majorp;
+ int minorp;
+ jboolean result;
+
+ gdk_threads_enter ();
+
+ display = gdk_display_get_default ();
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ result = XTestQueryExtension (xdisplay,
+ &event_basep,
+ &error_basep,
+ &majorp,
+ &minorp);
+
+ gdk_threads_leave ();
+
+ return result;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseMove
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint x, jint y)
+{
+ GdkDisplay *display;
+ Display *xdisplay;
+ int result;
+
+ gdk_threads_enter ();
+
+ display = gdk_display_get_default ();
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ result = XTestFakeMotionEvent (xdisplay,
+ -1,
+ x, y, CurrentTime);
+
+ XFlush (xdisplay);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mousePress
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint buttons)
+{
+ GdkDisplay *display;
+ Display *xdisplay;
+ int result;
+
+ gdk_threads_enter ();
+
+ display = gdk_display_get_default ();
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ result = XTestFakeButtonEvent (xdisplay,
+ awt_button_mask_to_num (buttons),
+ True, CurrentTime);
+
+ XFlush (xdisplay);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseRelease
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint buttons)
+{
+ GdkDisplay *display;
+ Display *xdisplay;
+ int result;
+
+ gdk_threads_enter ();
+
+ display = gdk_display_get_default ();
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ result = XTestFakeButtonEvent (xdisplay,
+ awt_button_mask_to_num (buttons),
+ False, CurrentTime);
+
+ XFlush (xdisplay);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseWheel
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint wheelAmt)
+{
+ GdkDisplay *display;
+ Display *xdisplay;
+ int i = 0;
+
+ gdk_threads_enter ();
+
+ display = gdk_display_get_default ();
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ if (wheelAmt < 0)
+ for (i = 0; i < -wheelAmt; i++)
+ {
+ XTestFakeButtonEvent (xdisplay,
+ 4,
+ True, CurrentTime);
+ XTestFakeButtonEvent (xdisplay,
+ 4,
+ False, CurrentTime);
+ }
+ else
+ for (i = 0; i < wheelAmt; i++)
+ {
+ XTestFakeButtonEvent (xdisplay,
+ 5,
+ True, CurrentTime);
+ XTestFakeButtonEvent (xdisplay,
+ 5,
+ False, CurrentTime);
+ }
+
+ XFlush (xdisplay);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkRobotPeer_keyPress
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint keycode)
+{
+ GdkDisplay *display;
+ Display *xdisplay;
+ GdkKeymapKey *keymap_keys = NULL;
+ gint n_keys = 0;
+ guint lookup_keyval = 0;
+ int result;
+
+ gdk_threads_enter ();
+
+ display = gdk_display_get_default ();
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ lookup_keyval = cp_gtk_awt_keycode_to_keysym (keycode,
+ AWT_KEY_LOCATION_LEFT);
+
+ if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
+ lookup_keyval,
+ &keymap_keys,
+ &n_keys))
+ {
+ /* No matching keymap entry was found. */
+ g_printerr ("No matching keymap entries were found\n");
+ gdk_threads_leave ();
+ return;
+ }
+
+ /* If n_keys > 1 then there are multiple hardware keycodes that
+ translate to lookup_keyval. We arbitrarily choose the first
+ hardware keycode from the list returned by
+ gdk_keymap_get_entries_for_keyval. */
+ result = XTestFakeKeyEvent (xdisplay,
+ keymap_keys[0].keycode,
+ True, CurrentTime);
+
+ g_free (keymap_keys);
+
+ XFlush (xdisplay);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkRobotPeer_keyRelease
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint keycode)
+{
+ GdkDisplay *display;
+ Display *xdisplay;
+ GdkKeymapKey *keymap_keys = NULL;
+ gint n_keys = 0;
+ guint lookup_keyval = 0;
+ int result;
+
+ gdk_threads_enter ();
+
+ display = gdk_display_get_default ();
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ lookup_keyval = cp_gtk_awt_keycode_to_keysym (keycode,
+ AWT_KEY_LOCATION_LEFT);
+
+ if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
+ lookup_keyval,
+ &keymap_keys,
+ &n_keys))
+ {
+ /* No matching keymap entry was found. */
+ g_printerr ("No matching keymap entries were found\n");
+ gdk_threads_leave ();
+ return;
+ }
+
+ /* If n_keys > 1 then there are multiple hardware keycodes that
+ translate to lookup_keyval. We arbitrarily choose the first
+ hardware keycode from the list returned by
+ gdk_keymap_get_entries_for_keyval. */
+ result = XTestFakeKeyEvent (xdisplay,
+ keymap_keys[0].keycode,
+ False, CurrentTime);
+
+ g_free (keymap_keys);
+
+ XFlush (xdisplay);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_awt_peer_gtk_GdkRobotPeer_nativeGetRGBPixels
+ (JNIEnv *env, jobject obj __attribute__((unused)), jint x, jint y,
+ jint width, jint height)
+{
+ jint stride_bytes, stride_pixels, n_channels, n_pixels;
+ jintArray jpixels;
+ jint *java_pixels;
+ guchar *gdk_pixels;
+ GdkPixbuf *pixbuf_no_alpha = NULL;
+ GdkPixbuf *pixbuf = NULL;
+
+#ifndef WORDS_BIGENDIAN
+ int i;
+#endif
+
+ gdk_threads_enter ();
+
+ pixbuf_no_alpha = gdk_pixbuf_get_from_drawable (NULL,
+ gdk_get_default_root_window (),
+ NULL, x, y, 0, 0,
+ width, height);
+
+ pixbuf = gdk_pixbuf_add_alpha(pixbuf_no_alpha, FALSE, 0, 0, 0);
+ g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
+
+ stride_bytes = gdk_pixbuf_get_rowstride (pixbuf);
+ n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+ stride_pixels = stride_bytes / n_channels;
+ n_pixels = height * stride_pixels;
+ gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+ gdk_threads_leave ();
+
+ jpixels = (*env)->NewIntArray (env, n_pixels);
+
+ gdk_threads_enter ();
+
+ java_pixels = (*env)->GetIntArrayElements (env, jpixels, NULL);
+
+ memcpy (java_pixels,
+ gdk_pixels,
+ (height * stride_bytes));
+
+#ifndef WORDS_BIGENDIAN
+ /* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */
+ for (i = 0; i < n_pixels; ++i)
+ {
+ java_pixels[i] = SWAPU32 ((unsigned)java_pixels[i]);
+ }
+#endif
+
+ g_object_unref (pixbuf);
+
+ (*env)->ReleaseIntArrayElements (env, jpixels, java_pixels, 0);
+
+ gdk_threads_leave ();
+
+ return jpixels;
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
new file mode 100644
index 00000000000..918ecfd0a8e
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
@@ -0,0 +1,192 @@
+/* gnu_java_awt_GdkTextLayout.c
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+
+#include <jni.h>
+#include <gtk/gtk.h>
+#include "native_state.h"
+#include "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_GdkTextLayout.h"
+
+struct state_table *cp_gtk_native_text_layout_state_table;
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkTextLayout_initStaticState
+ (JNIEnv *env, jclass clazz)
+{
+ NSA_TEXT_LAYOUT_INIT (env, clazz);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkTextLayout_initState
+ (JNIEnv *env, jobject self)
+{
+ struct textlayout *tl;
+
+ gdk_threads_enter ();
+
+ g_assert(self != NULL);
+ tl = g_malloc0 (sizeof (struct textlayout));
+ g_assert(tl != NULL);
+ tl->pango_layout = pango_layout_new(gdk_pango_context_get());
+ g_assert(tl->pango_layout != NULL);
+ NSA_SET_TEXT_LAYOUT_PTR (env, self, tl);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText
+ (JNIEnv *env, jobject self, jstring text)
+{
+ struct textlayout *tl;
+ gchar *str = NULL;
+ gint len = 0;
+
+ gdk_threads_enter ();
+
+ g_assert(self != NULL);
+ g_assert(text != NULL);
+
+ tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self);
+ g_assert(tl != NULL);
+ g_assert(tl->pango_layout != NULL);
+
+ len = (*env)->GetStringUTFLength (env, text);
+ str = (gchar *)(*env)->GetStringUTFChars (env, text, NULL);
+ g_assert (str != NULL);
+
+ pango_layout_set_text (tl->pango_layout, text, len);
+
+ (*env)->ReleaseStringUTFChars (env, text, str);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkTextLayout_indexToPos
+ (JNIEnv *env, jobject self, jint idx, jdoubleArray javaPos)
+{
+ struct textlayout *tl;
+ PangoRectangle pangoPos;
+ jdouble *nativePos;
+
+ gdk_threads_enter ();
+
+ g_assert(self != NULL);
+ g_assert(javaPos != NULL);
+
+ tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self);
+ g_assert(tl != NULL);
+ g_assert(tl->pango_layout != NULL);
+
+ g_assert((*env)->GetArrayLength (env, javaPos) == 4);
+
+ nativePos = (*env)->GetDoubleArrayElements (env, javaPos, NULL);
+
+ pango_layout_index_to_pos (tl->pango_layout, idx, &pangoPos);
+
+ nativePos[0] = (jdouble) pangoPos.x;
+ nativePos[1] = (jdouble) pangoPos.y;
+ nativePos[2] = (jdouble) pangoPos.width;
+ nativePos[3] = (jdouble) pangoPos.height;
+
+ (*env)->ReleaseDoubleArrayElements (env, javaPos, nativePos, 0);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkTextLayout_getExtents
+ (JNIEnv *env, jobject self, jdoubleArray javaInkExtents, jdoubleArray javaLogExtents)
+{
+ struct textlayout *tl;
+ PangoRectangle pangoInkExtents, pangoLogExtents;
+ jdouble *nativeInkExtents, *nativeLogExtents;
+
+ gdk_threads_enter ();
+
+ g_assert(self != NULL);
+ g_assert(javaInkExtents != NULL);
+ g_assert(javaLogExtents != NULL);
+
+ tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self);
+ g_assert(tl != NULL);
+ g_assert(tl->pango_layout != NULL);
+
+ g_assert((*env)->GetArrayLength (env, javaInkExtents) == 4);
+ g_assert((*env)->GetArrayLength (env, javaLogExtents) == 4);
+
+ nativeInkExtents = (*env)->GetDoubleArrayElements (env, javaInkExtents, NULL);
+ nativeLogExtents = (*env)->GetDoubleArrayElements (env, javaLogExtents, NULL);
+
+ pango_layout_get_extents (tl->pango_layout,
+ &pangoInkExtents, &pangoLogExtents);
+
+ nativeInkExtents[0] = (jdouble) pangoInkExtents.x;
+ nativeInkExtents[1] = (jdouble) pangoInkExtents.y;
+ nativeInkExtents[2] = (jdouble) pangoInkExtents.width;
+ nativeInkExtents[3] = (jdouble) pangoInkExtents.height;
+
+ nativeLogExtents[0] = (jdouble) pangoLogExtents.x;
+ nativeLogExtents[1] = (jdouble) pangoLogExtents.y;
+ nativeLogExtents[2] = (jdouble) pangoLogExtents.width;
+ nativeLogExtents[3] = (jdouble) pangoLogExtents.height;
+
+ (*env)->ReleaseDoubleArrayElements (env, javaInkExtents, nativeInkExtents, 0);
+ (*env)->ReleaseDoubleArrayElements (env, javaLogExtents, nativeLogExtents, 0);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkTextLayout_dispose
+ (JNIEnv *env, jobject self)
+{
+ struct textlayout *tl;
+
+ gdk_threads_enter ();
+
+ g_assert(self != NULL);
+ tl = (struct textlayout *) NSA_DEL_TEXT_LAYOUT_PTR (env, self);
+ g_assert(tl != NULL);
+ if (tl->pango_layout != NULL)
+ g_object_unref (tl->pango_layout);
+ g_free(tl);
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c
new file mode 100644
index 00000000000..5e8ab26c3ed
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c
@@ -0,0 +1,338 @@
+/* gtkbuttonpeer.c -- Native implementation of GtkButtonPeer
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkButtonPeer.h"
+
+static jmethodID beginNativeRepaintID;
+static jmethodID endNativeRepaintID;
+
+void
+cp_gtk_button_init_jni (void)
+{
+ jclass gtkbuttonpeer;
+
+ gtkbuttonpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GtkButtonPeer");
+
+ beginNativeRepaintID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkbuttonpeer,
+ "beginNativeRepaint",
+ "()V");
+
+ endNativeRepaintID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkbuttonpeer,
+ "endNativeRepaint", "()V");
+}
+
+static void block_expose_event_cb (GtkWidget *widget,
+ jobject peer);
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_create
+ (JNIEnv *env, jobject obj, jstring label)
+{
+ const char *c_label;
+ GtkWidget *eventbox;
+ GtkWidget *button;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ c_label = (*env)->GetStringUTFChars (env, label, NULL);
+
+ eventbox = gtk_event_box_new ();
+ button = gtk_button_new_with_label (c_label);
+ gtk_container_add (GTK_CONTAINER (eventbox), button);
+ gtk_widget_show (button);
+
+ (*env)->ReleaseStringUTFChars (env, label, c_label);
+ NSA_SET_PTR (env, obj, eventbox);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jobject *gref;
+ GtkWidget *button;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ button = gtk_bin_get_child (GTK_BIN (ptr));
+
+ /* Button signals */
+ g_signal_connect_after (G_OBJECT (button), "pressed",
+ G_CALLBACK (block_expose_event_cb), *gref);
+
+ g_signal_connect_after (G_OBJECT (button), "released",
+ G_CALLBACK (block_expose_event_cb), *gref);
+
+ /* Component signals */
+ cp_gtk_component_connect_signals (G_OBJECT (button), gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkSetLabel
+ (JNIEnv *env, jobject obj, jstring jtext)
+{
+ const char *text;
+ GtkWidget *button;
+ GtkWidget *label;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ text = (*env)->GetStringUTFChars (env, jtext, NULL);
+
+ button = gtk_bin_get_child (GTK_BIN (ptr));
+ label = gtk_bin_get_child (GTK_BIN (button));
+ gtk_label_set_text (GTK_LABEL (label), text);
+
+ (*env)->ReleaseStringUTFChars (env, jtext, text);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkWidgetModifyFont
+ (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+ const char *font_name;
+ void *ptr;
+ GtkWidget *button;
+ GtkWidget *label;
+ PangoFontDescription *font_desc;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+ button = gtk_bin_get_child (GTK_BIN (ptr));
+ label = gtk_bin_get_child (GTK_BIN (button));
+
+ font_desc = pango_font_description_from_string (font_name);
+ pango_font_description_set_size (font_desc,
+ size * cp_gtk_dpi_conversion_factor);
+
+ if (style & AWT_STYLE_BOLD)
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+ if (style & AWT_STYLE_ITALIC)
+ pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+ gtk_widget_modify_font (GTK_WIDGET(label), font_desc);
+
+ pango_font_description_free (font_desc);
+
+ (*env)->ReleaseStringUTFChars (env, name, font_name);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkWidgetSetBackground
+ (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
+{
+ GdkColor normal_color;
+ GdkColor prelight_color;
+ GdkColor active_color;
+ int prelight_red;
+ int prelight_blue;
+ int prelight_green;
+ GtkWidget *button;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ normal_color.red = (red / 255.0) * 65535;
+ normal_color.green = (green / 255.0) * 65535;
+ normal_color.blue = (blue / 255.0) * 65535;
+
+ /* This calculation only approximate the active color produced by
+ Sun's AWT. */
+ active_color.red = 0.85 * (red / 255.0) * 65535;
+ active_color.green = 0.85 * (green / 255.0) * 65535;
+ active_color.blue = 0.85 * (blue / 255.0) * 65535;
+
+ /* There is no separate prelight color in Motif. */
+ prelight_red = 1.15 * (red / 255.0) * 65535;
+ prelight_green = 1.15 * (green / 255.0) * 65535;
+ prelight_blue = 1.15 * (blue / 255.0) * 65535;
+
+ prelight_color.red = prelight_red > 65535 ? 65535 : prelight_red;
+ prelight_color.green = prelight_green > 65535 ? 65535 : prelight_green;
+ prelight_color.blue = prelight_blue > 65535 ? 65535 : prelight_blue;
+
+ button = gtk_bin_get_child (GTK_BIN (ptr));
+
+ gtk_widget_modify_bg (button, GTK_STATE_NORMAL, &normal_color);
+ gtk_widget_modify_bg (button, GTK_STATE_ACTIVE, &active_color);
+ gtk_widget_modify_bg (button, GTK_STATE_PRELIGHT, &prelight_color);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkWidgetSetForeground
+ (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
+{
+ GdkColor color;
+ GtkWidget *button;
+ GtkWidget *label;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ color.red = (red / 255.0) * 65535;
+ color.green = (green / 255.0) * 65535;
+ color.blue = (blue / 255.0) * 65535;
+
+ button = gtk_bin_get_child (GTK_BIN (ptr));
+ label = gtk_bin_get_child (GTK_BIN (button));
+
+ gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &color);
+ gtk_widget_modify_fg (label, GTK_STATE_ACTIVE, &color);
+ gtk_widget_modify_fg (label, GTK_STATE_PRELIGHT, &color);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkActivate
+ (JNIEnv *env, jobject obj)
+{
+ GtkWidget *button;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ button = gtk_bin_get_child (GTK_BIN (ptr));
+ gtk_widget_activate (GTK_WIDGET (button));
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkWidgetRequestFocus
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ GtkWidget *button;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ button = gtk_bin_get_child (GTK_BIN (ptr));
+ gtk_widget_grab_focus (button);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkButtonPeer_setNativeBounds
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+ GtkWidget *widget, *child;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ widget = GTK_WIDGET (ptr);
+
+ /* We assume that -1 is a width or height and not a request for the
+ widget's natural size. */
+ width = width < 0 ? 0 : width;
+ height = height < 0 ? 0 : height;
+ child = gtk_bin_get_child (GTK_BIN (widget));
+
+ if (!(width == 0 && height == 0))
+ {
+ /* Set the event box's size request... */
+ gtk_widget_set_size_request (widget, width, height);
+ /* ...and the button's size request... */
+ gtk_widget_set_size_request (child, width, height);
+ /* ...and the label's size request. */
+ gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (child)), width,
+ height);
+ if (widget->parent != NULL)
+ gtk_fixed_move (GTK_FIXED (widget->parent), widget, x, y);
+ }
+
+ gdk_threads_leave ();
+}
+
+static void
+block_expose_event_cb (GtkWidget *widget, jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ beginNativeRepaintID);
+
+ gdk_threads_enter ();
+
+ gdk_window_process_updates (widget->window, TRUE);
+
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ endNativeRepaintID);
+
+ gdk_threads_enter ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c
new file mode 100644
index 00000000000..52922ddb82e
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c
@@ -0,0 +1,58 @@
+/* gtkcanvaspeer.c -- Native implementation of GtkCanvasPeer
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkCanvasPeer.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCanvasPeer_create
+ (JNIEnv *env, jobject obj)
+{
+ gpointer widget;
+
+ gdk_threads_enter ();
+
+ /* Create global reference and save it for future use */
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ widget = gtk_type_new (gtk_drawing_area_get_type ());
+
+ NSA_SET_PTR (env, obj, widget);
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c
new file mode 100644
index 00000000000..4f28750921b
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c
@@ -0,0 +1,77 @@
+/* gtkcheckboxgrouppeer.c -- Native implementation of GtkCheckboxGroupPeer
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_dispose
+ (JNIEnv *env, jobject obj)
+{
+ /* The actual underlying widget is owned by a different class. So
+ we just clean up the hash table here. */
+ NSA_DEL_PTR (env, obj);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_remove
+ (JNIEnv *env, jobject obj, jobject checkbox)
+{
+ GtkRadioButton *button;
+ void *ptr;
+ GSList *list;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, checkbox);
+ button = GTK_RADIO_BUTTON (ptr);
+
+ /* Update the group to point to some other widget in the group. We
+ have to do this because Gtk doesn't have a separate object to
+ represent a radio button's group. */
+ for (list = gtk_radio_button_group (button); list != NULL;
+ list = list->next)
+ {
+ if (list->data != button)
+ break;
+ }
+
+ NSA_SET_PTR (env, obj, list ? list->data : NULL);
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c
new file mode 100644
index 00000000000..77836cedd1e
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c
@@ -0,0 +1,78 @@
+/* gtkmenuitempeer.c -- Native implementation of GtkMenuItemPeer
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer_create
+ (JNIEnv *env, jobject obj, jstring label)
+{
+ GtkWidget *widget;
+ const char *str;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ str = (*env)->GetStringUTFChars (env, label, NULL);
+
+ widget = gtk_check_menu_item_new_with_label (str);
+ gtk_widget_show (widget);
+
+ (*env)->ReleaseStringUTFChars (env, label, str);
+
+ NSA_SET_PTR (env, obj, widget);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer_setState
+ (JNIEnv *env, jobject obj, jboolean state)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (ptr), state);
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c
new file mode 100644
index 00000000000..cf883dd3307
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c
@@ -0,0 +1,240 @@
+/* gtkcheckboxpeer.c -- Native implementation of GtkCheckboxPeer
+ Copyright (C) 1998, 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkCheckboxPeer.h"
+#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
+
+static jmethodID postItemEventID;
+
+void
+cp_gtk_checkbox_init_jni (void)
+{
+ jclass gtkcheckboxpeer;
+
+ gtkcheckboxpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GtkCheckboxPeer");
+
+ postItemEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkcheckboxpeer,
+ "postItemEvent",
+ "(Ljava/lang/Object;I)V");
+}
+
+static void item_toggled_cb (GtkToggleButton *item, jobject peer);
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_create
+ (JNIEnv *env, jobject obj, jobject group)
+{
+ GtkWidget *button;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ if (group == NULL)
+ button = gtk_check_button_new_with_label ("");
+ else
+ {
+ void *native_group = NSA_GET_PTR (env, group);
+ button = gtk_radio_button_new_with_label_from_widget (native_group, "");
+ if (native_group == NULL)
+ {
+ /* Set the native group so we can use the correct value the
+ next time around. FIXME: this doesn't work! */
+ NSA_SET_PTR (env, group, button);
+ }
+ }
+
+ NSA_SET_PTR (env, obj, button);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr = NULL;
+ jobject *gref = NULL;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ /* Checkbox signals */
+ g_signal_connect (G_OBJECT (ptr), "toggled",
+ G_CALLBACK (item_toggled_cb), *gref);
+
+ /* Component signals */
+ cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_nativeSetCheckboxGroup
+ (JNIEnv *env, jobject obj, jobject group)
+{
+ GtkRadioButton *button;
+ void *native_group, *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ /* FIXME: we can't yet switch between a checkbutton and a
+ radiobutton. However, AWT requires this. For now we just
+ crash. */
+
+ button = GTK_RADIO_BUTTON (ptr);
+
+ native_group = NSA_GET_PTR (env, group);
+ if (native_group == NULL)
+ gtk_radio_button_set_group (button, NULL);
+ else
+ gtk_radio_button_set_group (button,
+ gtk_radio_button_group
+ (GTK_RADIO_BUTTON (native_group)));
+
+ /* If the native group wasn't set on the new CheckboxGroup, then set
+ it now so that the right thing will happen with the next
+ radiobutton. The native state for a CheckboxGroup is a pointer
+ to one of the widgets in the group. We are careful to keep this
+ always pointing at a live widget; whenever a widget is destroyed
+ (or otherwise removed from the group), the CheckboxGroup peer is
+ notified. */
+ if (native_group == NULL)
+ NSA_SET_PTR (env, group, native_group);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_gtkToggleButtonSetActive
+ (JNIEnv *env, jobject obj, jboolean is_active)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptr), is_active);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_gtkWidgetModifyFont
+ (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+ const char *font_name;
+ void *ptr;
+ GtkWidget *button;
+ GtkWidget *label;
+ PangoFontDescription *font_desc;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ button = GTK_WIDGET (ptr);
+ label = gtk_bin_get_child (GTK_BIN(button));
+
+ if (!label)
+ return;
+
+ font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+ font_desc = pango_font_description_from_string (font_name);
+ pango_font_description_set_size (font_desc,
+ size * cp_gtk_dpi_conversion_factor);
+
+ if (style & AWT_STYLE_BOLD)
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+ if (style & AWT_STYLE_ITALIC)
+ pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+ gtk_widget_modify_font (GTK_WIDGET(label), font_desc);
+
+ pango_font_description_free (font_desc);
+
+ (*env)->ReleaseStringUTFChars (env, name, font_name);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_gtkButtonSetLabel
+ (JNIEnv *env, jobject obj, jstring label)
+{
+ const char *c_label;
+ GtkWidget *label_widget;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ c_label = (*env)->GetStringUTFChars (env, label, NULL);
+
+ label_widget = gtk_bin_get_child (GTK_BIN (ptr));
+ gtk_label_set_text (GTK_LABEL (label_widget), c_label);
+
+ (*env)->ReleaseStringUTFChars (env, label, c_label);
+
+ gdk_threads_leave ();
+}
+
+static void
+item_toggled_cb (GtkToggleButton *item, jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postItemEventID,
+ peer,
+ item->active ?
+ (jint) AWT_ITEM_SELECTED :
+ (jint) AWT_ITEM_DESELECTED);
+
+ gdk_threads_enter ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c
new file mode 100644
index 00000000000..ed9df543332
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c
@@ -0,0 +1,248 @@
+/* gtkchoicepeer.c -- Native implementation of GtkChoicePeer
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkChoicePeer.h"
+
+static jmethodID postChoiceItemEventID;
+
+void
+cp_gtk_choice_init_jni (void)
+{
+ jclass gtkchoicepeer;
+
+ gtkchoicepeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GtkChoicePeer");
+
+ postChoiceItemEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkchoicepeer,
+ "postChoiceItemEvent",
+ "(Ljava/lang/String;I)V");
+}
+
+static void selection_changed_cb (GtkComboBox *combobox, jobject peer);
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_create
+ (JNIEnv *env, jobject obj)
+{
+ GtkWidget *combobox;
+ jobject *gref;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ combobox = gtk_combo_box_new_text ();
+
+ NSA_SET_PTR (env, obj, combobox);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr = NULL;
+ jobject *gref = NULL;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ /* Choice signals */
+ g_signal_connect (G_OBJECT (ptr), "changed",
+ G_CALLBACK (selection_changed_cb), *gref);
+
+ /* Component signals */
+ cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_append
+ (JNIEnv *env, jobject obj, jobjectArray items)
+{
+ gpointer ptr;
+ jsize count, i;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ count = (*env)->GetArrayLength (env, items);
+
+ for (i = 0; i < count; i++)
+ {
+ jobject item;
+ const char *label;
+
+ item = (*env)->GetObjectArrayElement (env, items, i);
+ label = (*env)->GetStringUTFChars (env, item, NULL);
+
+ gtk_combo_box_append_text (GTK_COMBO_BOX (ptr), label);
+
+ (*env)->ReleaseStringUTFChars (env, item, label);
+ }
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeAdd
+ (JNIEnv *env, jobject obj, jstring item, jint index)
+{
+ void *ptr;
+ const char *label;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ label = (*env)->GetStringUTFChars (env, item, 0);
+
+ gtk_combo_box_insert_text (GTK_COMBO_BOX (ptr), index, label);
+
+ (*env)->ReleaseStringUTFChars (env, item, label);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeRemove
+ (JNIEnv *env, jobject obj, jint index)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_combo_box_remove_text (GTK_COMBO_BOX (ptr), index);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeRemoveAll
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ GtkTreeModel *model;
+ gint count, i;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (ptr));
+ count = gtk_tree_model_iter_n_children (model, NULL);
+
+ /* First, unselect everything, to avoid problems when removing items. */
+ gtk_combo_box_set_active (GTK_COMBO_BOX (ptr), -1);
+
+ for (i = count - 1; i >= 0; i--) {
+ gtk_combo_box_remove_text (GTK_COMBO_BOX (ptr), i);
+ }
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_select
+ (JNIEnv *env, jobject obj, jint index)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (ptr), index);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeGetSelected
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ int index;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ index = gtk_combo_box_get_active (GTK_COMBO_BOX (ptr));
+
+ gdk_threads_leave ();
+
+ return index;
+}
+
+static void selection_changed_cb (GtkComboBox *combobox, jobject peer)
+{
+ jstring label;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *selected;
+ gint index;
+
+ index = gtk_combo_box_get_active(combobox);
+
+ if (index >= 0)
+ {
+ model = gtk_combo_box_get_model (combobox);
+ gtk_combo_box_get_active_iter (combobox, &iter);
+ gtk_tree_model_get (model, &iter, 0, &selected, -1);
+ label = (*cp_gtk_gdk_env())->NewStringUTF (cp_gtk_gdk_env(), selected);
+
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postChoiceItemEventID,
+ label,
+ (jint) AWT_ITEM_SELECTED);
+
+ gdk_threads_enter ();
+ }
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
new file mode 100644
index 00000000000..dea9d4cc7c2
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
@@ -0,0 +1,204 @@
+/* gtkclipboard.c
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkClipboard.h"
+
+static jmethodID stringSelectionReceivedID;
+static jmethodID stringSelectionHandlerID;
+static jmethodID selectionClearID;
+
+static void selection_received_cb (GtkWidget *, GtkSelectionData *,
+ guint, gpointer);
+static void selection_get_cb (GtkWidget *, GtkSelectionData *, guint,
+ guint, gpointer);
+static gint selection_clear_cb (GtkWidget *, GdkEventSelection *);
+
+static GtkWidget *clipboard;
+static jobject cb_obj;
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkClipboard_initNativeState (JNIEnv *env,
+ jobject obj)
+{
+ gdk_threads_enter ();
+
+ if (!stringSelectionReceivedID)
+ {
+ jclass gtkclipboard;
+
+ gtkclipboard = (*env)->FindClass (env,
+ "gnu/java/awt/peer/gtk/GtkClipboard");
+ stringSelectionReceivedID = (*env)->GetMethodID (env, gtkclipboard,
+ "stringSelectionReceived",
+ "(Ljava/lang/String;)V");
+ stringSelectionHandlerID = (*env)->GetMethodID (env, gtkclipboard,
+ "stringSelectionHandler",
+ "()Ljava/lang/String;");
+ selectionClearID = (*env)->GetMethodID (env, gtkclipboard,
+ "selectionClear", "()V");
+ }
+
+ cb_obj = (*env)->NewGlobalRef (env, obj);
+
+ clipboard = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ g_signal_connect (G_OBJECT(clipboard), "selection_received",
+ G_CALLBACK (selection_received_cb), NULL);
+
+ g_signal_connect (G_OBJECT(clipboard), "selection_clear_event",
+ G_CALLBACK (selection_clear_cb), NULL);
+
+ gtk_selection_add_target (clipboard, GDK_SELECTION_PRIMARY,
+ GDK_TARGET_STRING, 0);
+
+ g_signal_connect (G_OBJECT(clipboard), "selection_get",
+ G_CALLBACK (selection_get_cb), NULL);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkClipboard_requestStringConversion
+ (JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused)))
+{
+ gdk_threads_enter ();
+
+ gtk_selection_convert (clipboard, GDK_SELECTION_PRIMARY,
+ GDK_TARGET_STRING, GDK_CURRENT_TIME);
+
+ gdk_threads_leave ();
+}
+
+static void
+selection_received_cb (GtkWidget *widget __attribute__((unused)),
+ GtkSelectionData *selection_data __attribute__((unused)),
+ guint time __attribute__((unused)),
+ gpointer data __attribute__((unused)))
+{
+ /* Check to see if retrieval succeeded */
+ if (selection_data->length < 0
+ || selection_data->type != GDK_SELECTION_TYPE_STRING)
+ {
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), cb_obj, stringSelectionReceivedID,
+ NULL);
+
+ gdk_threads_enter ();
+ }
+ else
+ {
+ char *str = (char *) selection_data->data;
+
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), cb_obj, stringSelectionReceivedID,
+ (*cp_gtk_gdk_env())->NewStringUTF (cp_gtk_gdk_env(), str));
+
+ gdk_threads_enter ();
+ }
+
+ return;
+}
+
+static void
+selection_get_cb (GtkWidget *widget __attribute__((unused)),
+ GtkSelectionData *selection_data,
+ guint info __attribute__((unused)),
+ guint time __attribute__((unused)),
+ gpointer data __attribute__((unused)))
+{
+ jstring jstr;
+ const char *utf;
+ jsize utflen;
+
+ gdk_threads_leave ();
+
+ jstr = (*cp_gtk_gdk_env())->CallObjectMethod (cp_gtk_gdk_env(), cb_obj,
+ stringSelectionHandlerID);
+
+ gdk_threads_enter ();
+
+ if (!jstr)
+ {
+ gtk_selection_data_set (selection_data,
+ GDK_TARGET_STRING, 8, NULL, 0);
+ return;
+ }
+
+ utflen = (*cp_gtk_gdk_env())->GetStringUTFLength (cp_gtk_gdk_env(), jstr);
+ utf = (*cp_gtk_gdk_env())->GetStringUTFChars (cp_gtk_gdk_env(), jstr, NULL);
+
+ gtk_selection_data_set (selection_data, GDK_TARGET_STRING, 8,
+ (const unsigned char*)utf, utflen);
+
+ (*cp_gtk_gdk_env())->ReleaseStringUTFChars (cp_gtk_gdk_env(), jstr, utf);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkClipboard_selectionGet
+ (JNIEnv *env, jclass clazz __attribute__((unused)))
+{
+ GdkWindow *owner;
+
+ gdk_threads_enter ();
+
+ /* if we already own the clipboard, we need to tell the old data object
+ that we're no longer going to be using him */
+ owner = gdk_selection_owner_get (GDK_SELECTION_PRIMARY);
+ if (owner && owner == clipboard->window)
+ (*env)->CallVoidMethod (env, cb_obj, selectionClearID);
+
+ gtk_selection_owner_set (clipboard, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
+
+ gdk_threads_leave ();
+}
+
+static gint
+selection_clear_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventSelection *event __attribute__((unused)))
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), cb_obj, selectionClearID);
+
+ gdk_threads_enter ();
+
+ return TRUE;
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
new file mode 100644
index 00000000000..bd9dde39283
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
@@ -0,0 +1,1161 @@
+/* gtkcomponentpeer.c -- Native implementation of GtkComponentPeer
+ Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
+
+#include <gtk/gtkprivate.h>
+
+#define AWT_DEFAULT_CURSOR 0
+#define AWT_CROSSHAIR_CURSOR 1
+#define AWT_TEXT_CURSOR 2
+#define AWT_WAIT_CURSOR 3
+#define AWT_SW_RESIZE_CURSOR 4
+#define AWT_SE_RESIZE_CURSOR 5
+#define AWT_NW_RESIZE_CURSOR 6
+#define AWT_NE_RESIZE_CURSOR 7
+#define AWT_N_RESIZE_CURSOR 8
+#define AWT_S_RESIZE_CURSOR 9
+#define AWT_W_RESIZE_CURSOR 10
+#define AWT_E_RESIZE_CURSOR 11
+#define AWT_HAND_CURSOR 12
+#define AWT_MOVE_CURSOR 13
+
+#define AWT_BUTTON1_DOWN_MASK (1 << 10)
+#define AWT_BUTTON2_DOWN_MASK (1 << 11)
+#define AWT_BUTTON3_DOWN_MASK (1 << 12)
+
+/* FIXME: use gtk-double-click-time, gtk-double-click-distance */
+#define MULTI_CLICK_TIME 250
+/* as opposed to a MULTI_PASS_TIME :) */
+
+#define AWT_MOUSE_CLICKED 500
+#define AWT_MOUSE_PRESSED 501
+#define AWT_MOUSE_RELEASED 502
+#define AWT_MOUSE_MOVED 503
+#define AWT_MOUSE_ENTERED 504
+#define AWT_MOUSE_EXITED 505
+#define AWT_MOUSE_DRAGGED 506
+
+#define AWT_FOCUS_GAINED 1004
+#define AWT_FOCUS_LOST 1005
+
+static GtkWidget *find_fg_color_widget (GtkWidget *widget);
+static GtkWidget *find_bg_color_widget (GtkWidget *widget);
+
+static jmethodID postMouseEventID;
+static jmethodID setCursorID;
+static jmethodID postExposeEventID;
+static jmethodID postFocusEventID;
+
+void
+cp_gtk_component_init_jni (void)
+ {
+ jclass gtkcomponentpeer;
+
+ gtkcomponentpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GtkComponentPeer");
+
+ postMouseEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkcomponentpeer,
+ "postMouseEvent", "(IJIIIIZ)V");
+
+ setCursorID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkcomponentpeer,
+ "setCursor", "()V");
+
+ postExposeEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkcomponentpeer,
+ "postExposeEvent", "(IIII)V");
+
+ postFocusEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkcomponentpeer,
+ "postFocusEvent", "(IZ)V");
+}
+
+static gboolean component_button_press_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ jobject peer);
+static gboolean component_button_release_cb (GtkWidget *widget,
+ GdkEventButton *event,
+ jobject peer);
+static gboolean component_motion_notify_cb (GtkWidget *widget,
+ GdkEventMotion *event,
+ jobject peer);
+static gboolean component_enter_notify_cb (GtkWidget *widget,
+ GdkEventCrossing *event,
+ jobject peer);
+static gboolean component_leave_notify_cb (GtkWidget *widget,
+ GdkEventCrossing *event,
+ jobject peer);
+static gboolean component_expose_cb (GtkWidget *widget,
+ GdkEventExpose *event,
+ jobject peer);
+static gboolean component_focus_in_cb (GtkWidget *widget,
+ GdkEventFocus *event,
+ jobject peer);
+static gboolean component_focus_out_cb (GtkWidget *widget,
+ GdkEventFocus *event,
+ jobject peer);
+
+static jint
+button_to_awt_mods (int button)
+{
+ switch (button)
+ {
+ case 1:
+ return AWT_BUTTON1_MASK;
+ case 2:
+ return AWT_BUTTON2_MASK;
+ case 3:
+ return AWT_BUTTON3_MASK;
+ }
+
+ return 0;
+}
+
+static jint
+state_to_awt_mods (guint state)
+{
+ jint result = 0;
+
+ if (state & GDK_SHIFT_MASK)
+ result |= AWT_SHIFT_DOWN_MASK;
+ if (state & GDK_CONTROL_MASK)
+ result |= AWT_CTRL_DOWN_MASK;
+ if (state & GDK_MOD1_MASK)
+ result |= AWT_ALT_DOWN_MASK;
+
+ return result;
+}
+
+static jint
+state_to_awt_mods_with_button_states (guint state)
+{
+ jint result = 0;
+
+ if (state & GDK_SHIFT_MASK)
+ result |= AWT_SHIFT_DOWN_MASK;
+ if (state & GDK_CONTROL_MASK)
+ result |= AWT_CTRL_DOWN_MASK;
+ if (state & GDK_MOD1_MASK)
+ result |= AWT_ALT_DOWN_MASK;
+ if (state & GDK_BUTTON1_MASK)
+ result |= AWT_BUTTON1_DOWN_MASK;
+ if (state & GDK_BUTTON2_MASK)
+ result |= AWT_BUTTON2_DOWN_MASK;
+ if (state & GDK_BUTTON3_MASK)
+ result |= AWT_BUTTON3_DOWN_MASK;
+
+ return result;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursor
+ (JNIEnv *env, jobject obj, jint type)
+{
+ void *ptr;
+ GtkWidget *widget;
+ GdkCursorType gdk_cursor_type;
+ GdkCursor *gdk_cursor;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ switch (type)
+ {
+ case AWT_CROSSHAIR_CURSOR:
+ gdk_cursor_type = GDK_CROSSHAIR;
+ break;
+ case AWT_TEXT_CURSOR:
+ gdk_cursor_type = GDK_XTERM;
+ break;
+ case AWT_WAIT_CURSOR:
+ gdk_cursor_type = GDK_WATCH;
+ break;
+ case AWT_SW_RESIZE_CURSOR:
+ gdk_cursor_type = GDK_BOTTOM_LEFT_CORNER;
+ break;
+ case AWT_SE_RESIZE_CURSOR:
+ gdk_cursor_type = GDK_BOTTOM_RIGHT_CORNER;
+ break;
+ case AWT_NW_RESIZE_CURSOR:
+ gdk_cursor_type = GDK_TOP_LEFT_CORNER;
+ break;
+ case AWT_NE_RESIZE_CURSOR:
+ gdk_cursor_type = GDK_TOP_RIGHT_CORNER;
+ break;
+ case AWT_N_RESIZE_CURSOR:
+ gdk_cursor_type = GDK_TOP_SIDE;
+ break;
+ case AWT_S_RESIZE_CURSOR:
+ gdk_cursor_type = GDK_BOTTOM_SIDE;
+ break;
+ case AWT_W_RESIZE_CURSOR:
+ gdk_cursor_type = GDK_LEFT_SIDE;
+ break;
+ case AWT_E_RESIZE_CURSOR:
+ gdk_cursor_type = GDK_RIGHT_SIDE;
+ break;
+ case AWT_HAND_CURSOR:
+ gdk_cursor_type = GDK_HAND2;
+ break;
+ case AWT_MOVE_CURSOR:
+ gdk_cursor_type = GDK_FLEUR;
+ break;
+ default:
+ gdk_cursor_type = GDK_LEFT_PTR;
+ }
+
+ widget = GTK_WIDGET(ptr);
+
+ gdk_cursor = gdk_cursor_new (gdk_cursor_type);
+ gdk_window_set_cursor (widget->window, gdk_cursor);
+ gdk_cursor_destroy (gdk_cursor);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetParent
+ (JNIEnv *env, jobject obj, jobject parent)
+{
+ void *ptr;
+ void *parent_ptr;
+ GtkWidget *widget;
+ GtkWidget *parent_widget;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ parent_ptr = NSA_GET_PTR (env, parent);
+
+ widget = GTK_WIDGET (ptr);
+ parent_widget = GTK_WIDGET (parent_ptr);
+
+ if (widget->parent == NULL)
+ {
+ if (GTK_IS_WINDOW (parent_widget))
+ {
+ GList *children = gtk_container_children
+ (GTK_CONTAINER (parent_widget));
+
+ if (GTK_IS_MENU_BAR (children->data))
+ gtk_fixed_put (GTK_FIXED (children->next->data), widget, 0, 0);
+ else
+ gtk_fixed_put (GTK_FIXED (children->data), widget, 0, 0);
+ }
+ else
+ if (GTK_IS_SCROLLED_WINDOW (parent_widget))
+ {
+ gtk_scrolled_window_add_with_viewport
+ (GTK_SCROLLED_WINDOW (parent_widget), widget);
+ gtk_viewport_set_shadow_type (GTK_VIEWPORT (widget->parent),
+ GTK_SHADOW_NONE);
+
+ }
+ else
+ {
+ if (widget->parent == NULL)
+ gtk_fixed_put (GTK_FIXED (parent_widget), widget, 0, 0);
+ }
+ }
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetSensitive
+ (JNIEnv *env, jobject obj, jboolean sensitive)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (ptr), sensitive);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetRequestFocus
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_widget_grab_focus (GTK_WIDGET (ptr));
+
+ gdk_threads_leave ();
+}
+
+/*
+ * Translate a Java KeyEvent object into a GdkEventKey event, then
+ * pass it to the GTK main loop for processing.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetDispatchKeyEvent
+ (JNIEnv *env, jobject obj, jint id, jlong when, jint mods,
+ jint keyCode, jint keyLocation)
+{
+ void *ptr;
+ GdkEvent *event = NULL;
+ GdkKeymapKey *keymap_keys = NULL;
+ gint n_keys = 0;
+ guint lookup_keyval = 0;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ if (id == AWT_KEY_PRESSED)
+ event = gdk_event_new (GDK_KEY_PRESS);
+ else if (id == AWT_KEY_RELEASED)
+ event = gdk_event_new (GDK_KEY_RELEASE);
+ else
+ {
+ gdk_threads_leave ();
+ /* Don't send AWT KEY_TYPED events to GTK. */
+ return;
+ }
+
+ if (GTK_IS_BUTTON (ptr))
+ event->key.window = GTK_BUTTON (ptr)->event_window;
+ else if (GTK_IS_SCROLLED_WINDOW (ptr))
+ event->key.window = GTK_WIDGET (GTK_SCROLLED_WINDOW (ptr)->container.child)->window;
+ else
+ event->key.window = GTK_WIDGET (ptr)->window;
+
+ event->key.send_event = 0;
+ event->key.time = (guint32) when;
+
+ if (mods & AWT_SHIFT_DOWN_MASK)
+ event->key.state |= GDK_SHIFT_MASK;
+ if (mods & AWT_CTRL_DOWN_MASK)
+ event->key.state |= GDK_CONTROL_MASK;
+ if (mods & AWT_ALT_DOWN_MASK)
+ event->key.state |= GDK_MOD1_MASK;
+
+ /* This hack is needed because the AWT has no notion of num lock.
+ It infers numlock state from the only Java virtual keys that are
+ affected by it. */
+ if (keyCode == VK_NUMPAD9
+ || keyCode == VK_NUMPAD8
+ || keyCode == VK_NUMPAD7
+ || keyCode == VK_NUMPAD6
+ || keyCode == VK_NUMPAD5
+ || keyCode == VK_NUMPAD4
+ || keyCode == VK_NUMPAD3
+ || keyCode == VK_NUMPAD2
+ || keyCode == VK_NUMPAD1
+ || keyCode == VK_NUMPAD0
+ || keyCode == VK_DECIMAL)
+ event->key.state |= GDK_MOD2_MASK;
+
+ /* These values don't need to be filled in since GTK doesn't use
+ them. */
+ event->key.length = 0;
+ event->key.string = NULL;
+
+ lookup_keyval = cp_gtk_awt_keycode_to_keysym (keyCode, keyLocation);
+
+ if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
+ lookup_keyval,
+ &keymap_keys,
+ &n_keys))
+ {
+ /* No matching keymap entry was found. */
+ g_printerr ("No matching keymap entries were found\n");
+ gdk_threads_leave ();
+ return;
+ }
+
+ /* Note: if n_keys > 1 then there are multiple hardware keycodes
+ that translate to lookup_keyval. We arbitrarily choose the first
+ hardware keycode from the list returned by
+ gdk_keymap_get_entries_for_keyval. */
+
+ event->key.hardware_keycode = keymap_keys[0].keycode;
+ event->key.group = keymap_keys[0].group;
+
+ g_free (keymap_keys);
+
+ if (!gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (),
+ event->key.hardware_keycode,
+ event->key.state,
+ event->key.group,
+ &event->key.keyval,
+ NULL, NULL, NULL))
+ {
+ /* No matching keyval was found. */
+ g_printerr ("No matching keyval was found\n");
+ gdk_threads_leave ();
+ return;
+ }
+
+ /* keyevent = (GdkEventKey *) event; */
+ /* g_printerr ("generated event: sent: %d time: %d state: %d keyval: %d length: %d string: %s hardware_keycode: %d group: %d\n", keyevent->send_event, keyevent->time, keyevent->state, keyevent->keyval, keyevent->length, keyevent->string, keyevent->hardware_keycode, keyevent->group); */
+
+ /* We already received the original key event on the window itself,
+ so we don't want to resend it. */
+ if (!GTK_IS_WINDOW (ptr))
+ {
+ if (GTK_IS_SCROLLED_WINDOW (ptr))
+ gtk_widget_event (GTK_WIDGET (GTK_SCROLLED_WINDOW (ptr)->container.child), event);
+ else
+ gtk_widget_event (GTK_WIDGET (ptr), event);
+ }
+
+ gdk_threads_leave ();
+}
+
+/*
+ * Find the origin of a widget's window.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetLocationOnScreen
+ (JNIEnv * env, jobject obj, jintArray jpoint)
+{
+ void *ptr;
+ jint *point;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ point = (*env)->GetIntArrayElements (env, jpoint, 0);
+
+ gdk_window_get_origin (GTK_WIDGET (ptr)->window, point, point+1);
+
+ if (!GTK_IS_CONTAINER (ptr))
+ {
+ *point += GTK_WIDGET(ptr)->allocation.x;
+ *(point+1) += GTK_WIDGET(ptr)->allocation.y;
+ }
+
+ (*env)->ReleaseIntArrayElements(env, jpoint, point, 0);
+
+ gdk_threads_leave ();
+}
+
+/*
+ * Find this widget's current size.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetDimensions
+ (JNIEnv *env, jobject obj, jintArray jdims)
+{
+ void *ptr;
+ jint *dims;
+ GtkRequisition requisition;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ dims = (*env)->GetIntArrayElements (env, jdims, 0);
+ dims[0] = dims[1] = 0;
+
+ gtk_widget_size_request (GTK_WIDGET (ptr), &requisition);
+
+ dims[0] = requisition.width;
+ dims[1] = requisition.height;
+
+ (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
+
+ gdk_threads_leave ();
+}
+
+/*
+ * Find this widget's preferred size.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetPreferredDimensions
+ (JNIEnv *env, jobject obj, jintArray jdims)
+{
+ void *ptr;
+ jint *dims;
+ GtkRequisition current_req;
+ GtkRequisition natural_req;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ dims = (*env)->GetIntArrayElements (env, jdims, 0);
+ dims[0] = dims[1] = 0;
+
+ /* Widgets that extend GtkWindow such as GtkFileChooserDialog may have
+ a default size. These values seem more useful then the natural
+ requisition values, particularly for GtkFileChooserDialog. */
+ if (GTK_IS_WINDOW (ptr))
+ {
+ gint width, height;
+ gtk_window_get_default_size (GTK_WINDOW (ptr), &width, &height);
+
+ dims[0] = width;
+ dims[1] = height;
+ }
+ else
+ {
+ /* Save the widget's current size request. */
+ gtk_widget_size_request (GTK_WIDGET (ptr), &current_req);
+
+ /* Get the widget's "natural" size request. */
+ gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
+ gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
+
+ /* Reset the widget's size request. */
+ gtk_widget_set_size_request (GTK_WIDGET (ptr),
+ current_req.width, current_req.height);
+
+ dims[0] = natural_req.width;
+ dims[1] = natural_req.height;
+ }
+
+ (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setNativeBounds
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+ GtkWidget *widget;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ widget = GTK_WIDGET (ptr);
+
+ /* We assume that -1 is a width or height and not a request for the
+ widget's natural size. */
+ width = width < 0 ? 0 : width;
+ height = height < 0 ? 0 : height;
+
+ if (GTK_IS_VIEWPORT (widget->parent))
+ gtk_widget_set_size_request (widget, width, height);
+ else
+ {
+ if (!(width == 0 && height == 0))
+ {
+ gtk_widget_set_size_request (widget, width, height);
+ if (widget->parent != NULL)
+ gtk_fixed_move (GTK_FIXED (widget->parent), widget, x, y);
+ }
+ }
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetBackground
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jintArray array;
+ int *rgb;
+ GdkColor bg;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ bg = GTK_WIDGET (ptr)->style->bg[GTK_STATE_NORMAL];
+
+ gdk_threads_leave ();
+
+ array = (*env)->NewIntArray (env, 3);
+
+ gdk_threads_enter ();
+
+ rgb = (*env)->GetIntArrayElements (env, array, NULL);
+ /* convert color data from 16 bit values down to 8 bit values */
+ rgb[0] = bg.red >> 8;
+ rgb[1] = bg.green >> 8;
+ rgb[2] = bg.blue >> 8;
+ (*env)->ReleaseIntArrayElements (env, array, rgb, 0);
+
+ gdk_threads_leave ();
+
+ return array;
+}
+
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetForeground
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jintArray array;
+ jint *rgb;
+ GdkColor fg;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ fg = GTK_WIDGET (ptr)->style->fg[GTK_STATE_NORMAL];
+
+ gdk_threads_leave ();
+
+ array = (*env)->NewIntArray (env, 3);
+
+ gdk_threads_enter ();
+
+ rgb = (*env)->GetIntArrayElements (env, array, NULL);
+ /* convert color data from 16 bit values down to 8 bit values */
+ rgb[0] = fg.red >> 8;
+ rgb[1] = fg.green >> 8;
+ rgb[2] = fg.blue >> 8;
+ (*env)->ReleaseIntArrayElements (env, array, rgb, 0);
+
+ gdk_threads_leave ();
+
+ return array;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetBackground
+ (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
+{
+ GdkColor normal_color;
+ GdkColor active_color;
+ GtkWidget *widget;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ normal_color.red = (red / 255.0) * 65535;
+ normal_color.green = (green / 255.0) * 65535;
+ normal_color.blue = (blue / 255.0) * 65535;
+
+ /* This calculation only approximates the active colors produced by
+ Sun's AWT. */
+ active_color.red = 0.85 * (red / 255.0) * 65535;
+ active_color.green = 0.85 * (green / 255.0) * 65535;
+ active_color.blue = 0.85 * (blue / 255.0) * 65535;
+
+ widget = find_bg_color_widget (GTK_WIDGET (ptr));
+
+ gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &normal_color);
+ gtk_widget_modify_bg (widget, GTK_STATE_ACTIVE, &active_color);
+ gtk_widget_modify_bg (widget, GTK_STATE_PRELIGHT, &normal_color);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetForeground
+ (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
+{
+ GdkColor color;
+ GtkWidget *widget;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ color.red = (red / 255.0) * 65535;
+ color.green = (green / 255.0) * 65535;
+ color.blue = (blue / 255.0) * 65535;
+
+ widget = find_fg_color_widget (GTK_WIDGET (ptr));
+
+ gtk_widget_modify_fg (widget, GTK_STATE_NORMAL, &color);
+ gtk_widget_modify_fg (widget, GTK_STATE_ACTIVE, &color);
+ gtk_widget_modify_fg (widget, GTK_STATE_PRELIGHT, &color);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_show
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_widget_show (GTK_WIDGET (ptr));
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_hide
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_widget_hide (GTK_WIDGET (ptr));
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isEnabled
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jboolean ret_val;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ ret_val = GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET (ptr));
+
+ gdk_threads_leave ();
+
+ return ret_val;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isRealized
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jboolean ret_val;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ if (ptr == NULL)
+ return FALSE;
+
+ ret_val = GTK_WIDGET_REALIZED (GTK_WIDGET (ptr));
+
+ gdk_threads_leave ();
+
+ return ret_val;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_modalHasGrab
+ (JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused)))
+{
+ GtkWidget *widget;
+ jboolean retval;
+
+ gdk_threads_enter ();
+
+ widget = gtk_grab_get_current ();
+ retval = (widget && GTK_IS_WINDOW (widget) && GTK_WINDOW (widget)->modal);
+
+ gdk_threads_leave ();
+
+ return retval;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jobject *gref;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ cp_gtk_component_connect_signals (ptr, gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setNativeEventMask
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_widget_add_events (GTK_WIDGET (ptr),
+ GDK_POINTER_MOTION_MASK
+ | GDK_BUTTON_MOTION_MASK
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_KEY_PRESS_MASK
+ | GDK_KEY_RELEASE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK
+ | GDK_STRUCTURE_MASK
+ | GDK_KEY_PRESS_MASK
+ | GDK_FOCUS_CHANGE_MASK);
+
+ gdk_threads_leave ();
+}
+
+/* FIXME: these functions should be implemented by overridding the
+ appropriate GtkComponentPeer methods. */
+static GtkWidget *
+find_fg_color_widget (GtkWidget *widget)
+{
+ GtkWidget *fg_color_widget;
+
+ if (GTK_IS_EVENT_BOX (widget)
+ || (GTK_IS_BUTTON (widget)
+ && !GTK_IS_OPTION_MENU (widget)))
+ fg_color_widget = gtk_bin_get_child (GTK_BIN(widget));
+ else
+ fg_color_widget = widget;
+
+ return fg_color_widget;
+}
+
+static GtkWidget *
+find_bg_color_widget (GtkWidget *widget)
+{
+ GtkWidget *bg_color_widget;
+
+ bg_color_widget = widget;
+
+ return bg_color_widget;
+}
+
+void
+cp_gtk_component_connect_expose_signals (GObject *ptr, jobject *gref)
+{
+ g_signal_connect (G_OBJECT (ptr), "expose-event",
+ G_CALLBACK (component_expose_cb), *gref);
+}
+
+void
+cp_gtk_component_connect_focus_signals (GObject *ptr, jobject *gref)
+{
+ g_signal_connect (G_OBJECT (ptr), "focus-in-event",
+ G_CALLBACK (component_focus_in_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "focus-out-event",
+ G_CALLBACK (component_focus_out_cb), *gref);
+}
+
+void
+cp_gtk_component_connect_mouse_signals (GObject *ptr, jobject *gref)
+{
+ g_signal_connect (G_OBJECT (ptr), "button-press-event",
+ G_CALLBACK (component_button_press_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "button-release-event",
+ G_CALLBACK (component_button_release_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "enter-notify-event",
+ G_CALLBACK (component_enter_notify_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "leave-notify-event",
+ G_CALLBACK (component_leave_notify_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "motion-notify-event",
+ G_CALLBACK (component_motion_notify_cb), *gref);
+}
+
+void
+cp_gtk_component_connect_signals (GObject *ptr, jobject *gref)
+{
+ cp_gtk_component_connect_expose_signals (ptr, gref);
+ cp_gtk_component_connect_focus_signals (ptr, gref);
+ cp_gtk_component_connect_mouse_signals (ptr, gref);
+}
+
+/* These variables are used to keep track of click counts. The AWT
+ allows more than a triple click to occur but GTK doesn't report
+ more-than-triple clicks. */
+static jint click_count = 1;
+static guint32 button_click_time = 0;
+static GdkWindow *button_window = NULL;
+static guint button_number = -1;
+static int hasBeenDragged;
+
+static gboolean
+component_button_press_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventButton *event,
+ jobject peer)
+{
+ /* Ignore double and triple click events. */
+ if (event->type == GDK_2BUTTON_PRESS
+ || event->type == GDK_3BUTTON_PRESS)
+ return FALSE;
+
+ if ((event->time < (button_click_time + MULTI_CLICK_TIME))
+ && (event->window == button_window)
+ && (event->button == button_number))
+ click_count++;
+ else
+ click_count = 1;
+
+ button_click_time = event->time;
+ button_window = event->window;
+ button_number = event->button;
+
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postMouseEventID,
+ AWT_MOUSE_PRESSED,
+ (jlong)event->time,
+ state_to_awt_mods (event->state)
+ | button_to_awt_mods (event->button),
+ (jint)event->x,
+ (jint)event->y,
+ click_count,
+ (event->button == 3) ? JNI_TRUE :
+ JNI_FALSE);
+
+ gdk_threads_enter ();
+
+ hasBeenDragged = FALSE;
+
+ return FALSE;
+}
+
+static gboolean
+component_button_release_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventButton *event,
+ jobject peer)
+{
+ int width, height;
+
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postMouseEventID,
+ AWT_MOUSE_RELEASED,
+ (jlong)event->time,
+ state_to_awt_mods (event->state)
+ | button_to_awt_mods (event->button),
+ (jint)event->x,
+ (jint)event->y,
+ click_count,
+ JNI_FALSE);
+
+ gdk_threads_enter ();
+
+ /* Generate an AWT click event only if the release occured in the
+ window it was pressed in, and the mouse has not been dragged since
+ the last time it was pressed. */
+ gdk_window_get_size (event->window, &width, &height);
+ if (! hasBeenDragged
+ && event->x >= 0
+ && event->y >= 0
+ && event->x <= width
+ && event->y <= height)
+ {
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postMouseEventID,
+ AWT_MOUSE_CLICKED,
+ (jlong)event->time,
+ state_to_awt_mods (event->state)
+ | button_to_awt_mods (event->button),
+ (jint)event->x,
+ (jint)event->y,
+ click_count,
+ JNI_FALSE);
+
+ gdk_threads_enter ();
+ }
+ return FALSE;
+}
+
+static gboolean
+component_motion_notify_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventMotion *event,
+ jobject peer)
+{
+ if (event->state & (GDK_BUTTON1_MASK
+ | GDK_BUTTON2_MASK
+ | GDK_BUTTON3_MASK
+ | GDK_BUTTON4_MASK
+ | GDK_BUTTON5_MASK))
+ {
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postMouseEventID,
+ AWT_MOUSE_DRAGGED,
+ (jlong)event->time,
+ state_to_awt_mods_with_button_states (event->state),
+ (jint)event->x,
+ (jint)event->y,
+ 0,
+ JNI_FALSE);
+
+ gdk_threads_enter ();
+
+ hasBeenDragged = TRUE;
+ }
+ else
+ {
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer, postMouseEventID,
+ AWT_MOUSE_MOVED,
+ (jlong)event->time,
+ state_to_awt_mods (event->state),
+ (jint)event->x,
+ (jint)event->y,
+ 0,
+ JNI_FALSE);
+
+ gdk_threads_enter ();
+ }
+ return FALSE;
+}
+
+static gboolean
+component_enter_notify_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventCrossing *event,
+ jobject peer)
+{
+ /* We are not interested in enter events that are due to
+ grab/ungrab and not to actually crossing boundaries */
+ if (event->mode == GDK_CROSSING_NORMAL)
+ {
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer, postMouseEventID,
+ AWT_MOUSE_ENTERED,
+ (jlong)event->time,
+ state_to_awt_mods_with_button_states (event->state),
+ (jint)event->x,
+ (jint)event->y,
+ 0,
+ JNI_FALSE);
+
+ gdk_threads_enter ();
+ }
+ return FALSE;
+}
+
+static gboolean
+component_leave_notify_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventCrossing *event,
+ jobject peer)
+{
+ /* We are not interested in leave events that are due to
+ grab/ungrab and not to actually crossing boundaries */
+ if (event->mode == GDK_CROSSING_NORMAL)
+ {
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postMouseEventID,
+ AWT_MOUSE_EXITED,
+ (jlong)event->time,
+ state_to_awt_mods_with_button_states (event->state),
+ (jint)event->x,
+ (jint)event->y,
+ 0,
+ JNI_FALSE);
+
+ gdk_threads_enter ();
+ }
+ return FALSE;
+}
+
+static gboolean
+component_expose_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventExpose *event,
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postExposeEventID,
+ (jint)event->area.x,
+ (jint)event->area.y,
+ (jint)event->area.width,
+ (jint)event->area.height);
+
+ gdk_threads_enter ();
+
+ return FALSE;
+}
+
+static gboolean
+component_focus_in_cb (GtkWidget *widget __attribute((unused)),
+ GdkEventFocus *event __attribute((unused)),
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postFocusEventID,
+ AWT_FOCUS_GAINED,
+ JNI_FALSE);
+
+ gdk_threads_enter ();
+
+ return FALSE;
+}
+
+static gboolean
+component_focus_out_cb (GtkWidget *widget __attribute((unused)),
+ GdkEventFocus *event __attribute((unused)),
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postFocusEventID,
+ AWT_FOCUS_LOST,
+ JNI_FALSE);
+
+ gdk_threads_enter ();
+
+ return FALSE;
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c
new file mode 100644
index 00000000000..563a0257eca
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c
@@ -0,0 +1,82 @@
+/* gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c -- Native
+ implementation of GtkEmbeddedWindowPeer
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer_create
+ (JNIEnv *env, jobject obj, jlong socket_id)
+{
+ GtkWidget *window;
+ GtkWidget *fixed;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ window = gtk_plug_new ((GdkNativeWindow) socket_id);
+
+ fixed = gtk_fixed_new ();
+ gtk_container_add (GTK_CONTAINER (window), fixed);
+
+ gtk_widget_show (fixed);
+
+ NSA_SET_PTR (env, obj, window);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer_construct
+ (JNIEnv *env, jobject obj, jlong socket_id)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ if (GTK_WIDGET_REALIZED (GTK_WIDGET (ptr)))
+ g_printerr ("ERROR: GtkPlug is already realized\n");
+
+ gtk_plug_construct (GTK_PLUG (ptr), (GdkNativeWindow) socket_id);
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c
new file mode 100644
index 00000000000..48478d3b9bb
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c
@@ -0,0 +1,281 @@
+/* gtkfiledialogpeer.c -- Native implementation of GtkFileDialogPeer
+ Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
+#include "gnu_java_awt_peer_gtk_GtkFileDialogPeer.h"
+
+static void handle_response_cb (GtkDialog *dialog,
+ gint responseId,
+ jobject peer_obj);
+
+/*
+ * Make a new file selection dialog
+ */
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_create
+ (JNIEnv *env, jobject obj, jobject parent)
+{
+ void *parentp;
+ gpointer widget;
+
+ gdk_threads_enter ();
+
+ /* Create global reference and save it for future use */
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ parentp = NSA_GET_PTR(env, parent);
+
+ /* FIXME: we should be using the default gnome-vfs backend but it is
+ not currently thread-safe. See:
+ http://bugzilla.gnome.org/show_bug.cgi?id=166852 */
+ widget = gtk_file_chooser_dialog_new_with_backend
+ ("Open File",
+ GTK_WINDOW(parentp),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ "gtk+",
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ /* GtkFileSelect is not modal by default */
+ gtk_window_set_modal (GTK_WINDOW (widget), TRUE);
+
+ /* We must add this window to the group so input in the others are
+ disable while it is being shown */
+ gtk_window_group_add_window (cp_gtk_global_window_group,
+ GTK_WINDOW (widget));
+
+ NSA_SET_PTR (env, obj, widget);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr = NULL;
+ jobject *gref = NULL;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ /* FileDialog signals */
+ g_signal_connect (G_OBJECT (ptr), "response",
+ G_CALLBACK (handle_response_cb), *gref);
+
+ /* Component signals */
+ cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeGetDirectory
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ const char *str;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ str = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER(ptr));
+
+ gdk_threads_leave ();
+
+ return (*env)->NewStringUTF(env, str);
+}
+
+
+/* This function interfaces with the Java callback method of the same name.
+ This function extracts the filename from the GtkFileFilterInfo object,
+ and passes it to the Java method. The Java method will call the filter's
+ accept() method and will give back the return value. */
+static gboolean filenameFilterCallback (const GtkFileFilterInfo *filter_info,
+ gpointer obj)
+{
+ jclass cx;
+ jmethodID id;
+ jstring *filename;
+ gboolean accepted;
+
+ cx = (*cp_gtk_gdk_env())->GetObjectClass (cp_gtk_gdk_env(), (jobject) obj);
+ id = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), cx, "filenameFilterCallback",
+ "(Ljava/lang/String;)Z");
+
+ filename = (*cp_gtk_gdk_env())->NewStringUTF(cp_gtk_gdk_env(), filter_info->filename);
+
+ gdk_threads_leave();
+
+ accepted = (*cp_gtk_gdk_env())->CallBooleanMethod(cp_gtk_gdk_env(), obj, id, filename);
+
+ gdk_threads_enter();
+
+ return accepted;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetFilenameFilter
+ (JNIEnv *env, jobject obj, jobject filter_obj __attribute__((unused)))
+{
+ void *ptr;
+ GtkFileFilter *filter;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ filter = gtk_file_filter_new();
+ gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
+ filenameFilterCallback, obj, NULL);
+
+ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(ptr), filter);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetDirectory
+ (JNIEnv *env, jobject obj, jstring directory)
+{
+ void *ptr;
+ const char *str;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ str = (*env)->GetStringUTFChars (env, directory, 0);
+
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(ptr), str);
+
+ (*env)->ReleaseStringUTFChars (env, directory, str);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetFile
+ (JNIEnv *env, jobject obj, jstring filename)
+{
+ void *ptr;
+ const char *str;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ str = (*env)->GetStringUTFChars (env, filename, 0);
+
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (ptr), str);
+
+ (*env)->ReleaseStringUTFChars (env, filename, str);
+
+ gdk_threads_leave ();
+}
+
+static void
+handle_response_cb (GtkDialog *dialog __attribute__((unused)),
+ gint responseId,
+ jobject peer_obj)
+{
+ static int isDisposeIDSet = 0;
+ static int isIDSet = 0;
+ static jmethodID gtkSetFilenameID;
+ static jmethodID hideID;
+ static jmethodID disposeID;
+ void *ptr;
+ G_CONST_RETURN gchar *fileName;
+ jstring str_fileName = NULL;
+
+ /* We only need this for the case when the user closed the window,
+ or clicked ok or cancel. */
+ if (responseId != GTK_RESPONSE_DELETE_EVENT
+ && responseId != GTK_RESPONSE_ACCEPT
+ && responseId != GTK_RESPONSE_CANCEL)
+ return;
+
+ ptr = NSA_GET_PTR (cp_gtk_gdk_env(), peer_obj);
+
+ if (responseId == GTK_RESPONSE_DELETE_EVENT)
+ {
+ if (!isDisposeIDSet)
+ {
+ jclass cx = (*cp_gtk_gdk_env())->GetObjectClass (cp_gtk_gdk_env(), peer_obj);
+ disposeID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), cx, "gtkDisposeFileDialog", "()V");
+ isDisposeIDSet = 1;
+ }
+
+ /* We can dispose of the dialog now (and unblock show) */
+ gdk_threads_leave ();
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer_obj, disposeID);
+ gdk_threads_enter ();
+
+ return;
+ }
+
+ if (responseId == GTK_RESPONSE_ACCEPT) {
+ fileName = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (GTK_WIDGET (ptr)));
+ str_fileName = (*cp_gtk_gdk_env())->NewStringUTF (cp_gtk_gdk_env(), fileName);
+ }
+
+ if (!isIDSet)
+ {
+ jclass cx = (*cp_gtk_gdk_env())->GetObjectClass (cp_gtk_gdk_env(), peer_obj);
+ hideID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), cx, "gtkHideFileDialog", "()V");
+ gtkSetFilenameID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), cx,
+ "gtkSetFilename", "(Ljava/lang/String;)V");
+ isIDSet = 1;
+ }
+
+ /* Set the Java object field 'file' with this value. */
+ gdk_threads_leave ();
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer_obj, gtkSetFilenameID, str_fileName);
+
+ /* We can hide the dialog now (and unblock show) */
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer_obj, hideID);
+
+ gdk_threads_enter ();
+}
+
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
new file mode 100644
index 00000000000..41dfcea67b2
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
@@ -0,0 +1,180 @@
+/* gtkframepeer.c -- Native implementation of GtkFramePeer
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkFramePeer.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_removeMenuBarPeer
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ void *mptr;
+ void *fixed;
+ GList* children;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ fixed = gtk_container_get_children (GTK_CONTAINER (ptr))->data;
+ children = gtk_container_get_children (GTK_CONTAINER (fixed));
+
+ while (children != NULL && !GTK_IS_MENU_SHELL (children->data))
+ {
+ children = children->next;
+ }
+
+ /* If there's a menu bar, remove it. */
+ if (children != NULL)
+ {
+ mptr = children->data;
+
+ /* This will actually destroy the MenuBar. By removing it from
+ its parent, the reference count for the MenuBar widget will
+ decrement to 0. The widget will be automatically destroyed by
+ GTK. */
+ gtk_container_remove (GTK_CONTAINER (fixed), GTK_WIDGET (mptr));
+ }
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_setMenuBarPeer
+ (JNIEnv *env, jobject obj, jobject menubar)
+{
+ void *ptr;
+ void *mptr;
+ void *fixed;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ mptr = NSA_GET_PTR (env, menubar);
+
+ fixed = gtk_container_get_children (GTK_CONTAINER (ptr))->data;
+ gtk_fixed_put (GTK_FIXED (fixed), mptr, 0, 0);
+ gtk_widget_show (mptr);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_getMenuBarHeight
+ (JNIEnv *env, jobject obj __attribute__((unused)), jobject menubar)
+{
+ GtkWidget *ptr;
+ GtkRequisition requisition;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, menubar);
+
+ gtk_widget_size_request (ptr, &requisition);
+
+ gdk_threads_leave ();
+
+ return requisition.height;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_setMenuBarWidth
+ (JNIEnv *env, jobject obj __attribute__((unused)), jobject menubar, jint width)
+{
+ GtkWidget *ptr;
+ GtkRequisition natural_req;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, menubar);
+
+ /* Get the menubar's natural size request. */
+ gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
+ gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
+
+ /* Set the menubar's size request to width by natural_req.height. */
+ gtk_widget_set_size_request (GTK_WIDGET (ptr),
+ width, natural_req.height);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_gtkFixedSetVisible
+ (JNIEnv *env, jobject obj, jboolean visible)
+{
+ void *ptr;
+ void *fixed;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ fixed = gtk_container_get_children (GTK_CONTAINER (ptr))->data;
+
+ if (visible)
+ gtk_widget_show (GTK_WIDGET (fixed));
+ else
+ gtk_widget_hide (GTK_WIDGET (fixed));
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_nativeSetIconImage
+ (JNIEnv *env, jobject obj, jobject gtkimage)
+{
+ void *ptr;
+ GdkPixbuf *pixbuf = NULL;
+
+ gdk_threads_enter ();
+
+ pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage);
+ g_assert (pixbuf != NULL);
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_window_set_icon (GTK_WINDOW (ptr), pixbuf);
+
+ /* if the GtkImage is offscreen, this is a temporary pixbuf which should
+ be thrown out. */
+ if(cp_gtk_image_is_offscreen (env, gtkimage) == JNI_TRUE)
+ gdk_pixbuf_unref (pixbuf);
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c
new file mode 100644
index 00000000000..0fae1da42b4
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c
@@ -0,0 +1,101 @@
+/* gtkgenericpeer.c -- Native implementation of GtkGenericPeer
+ Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkGenericPeer.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkGenericPeer_dispose
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ /* For now the native state for any object must be a widget.
+ However, a subclass could override dispose() if required. */
+ gtk_widget_destroy (GTK_WIDGET (ptr));
+
+ /* Remove entries from state tables */
+ NSA_DEL_GLOBAL_REF (env, obj);
+ NSA_DEL_PTR (env, obj);
+
+ gdk_threads_leave ();
+
+ /*
+ * Wake up the main thread, to make sure it re-checks the window
+ * destruction condition.
+ */
+
+ g_main_context_wakeup (NULL);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkGenericPeer_gtkWidgetModifyFont
+ (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+ const char *font_name;
+ void *ptr;
+ PangoFontDescription *font_desc;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+ font_desc = pango_font_description_from_string (font_name);
+ pango_font_description_set_size (font_desc,
+ size * cp_gtk_dpi_conversion_factor);
+
+ if (style & AWT_STYLE_BOLD)
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+ if (style & AWT_STYLE_ITALIC)
+ pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+ gtk_widget_modify_font (GTK_WIDGET(ptr), font_desc);
+
+ pango_font_description_free (font_desc);
+
+ (*env)->ReleaseStringUTFChars (env, name, font_name);
+
+ gdk_threads_leave();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
new file mode 100644
index 00000000000..86cad1487c6
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
@@ -0,0 +1,621 @@
+/* gtkimage.c
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkImage.h"
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+/* The constant fields in java.awt.Image */
+#define SCALE_DEFAULT 1
+#define SCALE_FAST 2
+#define SCALE_SMOOTH 4
+#define SCALE_REPLICATE 8
+#define SCALE_AREA_AVERAGING 16
+
+/* local stuff */
+static GdkInterpType mapHints(jint hints);
+static jboolean offScreen (JNIEnv * env, jobject obj);
+static void *getData (JNIEnv * env, jobject obj);
+static void createRawData (JNIEnv * env, jobject obj, void *ptr);
+static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height);
+
+/**
+ * Loads a pixmap from a file.
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_loadPixbuf
+ (JNIEnv *env, jobject obj, jstring name)
+{
+ const char *filename;
+ int width, height;
+ GdkPixbuf *pixbuf;
+
+ gdk_threads_enter ();
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+
+ if (filename == NULL)
+ {
+ gdk_threads_leave ();
+ return JNI_FALSE;
+ }
+
+ pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
+ if (pixbuf == NULL)
+ {
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+ gdk_threads_leave ();
+ return JNI_FALSE;
+ }
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+
+ createRawData (env, obj, pixbuf);
+ setWidthHeight(env, obj, width, height);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+
+ gdk_threads_leave ();
+
+ return JNI_TRUE;
+}
+
+/**
+ * Returns a copy of the pixel data as a java array.
+ */
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_getPixels(JNIEnv *env, jobject obj)
+{
+ GdkPixbuf *pixbuf;
+ int width, height, rowstride;
+ guchar *pixeldata;
+ jintArray result_array;
+ jint *result_array_iter, *dst;
+ int i,j;
+
+ gdk_threads_enter ();
+
+ pixbuf = cp_gtk_image_get_pixbuf (env, obj);
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ /* Must release the GDK lock before allocating memory through the
+ JVM, since some JVMs use the same lock for allocations and
+ finalization. Deadlock can occur on those JVMs. */
+ gdk_threads_leave ();
+
+ result_array = (*env)->NewIntArray (env, (width * height));
+
+ gdk_threads_enter ();
+
+ dst = result_array_iter =
+ (*env)->GetIntArrayElements (env, result_array, NULL);
+
+
+ pixeldata = gdk_pixbuf_get_pixels (pixbuf);
+
+ g_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
+
+ if (gdk_pixbuf_get_has_alpha (pixbuf))
+ {
+ for(i = 0 ; i < height; i++)
+ {
+ memcpy(dst, (void *)pixeldata, width * 4);
+ dst += width;
+ pixeldata += rowstride;
+ }
+ } else {
+ for(i = 0; i < height; i++)
+ {
+ for(j = 0; j < width; j++)
+ dst[j] = 0xFF000000 |
+ (pixeldata[j*3 + 2] & 0xFF) << 16 |
+ (pixeldata[j*3 + 1] & 0xFF) << 8 |
+ (pixeldata[j*3] & 0xFF);
+ dst += width;
+ pixeldata += rowstride;
+ }
+ }
+
+ if (offScreen (env, obj) == JNI_TRUE)
+ gdk_pixbuf_unref (pixbuf);
+
+ (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
+
+ gdk_threads_leave ();
+
+ return result_array;
+}
+
+/**
+ * Returns a copy of the pixel data as a java array.
+ * (GdkPixbuf only)
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_setPixels(JNIEnv *env, jobject obj,
+ jintArray pixels)
+{
+ GdkPixbuf *pixbuf = (GdkPixbuf *)getData (env, obj);
+ int width, height, rowstride;
+ guchar *pixeldata;
+ jint *src_array_iter, *src;
+ int i;
+
+ gdk_threads_enter ();
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ src = src_array_iter =
+ (*env)->GetIntArrayElements (env, pixels, NULL);
+
+ pixeldata = gdk_pixbuf_get_pixels (pixbuf);
+ for(i = 0 ; i < height; i++)
+ {
+ memcpy((void *)pixeldata, (void *)src, width * 4);
+ src += width;
+ pixeldata += rowstride;
+ }
+
+ (*env)->ReleaseIntArrayElements (env, pixels, src_array_iter, 0);
+
+ gdk_threads_leave ();
+}
+
+/**
+ * Allocates a Gtk Pixbuf or Pixmap.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_createPixmap(JNIEnv *env, jobject obj)
+{
+ int width, height;
+ jclass cls;
+ jfieldID field;
+
+ gdk_threads_enter ();
+
+ cls = (*env)->GetObjectClass (env, obj);
+ field = (*env)->GetFieldID (env, cls, "width", "I");
+ g_assert (field != 0);
+ width = (*env)->GetIntField (env, obj, field);
+
+ field = (*env)->GetFieldID (env, cls, "height", "I");
+ g_assert (field != 0);
+ height = (*env)->GetIntField (env, obj, field);
+
+ if (offScreen (env, obj) == JNI_FALSE)
+ createRawData (env, obj, gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ TRUE,
+ 8,
+ width,
+ height));
+ else
+ createRawData (env, obj, gdk_pixmap_new (NULL, width, height,
+ gdk_rgb_get_visual ()->depth));
+
+ gdk_threads_leave ();
+}
+
+/**
+ * Frees the Gtk Pixmap.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_freePixmap(JNIEnv *env, jobject obj)
+{
+ gdk_threads_enter ();
+ if (offScreen (env, obj) == JNI_FALSE)
+ gdk_pixbuf_unref ((GdkPixbuf *)getData (env, obj));
+ else
+ gdk_pixmap_unref ((GdkPixmap *)getData (env, obj));
+
+ gdk_threads_leave ();
+}
+
+/**
+ * Sets this pixmap to a scaled version of the source pixmap.
+ * width and height of the destination GtkImage must be set.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixmap(JNIEnv *env,
+ jobject destination,
+ jobject source,
+ jint hints)
+{
+ GdkPixbuf* dst;
+ int width, height;
+ jclass cls;
+ jfieldID field;
+
+ GdkPixbuf *pixbuf;
+
+ gdk_threads_enter ();
+
+ cls = (*env)->GetObjectClass (env, destination);
+ field = (*env)->GetFieldID (env, cls, "width", "I");
+ g_assert (field != 0);
+ width = (*env)->GetIntField (env, destination, field);
+
+ field = (*env)->GetFieldID (env, cls, "height", "I");
+ g_assert (field != 0);
+ height = (*env)->GetIntField (env, destination, field);
+
+ pixbuf = cp_gtk_image_get_pixbuf (env, source);
+
+ dst = gdk_pixbuf_scale_simple(pixbuf,
+ width, height,
+ mapHints(hints));
+
+ if (offScreen (env, source) == JNI_TRUE)
+ gdk_pixbuf_unref (pixbuf);
+
+ createRawData (env, destination, (void *)dst);
+
+ gdk_threads_leave ();
+}
+
+/**
+ * Draws the pixbuf at x, y, scaled to width and height and
+ * optionally composited with a given background color.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaled
+ (JNIEnv *env, jobject obj, jobject gc_obj,
+ jint bg_red, jint bg_green, jint bg_blue,
+ jint x, jint y, jint width, jint height, jboolean composite)
+{
+ GdkPixbuf* dst;
+ struct graphics *g;
+ guint32 bgColor;
+
+ gdk_threads_enter ();
+
+ bgColor = ((bg_red & 0xFF) << 16) |
+ ((bg_green & 0xFF) << 8) | (bg_blue & 0xFF);
+
+ g = (struct graphics *) NSA_GET_PTR (env, gc_obj);
+
+ if (!g || !GDK_IS_DRAWABLE (g->drawable))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ if (offScreen (env, obj) == JNI_FALSE)
+ {
+ GdkPixbuf* pixbuf = (GdkPixbuf *)getData (env, obj);
+
+ /* Scale and composite the image */
+ if (composite == JNI_TRUE)
+ dst = gdk_pixbuf_composite_color_simple (pixbuf,
+ width,
+ height,
+ GDK_INTERP_BILINEAR,
+ 255,
+ width,
+ bgColor,
+ bgColor);
+ else
+ dst = gdk_pixbuf_scale_simple(pixbuf,
+ width, height,
+ GDK_INTERP_BILINEAR);
+
+ gdk_draw_pixbuf (g->drawable,
+ g->gc,
+ dst,
+ 0, 0,
+ x + g->x_offset, y + g->y_offset,
+ width, height,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+ gdk_pixbuf_unref (dst);
+
+ } else {
+ /* Get a pixmap */
+ GdkPixmap* pixmap = (GdkPixmap *)getData (env, obj);
+ gdk_draw_drawable (g->drawable,
+ g->gc,
+ pixmap,
+ 0, 0, /* src x,y */
+ x + g->x_offset, y + g->y_offset,
+ width, height);
+ }
+
+ gdk_threads_leave ();
+}
+
+/**
+ * Draws the pixbuf at x, y, scaled to width and height and
+ * optionally composited and/or flipped with a given background color.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaledFlipped
+(JNIEnv *env, jobject obj, jobject gc_obj,
+ jint bg_red, jint bg_green, jint bg_blue,
+ jboolean flipx, jboolean flipy,
+ jint srcx, jint srcy, jint srcwidth, jint srcheight,
+ jint dstx, jint dsty, jint dstwidth, jint dstheight,
+ jboolean composite)
+{
+ GdkPixbuf *pixbuf;
+ GdkPixbuf *tmp, *dst;
+ struct graphics *g;
+ guint32 bgColor;
+
+ gdk_threads_enter ();
+
+ bgColor = ((bg_red & 0xFF) << 16) |
+ ((bg_green & 0xFF) << 8) | (bg_blue & 0xFF);
+
+ g = (struct graphics *) NSA_GET_PTR (env, gc_obj);
+
+ if (!g || !GDK_IS_DRAWABLE (g->drawable))
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ if (offScreen (env, obj) == JNI_FALSE)
+ {
+ pixbuf = (GdkPixbuf *)getData (env, obj);
+
+ /* Get the source area */
+ tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ TRUE,
+ 8,
+ srcwidth,
+ srcheight);
+
+ gdk_pixbuf_copy_area (pixbuf,
+ srcx, srcy,
+ srcwidth, srcheight,
+ tmp,
+ 0, 0); /* dst x , dst y */
+ } else {
+ /* Get a pixbuf from the pixmap */
+ GdkDrawable *pixmap = (GdkDrawable *)getData(env, obj);
+ tmp = gdk_pixbuf_get_from_drawable (NULL,
+ pixmap,
+ gdk_drawable_get_colormap( pixmap ),
+ srcx, srcy,
+ 0, 0, /* dst x , dst y */
+ srcwidth, srcheight);
+ }
+
+ /* FIXME: This #if should be discarded once I feel comfortable about
+ GTK 2.6 dependence */
+#if GTK_MINOR_VERSION > 4
+ /* Flip it if necessary. */
+ if (flipx == JNI_TRUE)
+ {
+ GdkPixbuf *tmp2 = gdk_pixbuf_flip (tmp, TRUE);
+ gdk_pixbuf_unref (tmp);
+ tmp = tmp2;
+ }
+ if (flipy == JNI_TRUE)
+ {
+ GdkPixbuf *tmp2 = gdk_pixbuf_flip (tmp, FALSE);
+ gdk_pixbuf_unref (tmp);
+ tmp = tmp2;
+ }
+#endif
+
+ /* Scale and composite the image */
+ if (composite == JNI_TRUE)
+ dst = gdk_pixbuf_composite_color_simple (tmp,
+ dstwidth,
+ dstheight,
+ GDK_INTERP_BILINEAR,
+ 255,
+ dstwidth,
+ bgColor,
+ bgColor);
+ else
+ dst = gdk_pixbuf_scale_simple(tmp,
+ dstwidth, dstheight,
+ GDK_INTERP_BILINEAR);
+ gdk_pixbuf_unref (tmp);
+
+ gdk_draw_pixbuf (g->drawable,
+ g->gc,
+ dst,
+ 0, 0,
+ dstx + g->x_offset, dsty + g->y_offset,
+ dstwidth, dstheight,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+
+ gdk_pixbuf_unref (dst);
+
+ gdk_threads_leave ();
+}
+
+/**
+ * Used by GtkFramePeer
+ */
+GdkPixbuf *cp_gtk_image_get_pixbuf (JNIEnv *env, jobject obj)
+{
+ int width, height;
+ GdkPixbuf *pixbuf;
+ GdkPixmap* pixmap;
+ jclass cls;
+ jfieldID field;
+
+ if (offScreen (env, obj) == JNI_FALSE)
+ return (GdkPixbuf *)getData (env, obj);
+
+ cls = (*env)->GetObjectClass (env, obj);
+ field = (*env)->GetFieldID (env, cls, "width", "I");
+ g_assert (field != 0);
+ width = (*env)->GetIntField (env, obj, field);
+
+ field = (*env)->GetFieldID (env, cls, "height", "I");
+ g_assert (field != 0);
+ height = (*env)->GetIntField (env, obj, field);
+
+ /* Get a pixmap */
+ pixmap = (GdkPixmap *)getData (env, obj);
+ pixbuf = gdk_pixbuf_get_from_drawable (NULL,
+ pixmap,
+ gdk_drawable_get_colormap( pixmap ),
+ 0, 0, /* src x , src y */
+ 0, 0, /* dst x , dst y */
+ width, height);
+ return pixbuf;
+}
+
+/**
+ * Used by GdkGraphics
+ */
+GdkPixmap *cp_gtk_image_get_pixmap (JNIEnv *env, jobject obj)
+{
+ if (offScreen (env, obj) == JNI_FALSE)
+ return NULL;
+ return (GdkPixmap *)getData (env, obj);
+}
+
+jboolean cp_gtk_image_is_offscreen (JNIEnv *env, jobject obj)
+{
+ return offScreen(env, obj);
+}
+
+/**
+ * Maps java.awt.Image scaling hints to the native GDK ones.
+ */
+static GdkInterpType mapHints(jint hints)
+{
+ switch ( hints )
+ {
+ /* For FAST, we use the nearest-neighbor. Fastest and lowest quality. */
+ case SCALE_FAST:
+ case SCALE_REPLICATE:
+ return GDK_INTERP_NEAREST;
+
+ /* Hyperbolic for smooth. Slowest too. */
+ case SCALE_SMOOTH:
+ return GDK_INTERP_HYPER;
+
+ /* the inbetweenish method */
+ case SCALE_AREA_AVERAGING:
+ return GDK_INTERP_TILES;
+
+ /* default to bilinear */
+ }
+ return GDK_INTERP_BILINEAR;
+}
+
+/* Sets the width and height fields of a GtkImage object. */
+static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height)
+{
+ jclass cls;
+ jfieldID field;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ g_assert (cls != 0);
+ field = (*env)->GetFieldID (env, cls, "width", "I");
+ g_assert (field != 0);
+ (*env)->SetIntField (env, obj, field, (jint)width);
+
+ field = (*env)->GetFieldID (env, cls, "height", "I");
+ g_assert (field != 0);
+ (*env)->SetIntField (env, obj, field, (jint)height);
+}
+
+/* Returns the value of the offScreen field. */
+static jboolean offScreen (JNIEnv *env, jobject obj)
+{
+ jclass cls;
+ jfieldID field;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ field = (*env)->GetFieldID (env, cls, "offScreen", "Z");
+ g_assert (field != 0);
+ return (*env)->GetBooleanField (env, obj, field);
+}
+
+/* Store and get the pixbuf pointer */
+static void
+createRawData (JNIEnv * env, jobject obj, void *ptr)
+{
+ jclass cls;
+ jmethodID method;
+ jobject data;
+ jfieldID data_fid;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ data_fid = (*env)->GetFieldID (env, cls, "pixmap",
+ "Lgnu/classpath/RawData;");
+ g_assert (data_fid != 0);
+
+#if SIZEOF_VOID_P == 8
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(J)V");
+ data = (*env)->NewObject (env, cls, method, (jlong) ptr);
+#else
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
+ data = (*env)->NewObject (env, cls, method, (jint) ptr);
+#endif
+
+ (*env)->SetObjectField (env, obj, data_fid, data);
+}
+
+static void *
+getData (JNIEnv * env, jobject obj)
+{
+ jclass cls;
+ jfieldID field;
+ jfieldID data_fid;
+ jobject data;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ data_fid = (*env)->GetFieldID (env, cls, "pixmap",
+ "Lgnu/classpath/RawData;");
+ g_assert (data_fid != 0);
+ data = (*env)->GetObjectField (env, obj, data_fid);
+
+#if SIZEOF_VOID_P == 8
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ field = (*env)->GetFieldID (env, cls, "data", "J");
+ return (void *) (*env)->GetLongField (env, data, field);
+#else
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ field = (*env)->GetFieldID (env, cls, "data", "I");
+ return (void *) (*env)->GetIntField (env, data, field);
+#endif
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c
new file mode 100644
index 00000000000..7968ca77371
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c
@@ -0,0 +1,183 @@
+/* gtklabelpeer.c -- Native implementation of GtkLabelPeer
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkLabelPeer.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkLabelPeer_create
+ (JNIEnv *env, jobject obj, jstring text, jfloat xalign)
+{
+ GtkWidget *label;
+ GtkWidget *eventbox;
+ const char *str;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ str = (*env)->GetStringUTFChars (env, text, 0);
+
+ eventbox = gtk_event_box_new ();
+ label = gtk_label_new (str);
+ gtk_misc_set_alignment (GTK_MISC (label), xalign, 0.5);
+ gtk_container_add (GTK_CONTAINER (eventbox), label);
+ gtk_widget_show (label);
+
+ (*env)->ReleaseStringUTFChars (env, text, str);
+
+ NSA_SET_PTR (env, obj, eventbox);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkLabelPeer_gtkWidgetModifyFont
+ (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+ const char *font_name;
+ void *ptr;
+ GtkWidget *label;
+ PangoFontDescription *font_desc;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+ label = gtk_bin_get_child (GTK_BIN (ptr));
+
+ if (!label)
+ {
+ gdk_threads_leave ();
+ return;
+ }
+
+ font_desc = pango_font_description_from_string (font_name);
+ pango_font_description_set_size (font_desc,
+ size * cp_gtk_dpi_conversion_factor);
+
+ if (style & AWT_STYLE_BOLD)
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+ if (style & AWT_STYLE_ITALIC)
+ pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+ gtk_widget_modify_font (GTK_WIDGET (label), font_desc);
+
+ pango_font_description_free (font_desc);
+
+ (*env)->ReleaseStringUTFChars (env, name, font_name);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkLabelPeer_setText
+ (JNIEnv *env, jobject obj, jstring text)
+{
+ const char *str;
+ void *ptr;
+ GtkWidget *label;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ str = (*env)->GetStringUTFChars (env, text, 0);
+
+ label = gtk_bin_get_child (GTK_BIN (ptr));
+
+ gtk_label_set_label (GTK_LABEL (label), str);
+
+ (*env)->ReleaseStringUTFChars (env, text, str);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkLabelPeer_nativeSetAlignment
+ (JNIEnv *env, jobject obj, jfloat xalign)
+{
+ void *ptr;
+ GtkWidget *label;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ label = gtk_bin_get_child (GTK_BIN(ptr));
+
+ gtk_misc_set_alignment (GTK_MISC (label), xalign, 0.5);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkLabelPeer_setNativeBounds
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+ GtkWidget *widget;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ widget = GTK_WIDGET (ptr);
+
+ /* We assume that -1 is a width or height and not a request for the
+ widget's natural size. */
+ width = width < 0 ? 0 : width;
+ height = height < 0 ? 0 : height;
+
+ if (!(width == 0 && height == 0))
+ {
+ /* Set the event box's size request... */
+ gtk_widget_set_size_request (widget, width, height);
+ /* ...and the label's size request. */
+ gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (widget)),
+ width, height);
+
+ if (widget->parent != NULL)
+ gtk_fixed_move (GTK_FIXED (widget->parent), widget, x, y);
+ }
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c
new file mode 100644
index 00000000000..d513176bed1
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c
@@ -0,0 +1,539 @@
+/* GtkListPeer.c -- implements GtkListPeer's native methods
+ Copyright (C) 1998, 1999, 2003, 2004 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkListPeer.h"
+
+static jmethodID postListItemEventID;
+
+void
+cp_gtk_list_init_jni (void)
+{
+ jclass gtklistpeer;
+
+ gtklistpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GtkListPeer");
+
+ postListItemEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtklistpeer,
+ "postItemEvent",
+ "(II)V");
+}
+
+enum
+ {
+ COLUMN_STRING,
+ N_COLUMNS
+ };
+
+static gboolean item_highlighted_cb (GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gboolean path_currently_selected,
+ jobject peer);
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_create
+ (JNIEnv *env, jobject obj, jint rows)
+{
+ GtkWidget *sw;
+ GtkWidget *list;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ GtkListStore *list_store;
+ GtkTreeIter iter;
+ GtkRequisition req;
+ gint i;
+
+ gdk_threads_enter ();
+
+ /* Create global reference and save it for future use */
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
+ /* Add the number of rows so that we can calculate the tree view's
+ size request. */
+ for (i = 0; i < rows; i++)
+ {
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter,
+ COLUMN_STRING, "",
+ -1);
+ }
+ list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (NULL,
+ renderer,
+ "text",
+ COLUMN_STRING,
+ NULL);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
+
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
+
+ gtk_widget_size_request (GTK_WIDGET (list), &req);
+
+ gtk_widget_set_size_request (GTK_WIDGET (list), req.width, req.height);
+
+ gtk_container_add (GTK_CONTAINER (sw), list);
+
+ /* Remove the blank rows. */
+ gtk_list_store_clear (list_store);
+
+ gtk_widget_show (list);
+ gtk_widget_show (sw);
+
+ NSA_SET_PTR (env, obj, sw);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jobject *gref;
+ GtkWidget *list;
+ GtkTreeSelection *selection;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
+ gtk_tree_selection_set_select_function (selection, item_highlighted_cb,
+ *gref, NULL);
+
+ cp_gtk_component_connect_signals (G_OBJECT (list), gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetModifyFont
+ (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+ const char *font_name;
+ void *ptr;
+ GtkWidget *list;
+ PangoFontDescription *font_desc;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+
+ font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+ font_desc = pango_font_description_from_string (font_name);
+ pango_font_description_set_size (font_desc,
+ size * cp_gtk_dpi_conversion_factor);
+
+ if (style & AWT_STYLE_BOLD)
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+ if (style & AWT_STYLE_ITALIC)
+ pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+ gtk_widget_modify_font (GTK_WIDGET (list), font_desc);
+
+ pango_font_description_free (font_desc);
+
+ (*env)->ReleaseStringUTFChars (env, name, font_name);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetRequestFocus
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ GtkWidget *list;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+ gtk_widget_grab_focus (list);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_append
+ (JNIEnv *env, jobject obj, jobjectArray items)
+{
+ void *ptr;
+ GtkWidget *list;
+ GtkTreeIter iter;
+ GtkTreeModel *list_store;
+ jint count;
+ jint i;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ count = (*env)->GetArrayLength (env, items);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+ list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+
+ for (i = 0; i < count; i++)
+ {
+ const char *text;
+ jobject item;
+
+ item = (*env)->GetObjectArrayElement (env, items, i);
+
+ text = (*env)->GetStringUTFChars (env, item, NULL);
+ gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
+ COLUMN_STRING, text,
+ -1);
+ (*env)->ReleaseStringUTFChars (env, item, text);
+ }
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_add
+ (JNIEnv *env, jobject obj, jstring text, jint index)
+{
+ void *ptr;
+ const char *str;
+ GtkWidget *list;
+ GtkTreeIter iter;
+ GtkTreeModel *list_store;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ str = (*env)->GetStringUTFChars (env, text, NULL);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+ list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+
+ if (index == -1)
+ gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
+ else
+ gtk_list_store_insert (GTK_LIST_STORE (list_store), &iter, index);
+
+ gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
+ COLUMN_STRING, str, -1);
+
+ (*env)->ReleaseStringUTFChars (env, text, str);
+
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_delItems
+ (JNIEnv *env, jobject obj, jint start, jint end)
+{
+ void *ptr;
+ GtkWidget *list;
+ GtkTreeIter iter;
+ GtkTreeModel *list_store;
+ jint i;
+ jint num_items;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+ list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+
+ /* Special case: remove all rows. */
+ if (end == -1)
+ gtk_list_store_clear (GTK_LIST_STORE (list_store));
+ else
+ {
+ i = 0;
+ num_items = end - start + 1;
+ gtk_tree_model_iter_nth_child (list_store, &iter, NULL, start);
+ while (i < num_items)
+ {
+ gtk_list_store_remove (GTK_LIST_STORE (list_store), &iter);
+ i++;
+ }
+ }
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_select
+ (JNIEnv *env, jobject obj, jint index)
+{
+ void *ptr;
+ GtkWidget *list;
+ GtkTreePath *path;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+ path = gtk_tree_path_new_from_indices (index, -1);
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, NULL, FALSE);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_deselect
+ (JNIEnv *env, jobject obj, jint index)
+{
+ void *ptr;
+ GtkWidget *list;
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
+ path = gtk_tree_path_new_from_indices (index, -1);
+ gtk_tree_selection_unselect_path (selection, path);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize
+ (JNIEnv *env, jobject obj, jint rows, jint visible_rows, jintArray jdims)
+{
+ void *ptr;
+ jint *dims;
+ GtkRequisition current_req;
+ GtkRequisition natural_req;
+
+ gdk_threads_enter ();
+
+ dims = (*env)->GetIntArrayElements (env, jdims, NULL);
+ dims[0] = dims[1] = 0;
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ /* Save the widget's current size request. */
+ gtk_widget_size_request (GTK_WIDGET (ptr), &current_req);
+
+ /* Get the widget's "natural" size request. */
+ gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
+ gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
+
+ /* Reset the widget's size request. */
+ gtk_widget_set_size_request (GTK_WIDGET (ptr),
+ current_req.width, current_req.height);
+
+ dims[0] = natural_req.width;
+
+ /* Calculate the final height, by comparing the number of rows
+ in the list to the number of rows requested by the caller.
+ FIXME: Is there a GTK method that counts the number of rows
+ in the list? If so, we don't need to bring visible_rows from
+ the Java peer. */
+ if (rows == visible_rows)
+ dims[1] = natural_req.height;
+ else
+ dims[1] = natural_req.height / visible_rows * rows;
+
+ (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
+
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_getSelectedIndexes
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ GtkWidget *list;
+ GtkTreeSelection *selection;
+ jintArray result_array;
+ jint *result_array_iter;
+ GList *current_row;
+ GList *rows;
+ gint *indices;
+ jint count;
+ jint i;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
+ count = gtk_tree_selection_count_selected_rows (selection);
+ if (count > 0)
+ {
+ current_row = rows = gtk_tree_selection_get_selected_rows (selection, NULL);
+
+ gdk_threads_leave ();
+
+ result_array = (*env)->NewIntArray (env, count);
+
+ gdk_threads_enter ();
+
+ result_array_iter = (*env)->GetIntArrayElements (env, result_array, NULL);
+
+ for (i = 0; i < count; i++)
+ {
+ indices = gtk_tree_path_get_indices (current_row->data);
+ result_array_iter[i] = indices ? indices[0] : -1;
+ current_row = g_list_next (current_row);
+ }
+
+ if (rows)
+ {
+ g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (rows);
+ }
+
+ (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
+ }
+ else
+ result_array = NULL;
+
+ gdk_threads_leave ();
+
+ return result_array;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_makeVisible
+ (JNIEnv *env, jobject obj, jint index)
+{
+ void *ptr;
+ GtkWidget *list;
+ GtkTreePath *path;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+ path = gtk_tree_path_new_from_indices (index, -1);
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (list), path,
+ NULL, FALSE, 0.0, 0.0);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkListPeer_setMultipleMode
+ (JNIEnv *env, jobject obj, jboolean mode)
+{
+ void *ptr;
+ GtkWidget *list;
+ GtkTreeSelection *selection;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ list = gtk_bin_get_child (GTK_BIN (ptr));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
+ gtk_tree_selection_set_mode (selection,
+ mode ? GTK_SELECTION_MULTIPLE
+ : GTK_SELECTION_SINGLE);
+
+ gdk_threads_leave ();
+}
+
+static gboolean
+item_highlighted_cb (GtkTreeSelection *selection __attribute__((unused)),
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gboolean path_currently_selected,
+ jobject peer)
+{
+ GtkTreeIter iter;
+ jint row;
+ gint *indices;
+
+ if (gtk_tree_model_get_iter (model, &iter, path))
+ {
+ indices = gtk_tree_path_get_indices (path);
+ row = indices ? indices[0] : -1;
+
+ if (!path_currently_selected)
+ {
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postListItemEventID,
+ row,
+ (jint) AWT_ITEM_SELECTED);
+
+ gdk_threads_enter ();
+ }
+ else
+ {
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postListItemEventID,
+ row,
+ (jint) AWT_ITEM_DESELECTED);
+
+ gdk_threads_enter ();
+ }
+ }
+
+ return TRUE;
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
new file mode 100644
index 00000000000..3e21a04024d
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c
@@ -0,0 +1,118 @@
+/* gtkmenubarpeer.c -- Native implementation of GtkMenuBarPeer
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkMenuBarPeer.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_create
+ (JNIEnv *env, jobject obj)
+{
+ GtkWidget *widget;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ widget = gtk_menu_bar_new ();
+ gtk_widget_show (widget);
+
+ NSA_SET_PTR (env, obj, widget);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_addMenu
+ (JNIEnv *env, jobject obj, jobject menupeer)
+{
+ void *mbar, *menu;
+
+ gdk_threads_enter ();
+
+ mbar = NSA_GET_PTR (env, obj);
+ menu = NSA_GET_PTR (env, menupeer);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (mbar), GTK_WIDGET (menu));
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_nativeSetHelpMenu
+ (JNIEnv *env, jobject obj, jobject menupeer)
+{
+ static void *helpmenu;
+ void *mbar, *menu;
+ GList *list;
+
+ gdk_threads_enter ();
+
+ mbar = NSA_GET_PTR (env, obj);
+ menu = NSA_GET_PTR (env, menupeer);
+
+ if (helpmenu != NULL)
+ {
+ list = gtk_container_children (GTK_CONTAINER (mbar));
+ while (list != NULL && list->data != helpmenu)
+ list = list->next;
+ if (list != NULL && list->data == helpmenu)
+ gtk_container_remove (GTK_CONTAINER (mbar), GTK_WIDGET (list->data));
+ }
+ helpmenu = menu;
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_delMenu
+ (JNIEnv *env, jobject obj, jint index)
+{
+ void *ptr;
+ GList *list;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ list = gtk_container_children (GTK_CONTAINER (ptr));
+ list = g_list_nth (list, index);
+ gtk_container_remove (GTK_CONTAINER (ptr), GTK_WIDGET (list->data));
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c
new file mode 100644
index 00000000000..01b74e46c57
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c
@@ -0,0 +1,56 @@
+/* gtkmenucomponentpeer.c -- Native implementation of GtkMenuComponentPeer
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkMenuComponentPeer.h"
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuComponentPeer_dispose
+ (JNIEnv *env, jobject obj)
+{
+ /* For MenuComponents and its subclasses, the widgets are
+ automatically destroyed by Gtk when the parent MenuBar
+ is removed from the Frame. So we avoid the widget
+ destruction in GtkGenericPeer dispose() by overriding
+ it here. */
+
+ /* However, references to the Java objects still exist in the
+ state tables, so we still have to remove those. */
+
+ NSA_DEL_GLOBAL_REF (env, obj);
+ NSA_DEL_PTR (env, obj);
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
new file mode 100644
index 00000000000..2746f1e4a70
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c
@@ -0,0 +1,193 @@
+/* gtkmenuitempeer.c -- Native implementation of GtkMenuItemPeer
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkMenuItemPeer.h"
+#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
+
+static jmethodID postMenuActionEventID;
+
+void
+cp_gtk_menuitem_init_jni (void)
+{
+ jclass gtkmenuitempeer;
+
+ gtkmenuitempeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GtkMenuItemPeer");
+
+ postMenuActionEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(),
+ gtkmenuitempeer,
+ "postMenuActionEvent",
+ "()V");
+}
+
+static void item_activate_cb (GtkMenuItem *item __attribute__((unused)),
+ jobject peer_obj);
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_create
+ (JNIEnv *env, jobject obj, jstring label)
+{
+ GtkWidget *widget;
+ const char *str;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ str = (*env)->GetStringUTFChars (env, label, NULL);
+
+ /* "-" signals that we need a separator. */
+ if (strcmp (str, "-") == 0)
+ widget = gtk_menu_item_new ();
+ else
+ widget = gtk_menu_item_new_with_label (str);
+
+ gtk_widget_show (widget);
+
+ (*env)->ReleaseStringUTFChars (env, label, str);
+
+ NSA_SET_PTR (env, obj, widget);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jobject *gref;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ g_signal_connect (G_OBJECT (ptr), "activate",
+ G_CALLBACK (item_activate_cb), *gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_gtkWidgetModifyFont
+ (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+ const char *font_name;
+ void *ptr;
+ GtkWidget *label;
+ PangoFontDescription *font_desc;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+ label = gtk_bin_get_child (GTK_BIN (ptr));
+
+ if (label)
+ {
+ font_desc = pango_font_description_from_string (font_name);
+ pango_font_description_set_size (font_desc,
+ size * cp_gtk_dpi_conversion_factor);
+
+ if (style & AWT_STYLE_BOLD)
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+ if (style & AWT_STYLE_ITALIC)
+ pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+ gtk_widget_modify_font (GTK_WIDGET(label), font_desc);
+
+ pango_font_description_free (font_desc);
+ }
+
+ (*env)->ReleaseStringUTFChars (env, name, font_name);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_setEnabled
+ (JNIEnv *env, jobject obj, jboolean enabled)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (ptr), enabled);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_setLabel
+ (JNIEnv *env, jobject obj, jstring label)
+{
+ void *ptr;
+ const char *str;
+ GtkAccelLabel *accel_label;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ str = (*env)->GetStringUTFChars (env, label, NULL);
+
+ accel_label = GTK_ACCEL_LABEL (GTK_BIN (ptr)->child);
+
+ gtk_label_set_text (GTK_LABEL (accel_label), str);
+ gtk_accel_label_refetch (accel_label);
+
+ (*env)->ReleaseStringUTFChars (env, label, str);
+
+ gdk_threads_leave ();
+}
+
+static void
+item_activate_cb (GtkMenuItem *item __attribute__((unused)), jobject peer_obj)
+{
+ gdk_threads_leave ();
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer_obj,
+ postMenuActionEventID);
+ gdk_threads_enter ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c
new file mode 100644
index 00000000000..16018f001e4
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c
@@ -0,0 +1,173 @@
+/* gtkmenupeer.c -- Native implementation of GtkMenuPeer
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkMenuPeer.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuPeer_setupAccelGroup
+ (JNIEnv *env, jobject obj, jobject parent)
+{
+ void *ptr1, *ptr2;
+
+ gdk_threads_enter ();
+
+ ptr1 = NSA_GET_PTR (env, obj);
+
+ if (!parent)
+ {
+ gtk_menu_set_accel_group (GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu),
+ gtk_accel_group_new ());
+ }
+ else
+ {
+ GtkAccelGroup *parent_accel;
+
+ ptr2 = NSA_GET_PTR (env, parent);
+ parent_accel = gtk_menu_get_accel_group (GTK_MENU (GTK_MENU_ITEM (ptr2)->submenu));
+
+ gtk_menu_set_accel_group (GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu),
+ parent_accel);
+ }
+
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuPeer_create
+ (JNIEnv *env, jobject obj, jstring label)
+{
+ GtkWidget *menu_title, *menu, *toplevel;
+ const char *str;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ str = (*env)->GetStringUTFChars (env, label, NULL);
+
+ menu = gtk_menu_new ();
+
+ if (str != NULL)
+ menu_title = gtk_menu_item_new_with_label (str);
+ else
+ menu_title = gtk_menu_item_new();
+
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_title), menu);
+
+ /* Allow this menu to grab the pointer. */
+ toplevel = gtk_widget_get_toplevel (menu);
+ if (GTK_IS_WINDOW (toplevel))
+ {
+ gtk_window_group_add_window (cp_gtk_global_window_group,
+ GTK_WINDOW(toplevel));
+ }
+
+ gtk_widget_show (menu_title);
+
+ NSA_SET_PTR (env, obj, menu_title);
+
+ (*env)->ReleaseStringUTFChars (env, label, str);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuPeer_addTearOff
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr1;
+ GtkWidget *menu, *item;
+
+ gdk_threads_enter ();
+
+ ptr1 = NSA_GET_PTR (env, obj);
+
+ menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (ptr1));
+ item = gtk_tearoff_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuPeer_addItem
+ (JNIEnv *env, jobject obj, jobject menuitempeer, jint key, jboolean shift)
+{
+ void *ptr1, *ptr2;
+ GtkWidget *menu;
+
+ gdk_threads_enter ();
+
+ ptr1 = NSA_GET_PTR (env, obj);
+ ptr2 = NSA_GET_PTR (env, menuitempeer);
+
+ menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(ptr1));
+ gtk_menu_shell_append (GTK_MENU_SHELL(menu), GTK_WIDGET (ptr2));
+
+ if (key)
+ {
+ gtk_widget_add_accelerator (GTK_WIDGET (ptr2), "activate",
+ gtk_menu_get_accel_group (GTK_MENU (menu)), key,
+ (GDK_CONTROL_MASK
+ | ((shift) ? GDK_SHIFT_MASK : 0)),
+ GTK_ACCEL_VISIBLE);
+ }
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkMenuPeer_delItem
+ (JNIEnv *env, jobject obj, jint index)
+{
+ void *ptr;
+ GList *list;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ list = gtk_container_children (GTK_CONTAINER (ptr));
+ list = g_list_nth (list, index);
+ gtk_container_remove (GTK_CONTAINER (ptr), GTK_WIDGET (list->data));
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c
new file mode 100644
index 00000000000..8a130e1a4b3
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c
@@ -0,0 +1,112 @@
+/* gtkpanelpeer.c -- Native implementation of GtkPanelPeer
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
+#include "gnu_java_awt_peer_gtk_GtkPanelPeer.h"
+
+static gboolean panel_focus_in_cb (GtkWidget * widget,
+ GdkEventFocus *event,
+ jobject peer);
+static gboolean panel_focus_out_cb (GtkWidget * widget,
+ GdkEventFocus *event,
+ jobject peer);
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkPanelPeer_create
+ (JNIEnv *env, jobject obj)
+{
+ GtkWidget *widget;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ widget = gtk_fixed_new ();
+
+ gtk_fixed_set_has_window (GTK_FIXED (widget), TRUE);
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
+
+ NSA_SET_PTR (env, obj, widget);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkPanelPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jobject *gref;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ /* Panel signals. These callbacks prevent expose events being
+ delivered to the panel when it is focused. */
+ g_signal_connect (G_OBJECT (ptr), "focus-in-event",
+ G_CALLBACK (panel_focus_in_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "focus-out-event",
+ G_CALLBACK (panel_focus_out_cb), *gref);
+
+ /* Component signals. Exclude focus signals. */
+ cp_gtk_component_connect_expose_signals (ptr, gref);
+ cp_gtk_component_connect_mouse_signals (ptr, gref);
+
+ gdk_threads_leave ();
+}
+
+static gboolean
+panel_focus_in_cb (GtkWidget * widget __attribute__((unused)),
+ GdkEventFocus *event __attribute__((unused)),
+ jobject peer __attribute__((unused)))
+{
+ return TRUE;
+}
+
+static gboolean
+panel_focus_out_cb (GtkWidget * widget __attribute__((unused)),
+ GdkEventFocus *event __attribute__((unused)),
+ jobject peer __attribute__((unused)))
+{
+ return TRUE;
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c
new file mode 100644
index 00000000000..e684a090f8f
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c
@@ -0,0 +1,105 @@
+/* gtkpopupmenupeer.c -- Native implementation of GtkPopupMenuPeer
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkPopupMenuPeer.h"
+
+struct pos
+{
+ gint x;
+ gint y;
+};
+
+static void
+menu_pos (GtkMenu *menu __attribute__((unused)),
+ gint *x, gint *y,
+ gboolean *push_in,
+ gpointer user_data)
+{
+ struct pos *p = (struct pos *) user_data;
+
+ *x = p->x;
+ *y = p->y;
+ *push_in = TRUE;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkPopupMenuPeer_show
+ (JNIEnv *env, jobject obj, jint x, jint y, jlong time)
+{
+ void *ptr;
+ struct pos *p;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ p = g_malloc (sizeof (struct pos));
+ p->x = x;
+ p->y = y;
+
+ gtk_menu_popup (GTK_MENU (GTK_MENU_ITEM (ptr)->submenu),
+ NULL, NULL, menu_pos, p, 0, time);
+
+ g_free (p);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkPopupMenuPeer_setupAccelGroup
+ (JNIEnv *env, jobject obj, jobject parent)
+{
+ void *ptr1, *ptr2;
+ GtkMenu *menu;
+
+ gdk_threads_enter ();
+
+ ptr1 = NSA_GET_PTR (env, obj);
+ ptr2 = NSA_GET_PTR (env, parent);
+
+ menu = GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu);
+ gtk_menu_set_accel_group (menu, gtk_accel_group_new ());
+ /* FIXME: update this to use GTK-2.4 GtkActions. */
+#if 0
+ _gtk_accel_group_attach (gtk_menu_get_accel_group (menu),
+ G_OBJECT (gtk_widget_get_toplevel (ptr2)));
+#endif
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c
new file mode 100644
index 00000000000..1445cec5577
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c
@@ -0,0 +1,205 @@
+/* gtkscrollpanepeer.c -- Native implementation of GtkScrollPanePeer
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkScrollPanePeer.h"
+
+#define AWT_SCROLLPANE_SCROLLBARS_AS_NEEDED 0
+#define AWT_SCROLLPANE_SCROLLBARS_ALWAYS 1
+#define AWT_SCROLLPANE_SCROLLBARS_NEVER 2
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_create
+ (JNIEnv *env, jobject obj, int width, int height)
+{
+ GtkWidget *sw;
+
+ gdk_threads_enter ();
+
+ /* Create global reference and save it for future use */
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+
+ gtk_widget_set_size_request (sw, width, height);
+
+ NSA_SET_PTR (env, obj, sw);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_setScrollPosition
+ (JNIEnv *env, jobject obj, jint x, jint y)
+{
+ GtkAdjustment *hadj, *vadj;
+ GtkScrolledWindow *sw;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ sw = GTK_SCROLLED_WINDOW (ptr);
+
+ hadj = gtk_scrolled_window_get_hadjustment (sw);
+ vadj = gtk_scrolled_window_get_vadjustment (sw);
+
+ gtk_adjustment_set_value (hadj, x);
+ gtk_adjustment_set_value (vadj, y);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_gtkScrolledWindowSetHScrollIncrement
+ (JNIEnv *env, jobject obj, jint u)
+{
+ GtkAdjustment *hadj;
+ GtkScrolledWindow *sw;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ sw = GTK_SCROLLED_WINDOW(ptr);
+
+ hadj = gtk_scrolled_window_get_hadjustment (sw);
+ hadj->step_increment = u;
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_gtkScrolledWindowSetVScrollIncrement
+ (JNIEnv *env, jobject obj, jint u)
+{
+ GtkAdjustment *vadj;
+ GtkScrolledWindow *sw;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ sw = GTK_SCROLLED_WINDOW(ptr);
+
+ vadj = gtk_scrolled_window_get_hadjustment (sw);
+ vadj->step_increment = u;
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_getHScrollbarHeight
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ GtkScrolledWindow *sw;
+ GtkRequisition requisition;
+ jint height = 0;
+ jint spacing = 0;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ sw = GTK_SCROLLED_WINDOW (ptr);
+
+ gtk_widget_size_request (sw->hscrollbar, &requisition);
+ gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
+ height = requisition.height + spacing;
+
+ gdk_threads_leave ();
+
+ return height;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_getVScrollbarWidth
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ GtkScrolledWindow *sw;
+ GtkRequisition requisition;
+ jint width = 0;
+ jint spacing = 0;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ sw = GTK_SCROLLED_WINDOW (ptr);
+
+ gtk_widget_size_request (sw->vscrollbar, &requisition);
+ gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
+ width = requisition.width + spacing;
+
+ gdk_threads_leave ();
+
+ return width;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_setPolicy
+ (JNIEnv *env, jobject obj, jint policy)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ switch (policy)
+ {
+ case AWT_SCROLLPANE_SCROLLBARS_AS_NEEDED:
+ policy = GTK_POLICY_AUTOMATIC;
+ break;
+ case AWT_SCROLLPANE_SCROLLBARS_ALWAYS:
+ policy = GTK_POLICY_ALWAYS;
+ break;
+ case AWT_SCROLLPANE_SCROLLBARS_NEVER:
+ policy = GTK_POLICY_NEVER;
+ break;
+ }
+
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ptr), policy, policy);
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollbarPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollbarPeer.c
new file mode 100644
index 00000000000..39686271084
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollbarPeer.c
@@ -0,0 +1,258 @@
+/* gtkscrollbarpeer.c -- Native implementation of GtkScrollbarPeer
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include <math.h>
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
+#include "gnu_java_awt_peer_gtk_GtkScrollbarPeer.h"
+
+#define AWT_ADJUSTMENT_UNIT_INCREMENT 1
+#define AWT_ADJUSTMENT_UNIT_DECREMENT 2
+#define AWT_ADJUSTMENT_BLOCK_DECREMENT 3
+#define AWT_ADJUSTMENT_BLOCK_INCREMENT 4
+#define AWT_ADJUSTMENT_TRACK 5
+
+static jmethodID postAdjustmentEventID;
+
+void
+cp_gtk_scrollbar_init_jni (void)
+{
+ jclass gtkscrollbarpeer;
+
+ gtkscrollbarpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GtkScrollbarPeer");
+
+ postAdjustmentEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(),
+ gtkscrollbarpeer,
+ "postAdjustmentEvent",
+ "(II)V");
+}
+
+#if GTK_MINOR_VERSION > 4
+static gboolean slider_moved_cb (GtkRange *range,
+ GtkScrollType scroll,
+ gdouble value,
+ jobject obj);
+#else
+static void post_change_event_cb (GtkRange *range,
+ jobject peer);
+#endif
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_create
+ (JNIEnv *env, jobject obj, jint orientation, jint value,
+ jint min, jint max, jint step_incr, jint page_incr, jint visible_amount)
+{
+ GtkWidget *scrollbar;
+ GtkObject *adj;
+
+ /* Create global reference and save it for future use */
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ gdk_threads_enter ();
+
+ adj = gtk_adjustment_new ((gdouble) value,
+ (gdouble) min,
+ (gdouble) max,
+ (gdouble) step_incr,
+ (gdouble) page_incr,
+ (gdouble) visible_amount);
+
+ scrollbar = orientation
+ ? gtk_vscrollbar_new (GTK_ADJUSTMENT (adj))
+ : gtk_hscrollbar_new (GTK_ADJUSTMENT (adj));
+
+ GTK_RANGE (scrollbar)->round_digits = 0;
+ /* These calls seem redundant but they are not. They clamp values
+ so that the slider's entirety is always between the two
+ steppers. */
+ gtk_range_set_range (GTK_RANGE (scrollbar), (gdouble) min, (gdouble) max);
+ gtk_range_set_value (GTK_RANGE (scrollbar), (gdouble) value);
+
+ gdk_threads_leave ();
+
+ NSA_SET_PTR (env, obj, scrollbar);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_connectSignals
+ (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 ();
+
+ /* Scrollbar signals */
+#if GTK_MINOR_VERSION > 4
+ g_signal_connect (G_OBJECT (ptr), "change-value",
+ G_CALLBACK (slider_moved_cb), *gref);
+#else
+ g_signal_connect (G_OBJECT (ptr), "value-changed",
+ G_CALLBACK (post_change_event_cb), *gref);
+#endif
+
+ /* Component signals */
+ cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setLineIncrement
+ (JNIEnv *env, jobject obj, jint amount)
+{
+ void *ptr;
+ GtkAdjustment *adj;
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gdk_threads_enter ();
+
+ adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
+ adj->step_increment = (gdouble) amount;
+ gtk_adjustment_changed (adj);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setPageIncrement
+ (JNIEnv *env, jobject obj, jint amount)
+{
+ void *ptr;
+ GtkAdjustment *adj;
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gdk_threads_enter ();
+
+ adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
+ adj->page_increment = (gdouble) amount;
+ gtk_adjustment_changed (adj);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setValues
+ (JNIEnv *env, jobject obj, jint value, jint visible, jint min, jint max)
+{
+ void *ptr;
+ GtkAdjustment *adj;
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gdk_threads_enter ();
+
+ adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
+ adj->page_size = (gdouble) visible;
+
+ gtk_range_set_range (GTK_RANGE (ptr), (gdouble) min, (gdouble) max);
+ gtk_range_set_value (GTK_RANGE (ptr), (gdouble) value);
+
+ gdk_threads_leave ();
+}
+
+#if GTK_MINOR_VERSION > 4
+static gboolean
+slider_moved_cb (GtkRange *range,
+ GtkScrollType scroll,
+ gdouble value,
+ jobject obj)
+{
+ GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (range));
+
+ value = CLAMP (value, adj->lower,
+ (adj->upper - adj->page_size));
+
+ if (range->round_digits >= 0)
+ {
+ gdouble power;
+ gint i;
+
+ i = range->round_digits;
+ power = 1;
+ while (i--)
+ power *= 10;
+
+ value = floor ((value * power) + 0.5) / power;
+ }
+
+ switch (scroll)
+ {
+ case GTK_SCROLL_STEP_BACKWARD:
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
+ AWT_ADJUSTMENT_UNIT_DECREMENT,
+ (jint) value);
+ break;
+ case GTK_SCROLL_STEP_FORWARD:
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
+ AWT_ADJUSTMENT_UNIT_INCREMENT,
+ (jint) value);
+ break;
+ case GTK_SCROLL_PAGE_BACKWARD:
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
+ AWT_ADJUSTMENT_BLOCK_DECREMENT,
+ (jint) value);
+ break;
+ case GTK_SCROLL_PAGE_FORWARD:
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
+ AWT_ADJUSTMENT_BLOCK_INCREMENT,
+ (jint) value);
+ break;
+ default:
+ /* GTK_SCROLL_JUMP: */
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
+ AWT_ADJUSTMENT_TRACK,
+ (jint) value);
+ break;
+ }
+ return FALSE;
+}
+#else
+static void
+post_change_event_cb (GtkRange *range, jobject peer)
+{
+ GtkAdjustment *adj;
+ adj = gtk_range_get_adjustment (range);
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer, postAdjustmentEventID,
+ AWT_ADJUSTMENT_TRACK, (jint) adj->value);
+}
+#endif
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
new file mode 100644
index 00000000000..9af88a026ee
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c
@@ -0,0 +1,522 @@
+/* gtktextareapeer.c -- Native implementation of GtkTextAreaPeer
+ Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkTextAreaPeer.h"
+
+#define AWT_TEXTAREA_SCROLLBARS_BOTH 0
+#define AWT_TEXTAREA_SCROLLBARS_VERTICAL_ONLY 1
+#define AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY 2
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_create
+ (JNIEnv *env, jobject obj,
+ jint textview_width, jint textview_height, jint scroll)
+{
+ GtkWidget *text, *sw;
+
+ gdk_threads_enter ();
+
+ /* Create global reference and save it for future use */
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ text = gtk_text_view_new ();
+ gtk_widget_set_size_request (text, textview_width, textview_height);
+ gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (text), TRUE);
+
+ gtk_widget_show (text);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (sw), text);
+
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ /* horizontal scrollbar */
+ (scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
+ || scroll == AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY) ?
+ GTK_POLICY_ALWAYS : GTK_POLICY_NEVER,
+ /* vertical scrollbar */
+ (scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
+ || scroll == AWT_TEXTAREA_SCROLLBARS_VERTICAL_ONLY) ?
+ GTK_POLICY_ALWAYS : GTK_POLICY_NEVER);
+
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text),
+ (scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
+ || scroll == AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY)
+ ? GTK_WRAP_NONE : GTK_WRAP_WORD);
+
+ NSA_SET_PTR (env, obj, sw);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ GtkWidget *text = NULL;
+ GtkTextBuffer *buf;
+ void *ptr;
+ jobject *gref;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ /* Unwrap the text view from the scrolled window */
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+
+ /* TextComponent signals */
+ cp_gtk_textcomponent_connect_signals (G_OBJECT (buf), gref);
+
+ /* Component signals */
+ cp_gtk_component_connect_signals (G_OBJECT (text), gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_insert
+ (JNIEnv *env, jobject obj, jstring contents, jint position)
+{
+ GtkTextBuffer *buf;
+ GtkTextIter iter;
+ GtkWidget *text;
+ void *ptr;
+ const char *str;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ str = (*env)->GetStringUTFChars (env, contents, NULL);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+ gtk_text_buffer_get_iter_at_offset (buf, &iter, position);
+ gtk_text_buffer_insert (buf, &iter, str, strlen (str));
+
+ (*env)->ReleaseStringUTFChars (env, contents, str);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_replaceRange
+ (JNIEnv *env, jobject obj, jstring contents, jint start, jint end)
+{
+ GtkWidget *text;
+ GtkTextBuffer *buf;
+ GtkTextIter iter, startIter, endIter;
+ void *ptr;
+ const char *str;
+ int mystart = start;
+ int myend = end;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ str = (*env)->GetStringUTFChars (env, contents, NULL);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+
+ gtk_text_buffer_get_iter_at_offset (buf, &startIter, mystart);
+ gtk_text_buffer_get_iter_at_offset (buf, &endIter, myend);
+ gtk_text_buffer_delete (buf, &startIter, &endIter);
+
+ gtk_text_buffer_get_iter_at_offset (buf, &iter, mystart);
+ gtk_text_buffer_insert(buf, &iter, str, strlen (str));
+
+ (*env)->ReleaseStringUTFChars (env, contents, str);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetModifyFont
+ (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+ const char *font_name;
+ void *ptr;
+ GtkWidget *text;
+ PangoFontDescription *font_desc;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+ font_desc = pango_font_description_from_string (font_name);
+ pango_font_description_set_size (font_desc,
+ size * cp_gtk_dpi_conversion_factor);
+
+ if (style & AWT_STYLE_BOLD)
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+ if (style & AWT_STYLE_ITALIC)
+ pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+ gtk_widget_modify_font (GTK_WIDGET (text), font_desc);
+
+ pango_font_description_free (font_desc);
+
+ (*env)->ReleaseStringUTFChars (env, name, font_name);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetRequestFocus
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ GtkWidget *text;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ gtk_widget_grab_focus (text);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getHScrollbarHeight
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ GtkScrolledWindow *sw;
+ GtkRequisition requisition;
+ jint height = 0;
+ jint spacing = 0;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ sw = GTK_SCROLLED_WINDOW (ptr);
+
+ if (sw)
+ {
+ gtk_widget_size_request (sw->hscrollbar, &requisition);
+ gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
+ height = requisition.height + spacing;
+ }
+
+ gdk_threads_leave ();
+
+ return height;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getVScrollbarWidth
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ GtkScrolledWindow *sw;
+ GtkRequisition requisition;
+ jint width = 0;
+ jint spacing = 0;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ sw = GTK_SCROLLED_WINDOW (ptr);
+
+ if (sw)
+ {
+ gtk_widget_size_request (sw->vscrollbar, &requisition);
+ gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
+ width = requisition.width + spacing;
+ }
+
+ gdk_threads_leave ();
+
+ return width;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getCaretPosition
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ int pos = 0;
+ GtkWidget *text = NULL;
+ GtkTextBuffer *buf;
+ GtkTextMark *mark;
+ GtkTextIter iter;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+ mark = gtk_text_buffer_get_insert (buf);
+ gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
+ pos = gtk_text_iter_get_offset (&iter);
+
+ gdk_threads_leave ();
+
+ return pos;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setCaretPosition
+ (JNIEnv *env, jobject obj, jint pos)
+{
+ void *ptr;
+ GtkWidget *text = NULL;
+ GtkTextBuffer *buf;
+ GtkTextIter iter;
+ GtkTextMark *oldmark;
+ GtkTextIter olditer;
+ int oldpos;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+
+ /* Save old position. */
+ oldmark = gtk_text_buffer_get_insert (buf);
+ gtk_text_buffer_get_iter_at_mark (buf, &olditer, oldmark);
+ oldpos = gtk_text_iter_get_offset (&olditer);
+
+ /* Move to new position. */
+ gtk_text_buffer_get_iter_at_offset (buf, &iter, pos);
+ gtk_text_buffer_place_cursor (buf, &iter);
+
+ /* Scroll to new position. Alignment is determined
+ comparing the new position to the old position. */
+ if (oldpos > pos)
+ gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
+ &iter, 0, TRUE, 0, 0);
+ else if (oldpos < pos)
+ gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
+ &iter, 0, TRUE, 1, 1);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionStart
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ int pos = 0;
+ GtkWidget *text = NULL;
+ GtkTextBuffer *buf;
+ GtkTextIter start;
+ GtkTextIter end;
+ GtkTextMark *mark;
+ GtkTextIter iter;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+
+ if (gtk_text_buffer_get_selection_bounds (buf, &start, &end))
+ {
+ pos = gtk_text_iter_get_offset (&start);
+ }
+ else
+ {
+ mark = gtk_text_buffer_get_insert (buf);
+ gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
+ pos = gtk_text_iter_get_offset (&iter);
+ }
+
+ gdk_threads_leave ();
+
+ return pos;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionEnd
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ int pos = 0;
+ GtkWidget *text = NULL;
+ GtkTextBuffer *buf;
+ GtkTextIter start;
+ GtkTextIter end;
+ GtkTextMark *mark;
+ GtkTextIter iter;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+
+ if (gtk_text_buffer_get_selection_bounds (buf, &start, &end))
+ {
+ pos = gtk_text_iter_get_offset (&end);
+ }
+ else
+ {
+ mark = gtk_text_buffer_get_insert (buf);
+ gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
+ pos = gtk_text_iter_get_offset (&iter);
+ }
+
+ gdk_threads_leave ();
+
+ return pos;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_select
+ (JNIEnv *env, jobject obj, jint start, jint end)
+{
+ void *ptr;
+ GtkWidget *text = NULL;
+ GtkTextBuffer *buf;
+ GtkTextIter iter;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+ gtk_text_buffer_get_iter_at_offset (buf, &iter, start);
+ /* quickly move both 'insert' and 'selection_bound' to the
+ same position */
+ gtk_text_buffer_place_cursor (buf, &iter);
+ gtk_text_buffer_get_iter_at_offset (buf, &iter, end);
+ gtk_text_buffer_move_mark_by_name (buf, "selection_bound", &iter);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setEditable
+ (JNIEnv *env, jobject obj, jboolean state)
+{
+ void *ptr;
+ GtkWidget *text = NULL;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (text), state);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getText
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ char *contents = NULL;
+ jstring jcontents;
+ GtkWidget *text = NULL;
+ GtkTextBuffer *buf;
+ GtkTextIter start, end;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+ gtk_text_buffer_get_start_iter (buf, &start);
+ gtk_text_buffer_get_end_iter (buf, &end);
+ contents = gtk_text_buffer_get_text (buf, &start, &end, FALSE);
+
+ jcontents = (*env)->NewStringUTF (env, contents);
+ g_free (contents);
+
+ gdk_threads_leave ();
+
+ return jcontents;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setText
+ (JNIEnv *env, jobject obj, jstring contents)
+{
+ void *ptr;
+ const char *str;
+ GtkWidget *text = NULL;
+ GtkTextBuffer *buf;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ str = (*env)->GetStringUTFChars (env, contents, NULL);
+
+ text = gtk_bin_get_child (GTK_BIN (ptr));
+
+ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
+ gtk_text_buffer_set_text (buf, str, strlen (str));
+
+ (*env)->ReleaseStringUTFChars (env, contents, str);
+
+ gdk_threads_leave ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
new file mode 100644
index 00000000000..eb658339dab
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
@@ -0,0 +1,423 @@
+/* gtktextfieldpeer.c -- Native implementation of GtkTextFieldPeer
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkTextFieldPeer.h"
+
+/* the color used for highlighting when the foreground is black,
+ since black highlights aren't a Good Idea. */
+#define BB_RED 16962
+#define BB_GREEN 26985
+#define BB_BLUE 31611
+
+static jmethodID postTextEventID;
+
+void
+cp_gtk_textcomponent_init_jni (void)
+{
+ jclass gtkcomponentpeer;
+
+ gtkcomponentpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GtkComponentPeer");
+
+ postTextEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkcomponentpeer,
+ "postTextEvent",
+ "()V");
+}
+
+static void textcomponent_changed_cb (GtkEditable *editable, jobject peer);
+
+static jint get_border_width (GtkWidget *entry);
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_create
+ (JNIEnv *env, jobject obj, jint text_width)
+{
+ GtkWidget *entry;
+
+ gdk_threads_enter ();
+
+ /* Create global reference and save it for future use */
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ entry = gtk_entry_new ();
+ gtk_widget_set_size_request (entry,
+ text_width + 2 * get_border_width (entry), -1);
+
+ NSA_SET_PTR (env, obj, entry);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jobject *gref;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ /* TextComponent signals */
+ cp_gtk_textcomponent_connect_signals (G_OBJECT (ptr), gref);
+
+ /* Component signals */
+ cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkWidgetSetBackground
+ (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
+{
+ GdkColor color;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ color.red = (red / 255.0) * 65535;
+ color.green = (green / 255.0) * 65535;
+ color.blue = (blue / 255.0) * 65535;
+
+ gtk_widget_modify_base (GTK_WIDGET (ptr), GTK_STATE_NORMAL, &color);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkWidgetSetForeground
+ (JNIEnv *env, jobject obj, jint red, jint green, jint blue)
+{
+ GdkColor color;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ color.red = (red / 255.0) * 65535;
+ color.green = (green / 255.0) * 65535;
+ color.blue = (blue / 255.0) * 65535;
+
+ gtk_widget_modify_text (GTK_WIDGET (ptr), GTK_STATE_NORMAL, &color);
+
+ if ( red == 0 && green == 0 && blue == 0)
+ {
+ color.red = BB_RED;
+ color.green = BB_GREEN;
+ color.blue = BB_BLUE;
+ }
+ gtk_widget_modify_base (GTK_WIDGET (ptr), GTK_STATE_SELECTED, &color);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkEntryGetBorderWidth
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ int border_width = 0;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ border_width = get_border_width (GTK_WIDGET (ptr));
+
+ gdk_threads_leave ();
+
+ return border_width;
+}
+
+/* GTK hard-codes this value. It is the space between a GtkEntry's
+ frame and its text. */
+#define INNER_BORDER 2
+
+static jint
+get_border_width (GtkWidget *entry)
+{
+ gint focus_width;
+ gboolean interior_focus;
+ int x_border_width = INNER_BORDER;
+
+ gtk_widget_style_get (entry,
+ "interior-focus", &interior_focus,
+ "focus-line-width", &focus_width,
+ NULL);
+
+ if (GTK_ENTRY (entry)->has_frame)
+ x_border_width += entry->style->xthickness;
+
+ if (!interior_focus)
+ x_border_width += focus_width;
+
+ return x_border_width;
+}
+
+#undef INNER_BORDER
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setEchoChar
+ (JNIEnv *env, jobject obj, jchar c)
+{
+ void *ptr;
+ GtkEntry *entry;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ entry = GTK_ENTRY (ptr);
+
+ if (c != 0)
+ {
+ /* FIXME: use gtk_entry_set_invisible_char (GtkEntry *entry,
+ gunichar ch) here. That means we must convert from jchar
+ (utf16) to gunichar (ucs4). */
+ gtk_entry_set_visibility (entry, FALSE);
+ }
+ else
+ gtk_entry_set_visibility (entry, TRUE);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkWidgetModifyFont
+ (JNIEnv *env, jobject obj, jstring name, jint style, jint size)
+{
+ const char *font_name;
+ void *ptr;
+ PangoFontDescription *font_desc;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ font_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+ font_desc = pango_font_description_from_string (font_name);
+ pango_font_description_set_size (font_desc,
+ size * cp_gtk_dpi_conversion_factor);
+
+ if (style & AWT_STYLE_BOLD)
+ pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+
+ if (style & AWT_STYLE_ITALIC)
+ pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
+
+ gtk_widget_modify_font (GTK_WIDGET (ptr), font_desc);
+
+ pango_font_description_free (font_desc);
+
+ (*env)->ReleaseStringUTFChars (env, name, font_name);
+
+ gdk_threads_leave();
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getCaretPosition
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ int pos = 0;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ pos = gtk_editable_get_position (GTK_EDITABLE (ptr));
+
+ gdk_threads_leave ();
+
+ return pos;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setCaretPosition
+ (JNIEnv *env, jobject obj, jint pos)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_editable_set_position (GTK_EDITABLE (ptr), pos);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getSelectionStart
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ int pos = 0;
+ int starti, endi;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ if (gtk_editable_get_selection_bounds (GTK_EDITABLE (ptr), &starti, &endi))
+ pos = starti;
+ else
+ pos = gtk_editable_get_position (GTK_EDITABLE (ptr));
+
+ gdk_threads_leave ();
+
+ return pos;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getSelectionEnd
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ int pos = 0;
+ int starti, endi;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ if (gtk_editable_get_selection_bounds (GTK_EDITABLE (ptr), &starti, &endi))
+ pos = endi;
+ else
+ pos = gtk_editable_get_position (GTK_EDITABLE (ptr));
+
+ gdk_threads_leave ();
+
+ return pos;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_select
+ (JNIEnv *env, jobject obj, jint start, jint end)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_editable_select_region (GTK_EDITABLE (ptr), start, end);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setEditable
+ (JNIEnv *env, jobject obj, jboolean state)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_editable_set_editable (GTK_EDITABLE (ptr), state);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getText
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ char *contents = NULL;
+ jstring jcontents;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ contents = gtk_editable_get_chars (GTK_EDITABLE (ptr), 0, -1);
+
+ jcontents = (*env)->NewStringUTF (env, contents);
+
+ g_free (contents);
+
+ gdk_threads_leave ();
+
+ return jcontents;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setText
+ (JNIEnv *env, jobject obj, jstring contents)
+{
+ void *ptr;
+ const char *str;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ str = (*env)->GetStringUTFChars (env, contents, NULL);
+
+ gtk_entry_set_text (GTK_ENTRY (ptr), str);
+
+ (*env)->ReleaseStringUTFChars (env, contents, str);
+
+ gdk_threads_leave ();
+}
+
+void
+cp_gtk_textcomponent_connect_signals (GObject *ptr, jobject *gref)
+{
+ g_signal_connect (G_OBJECT(ptr), "changed",
+ G_CALLBACK (textcomponent_changed_cb), *gref);
+}
+
+static void
+textcomponent_changed_cb (GtkEditable *editable __attribute__((unused)),
+ jobject peer)
+{
+ gdk_threads_leave ();
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer, postTextEventID);
+ gdk_threads_enter ();
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
new file mode 100644
index 00000000000..a8e1957ee20
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
@@ -0,0 +1,524 @@
+/* gtktoolkit.c -- Native portion of GtkToolkit
+ Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include "gtkpeer.h"
+#include "gnu_java_awt_peer_gtk_GtkToolkit.h"
+#include "gthread-jni.h"
+#include "jcl.h"
+
+#include <sys/time.h>
+
+#define RC_FILE ".classpath-gtkrc"
+
+/* From java.awt.SystemColor */
+#define AWT_DESKTOP 0
+#define AWT_ACTIVE_CAPTION 1
+#define AWT_ACTIVE_CAPTION_TEXT 2
+#define AWT_ACTIVE_CAPTION_BORDER 3
+#define AWT_INACTIVE_CAPTION 4
+#define AWT_INACTIVE_CAPTION_TEXT 5
+#define AWT_INACTIVE_CAPTION_BORDER 6
+#define AWT_WINDOW 7
+#define AWT_WINDOW_BORDER 8
+#define AWT_WINDOW_TEXT 9
+#define AWT_MENU 10
+#define AWT_MENU_TEXT 11
+#define AWT_TEXT 12
+#define AWT_TEXT_TEXT 13
+#define AWT_TEXT_HIGHLIGHT 14
+#define AWT_TEXT_HIGHLIGHT_TEXT 15
+#define AWT_TEXT_INACTIVE_TEXT 16
+#define AWT_CONTROL 17
+#define AWT_CONTROL_TEXT 18
+#define AWT_CONTROL_HIGHLIGHT 19
+#define AWT_CONTROL_LT_HIGHLIGHT 20
+#define AWT_CONTROL_SHADOW 21
+#define AWT_CONTROL_DK_SHADOW 22
+#define AWT_SCROLLBAR 23
+#define AWT_INFO 24
+#define AWT_INFO_TEXT 25
+#define AWT_NUM_COLORS 26
+
+struct state_table *cp_gtk_native_state_table;
+struct state_table *cp_gtk_native_global_ref_table;
+
+static jclass gtkgenericpeer;
+static JavaVM *java_vm;
+static jmethodID printCurrentThreadID;
+
+union env_union
+{
+ void *void_env;
+ JNIEnv *jni_env;
+};
+
+JNIEnv *
+cp_gtk_gdk_env()
+{
+ union env_union tmp;
+ g_assert((*java_vm)->GetEnv(java_vm, &tmp.void_env, JNI_VERSION_1_2) == JNI_OK);
+ return tmp.jni_env;
+}
+
+
+GtkWindowGroup *cp_gtk_global_window_group;
+double cp_gtk_dpi_conversion_factor;
+
+static void init_glib_threads(JNIEnv *, jint);
+
+static void init_dpi_conversion_factor (void);
+static void dpi_changed_cb (GtkSettings *settings,
+ GParamSpec *pspec);
+
+#if GTK_MINOR_VERSION > 4
+static GLogFunc old_glog_func;
+static void glog_func (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data);
+#endif
+
+/*
+ * Call gtk_init. It is very important that this happen before any other
+ * gtk calls.
+ *
+ * The portableNativeSync argument may have the values:
+ * 1 if the Java property gnu.classpath.awt.gtk.portable.native.sync
+ * is set to "true".
+ * 0 if it is set to "false"
+ * -1 if unset.
+ */
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkInit (JNIEnv *env,
+ jclass clazz __attribute__((unused)),
+ jint portableNativeSync)
+{
+ int argc = 1;
+ char **argv;
+ char *homedir, *rcpath = NULL;
+
+ gtkgenericpeer = (*env)->FindClass(env, "gnu/java/awt/peer/gtk/GtkGenericPeer");
+
+ printCurrentThreadID = (*env)->GetStaticMethodID (env, gtkgenericpeer,
+ "printCurrentThread", "()V");
+
+ NSA_INIT (env, gtkgenericpeer);
+
+ g_assert((*env)->GetJavaVM(env, &java_vm) == 0);
+
+ /* GTK requires a program's argc and argv variables, and requires that they
+ be valid. Set it up. */
+ argv = (char **) g_malloc (sizeof (char *) * 2);
+ argv[0] = (char *) g_malloc(1);
+ argv[0][0] = '\0';
+ argv[1] = NULL;
+
+ init_glib_threads(env, portableNativeSync);
+
+ /* From GDK 2.0 onwards we have to explicitly call gdk_threads_init */
+ gdk_threads_init();
+
+ gtk_init (&argc, &argv);
+
+ gdk_rgb_init ();
+ gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
+ gtk_widget_set_default_visual (gdk_rgb_get_visual ());
+
+ /* Make sure queued calls don't get sent to GTK/GDK while
+ we're shutting down. */
+ atexit (gdk_threads_enter);
+
+ if ((homedir = getenv ("HOME")))
+ {
+ rcpath = (char *) g_malloc (strlen (homedir) + strlen (RC_FILE) + 2);
+ sprintf (rcpath, "%s/%s", homedir, RC_FILE);
+ }
+
+ gtk_rc_parse ((rcpath) ? rcpath : RC_FILE);
+
+ g_free (rcpath);
+ g_free (argv[0]);
+ g_free (argv);
+
+ /* On errors or warning print a whole stacktrace. */
+#if GTK_MINOR_VERSION > 4
+ old_glog_func = g_log_set_default_handler (&glog_func, NULL);
+#endif
+
+#if GTK_CAIRO
+ cp_gtk_graphics2d_init_jni ();
+#endif
+ cp_gtk_graphics_init_jni ();
+ cp_gtk_button_init_jni ();
+ cp_gtk_checkbox_init_jni ();
+ cp_gtk_choice_init_jni ();
+ cp_gtk_component_init_jni ();
+ cp_gtk_list_init_jni ();
+ cp_gtk_menuitem_init_jni ();
+ cp_gtk_scrollbar_init_jni ();
+ cp_gtk_textcomponent_init_jni ();
+ cp_gtk_window_init_jni ();
+
+ cp_gtk_global_window_group = gtk_window_group_new ();
+
+ init_dpi_conversion_factor ();
+}
+
+
+/** Initialize GLIB's threads properly, based on the value of the
+ gnu.classpath.awt.gtk.portable.native.sync Java system property. If
+ that's unset, use the PORTABLE_NATIVE_SYNC config.h macro. (TODO:
+ In some release following 0.10, that config.h macro will go away.)
+ */
+static void
+init_glib_threads(JNIEnv *env, jint portableNativeSync)
+{
+ if (portableNativeSync < 0)
+ {
+#ifdef PORTABLE_NATIVE_SYNC /* Default value, if not set by the Java system
+ property */
+ portableNativeSync = 1;
+#else
+ portableNativeSync = 0;
+#endif
+ }
+
+ (*env)->GetJavaVM( env, &cp_gtk_the_vm );
+ if (!g_thread_supported ())
+ {
+ if (portableNativeSync)
+ g_thread_init ( &cp_gtk_portable_native_sync_jni_functions );
+ else
+ g_thread_init ( NULL );
+ }
+ else
+ {
+ /* Warn if portable native sync is desired but the threading
+ system is already initialized. In that case we can't
+ override the threading implementation with our portable
+ native sync functions. */
+ if (portableNativeSync)
+ g_printerr ("peer warning: portable native sync disabled.\n");
+ }
+
+ /* Debugging progress message; uncomment if needed: */
+ /* printf("called gthread init\n"); */
+}
+
+void
+cp_gtk_print_current_thread (void)
+{
+ (*cp_gtk_gdk_env())->CallStaticVoidMethod (cp_gtk_gdk_env(), gtkgenericpeer, printCurrentThreadID);
+}
+
+/* This is a big hack, needed until this pango bug is resolved:
+ http://bugzilla.gnome.org/show_bug.cgi?id=119081.
+ See: http://mail.gnome.org/archives/gtk-i18n-list/2003-August/msg00001.html
+ for details. */
+static void
+init_dpi_conversion_factor ()
+{
+ GtkSettings *settings = gtk_settings_get_default ();
+ GObjectClass *klass;
+
+ klass = G_OBJECT_CLASS (GTK_SETTINGS_GET_CLASS (settings));
+ if (g_object_class_find_property (klass, "gtk-xft-dpi"))
+ {
+ int int_dpi;
+ g_object_get (settings, "gtk-xft-dpi", &int_dpi, NULL);
+ /* If int_dpi == -1 gtk-xft-dpi returns the default value. So we
+ have to do approximate calculation here. */
+ if (int_dpi < 0)
+ cp_gtk_dpi_conversion_factor = PANGO_SCALE * 72.0 / 96.;
+ else
+ cp_gtk_dpi_conversion_factor =
+ PANGO_SCALE * 72.0 / (int_dpi / PANGO_SCALE);
+
+ g_signal_connect (settings, "notify::gtk-xft-dpi",
+ G_CALLBACK (dpi_changed_cb), NULL);
+ }
+ else
+ /* Approximate. */
+ cp_gtk_dpi_conversion_factor = PANGO_SCALE * 72.0 / 96.;
+}
+
+static void
+dpi_changed_cb (GtkSettings *settings,
+ GParamSpec *pspec __attribute__((unused)))
+{
+ int int_dpi;
+ g_object_get (settings, "gtk-xft-dpi", &int_dpi, NULL);
+ if (int_dpi < 0)
+ cp_gtk_dpi_conversion_factor = PANGO_SCALE * 72.0 / 96.;
+ else
+ cp_gtk_dpi_conversion_factor =
+ PANGO_SCALE * 72.0 / (int_dpi / PANGO_SCALE);
+}
+
+static int
+within_human_latency_tolerance(struct timeval *init)
+{
+ struct timeval curr;
+ unsigned long milliseconds_elapsed;
+
+ gettimeofday(&curr, NULL);
+
+ milliseconds_elapsed = (((curr.tv_sec * 1000) + (curr.tv_usec / 1000))
+ - ((init->tv_sec * 1000) + (init->tv_usec / 1000)));
+
+ return milliseconds_elapsed < 100;
+}
+
+#if GTK_MINOR_VERSION > 4
+static void
+glog_func (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ old_glog_func (log_domain, log_level, message, user_data);
+ if (log_level & (G_LOG_LEVEL_ERROR
+ | G_LOG_LEVEL_CRITICAL
+ | G_LOG_LEVEL_WARNING))
+ {
+ JNIEnv *env = cp_gtk_gdk_env ();
+ jthrowable *exc = (*env)->ExceptionOccurred(env);
+ gchar *detail = g_strconcat (log_domain, ": ", message, NULL);
+ JCL_ThrowException (env, "java/lang/InternalError", detail);
+ g_free (detail);
+ (*env)->ExceptionDescribe (env);
+ if (exc != NULL)
+ (*env)->Throw (env, exc);
+ else
+ (*env)->ExceptionClear (env);
+ }
+}
+#endif
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_iterateNativeQueue
+(JNIEnv *env,
+ jobject self __attribute__((unused)),
+ jobject lockedQueue,
+ jboolean block)
+{
+ /* We're holding an EventQueue lock, and we're about to acquire the GDK
+ * lock before dropping the EventQueue lock. This can deadlock if someone
+ * holds the GDK lock and wants to acquire the EventQueue lock; however
+ * all callbacks from GTK happen with the GDK lock released, so this
+ * would only happen in an odd case such as some JNI helper code
+ * acquiring the GDK lock and calling back into
+ * EventQueue.getNextEvent().
+ */
+
+ struct timeval init;
+ gettimeofday(&init, NULL);
+
+ gdk_threads_enter ();
+ (*env)->MonitorExit (env, lockedQueue);
+
+ if (block)
+ {
+
+ /* If we're blocking-when-empty, we want a do .. while loop. */
+ do
+ gtk_main_iteration ();
+ while (within_human_latency_tolerance (&init)
+ && gtk_events_pending ());
+ }
+ else
+ {
+ /* If we're not blocking-when-empty, we want a while loop. */
+ while (within_human_latency_tolerance (&init)
+ && gtk_events_pending ())
+ gtk_main_iteration ();
+ }
+
+ (*env)->MonitorEnter (env, lockedQueue);
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_wakeNativeQueue
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
+{
+ g_main_context_wakeup (NULL);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_nativeQueueEmpty
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
+{
+ jboolean empty = FALSE;
+
+ gdk_threads_enter ();
+
+ empty = ! gtk_events_pending();
+
+ gdk_threads_leave ();
+
+ return empty;
+}
+
+
+static jint gdk_color_to_java_color (GdkColor color);
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_beep
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
+{
+ gdk_threads_enter ();
+
+ gdk_beep ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_sync
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
+{
+ gdk_threads_enter ();
+
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_getScreenSizeDimensions
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jintArray jdims)
+{
+ jint *dims = (*env)->GetIntArrayElements (env, jdims, 0);
+
+ gdk_threads_enter ();
+
+ dims[0] = gdk_screen_width ();
+ dims[1] = gdk_screen_height ();
+
+ gdk_threads_leave ();
+
+ (*env)->ReleaseIntArrayElements(env, jdims, dims, 0);
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_getScreenResolution
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
+{
+ jint res;
+
+ gdk_threads_enter ();
+
+ res = gdk_screen_width () / (gdk_screen_width_mm () / 25.4);
+
+ gdk_threads_leave ();
+
+ return res;
+}
+
+#define CONVERT(type, state) \
+ gdk_color_to_java_color (style->type[GTK_STATE_ ## state])
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_loadSystemColors
+ (JNIEnv *env, jobject obj __attribute__((unused)),
+ jintArray jcolors)
+{
+ jint *colors;
+ GtkStyle *style;
+
+ gdk_threads_enter ();
+
+ colors = (*env)->GetIntArrayElements (env, jcolors, 0);
+
+ style = gtk_widget_get_default_style ();
+
+ colors[AWT_DESKTOP] = CONVERT (bg, SELECTED);
+ colors[AWT_ACTIVE_CAPTION] = CONVERT (bg, SELECTED);
+ colors[AWT_ACTIVE_CAPTION_TEXT] = CONVERT (text, SELECTED);
+ colors[AWT_ACTIVE_CAPTION_BORDER] = CONVERT (fg, NORMAL);
+ colors[AWT_INACTIVE_CAPTION] = CONVERT (base, INSENSITIVE);
+ colors[AWT_INACTIVE_CAPTION_TEXT] = CONVERT (fg, INSENSITIVE);
+ colors[AWT_INACTIVE_CAPTION_BORDER] = CONVERT (fg, INSENSITIVE);
+ colors[AWT_WINDOW] = CONVERT (bg, NORMAL);
+ colors[AWT_WINDOW_BORDER] = CONVERT (fg, NORMAL);
+ colors[AWT_WINDOW_TEXT] = CONVERT (fg, NORMAL);
+ colors[AWT_MENU] = CONVERT (bg, NORMAL);
+ colors[AWT_MENU_TEXT] = CONVERT (fg, NORMAL);
+ colors[AWT_TEXT] = CONVERT (bg, NORMAL);
+ colors[AWT_TEXT_TEXT] = CONVERT (fg, NORMAL);
+ colors[AWT_TEXT_HIGHLIGHT] = CONVERT (bg, SELECTED);
+ colors[AWT_TEXT_HIGHLIGHT_TEXT] = CONVERT (fg, SELECTED);
+ colors[AWT_TEXT_INACTIVE_TEXT] = CONVERT (bg, INSENSITIVE);
+ colors[AWT_CONTROL] = CONVERT (bg, NORMAL);
+ colors[AWT_CONTROL_TEXT] = CONVERT (fg, NORMAL);
+ colors[AWT_CONTROL_HIGHLIGHT] = CONVERT (base, ACTIVE);
+ colors[AWT_CONTROL_LT_HIGHLIGHT] = CONVERT (bg, PRELIGHT);
+ colors[AWT_CONTROL_SHADOW] = CONVERT (bg, ACTIVE);
+ colors[AWT_CONTROL_DK_SHADOW] = CONVERT (fg, INSENSITIVE);
+ colors[AWT_SCROLLBAR] = CONVERT (base, INSENSITIVE);
+ colors[AWT_INFO] = CONVERT (bg, NORMAL);
+ colors[AWT_INFO_TEXT] = CONVERT (fg, NORMAL);
+
+ (*env)->ReleaseIntArrayElements(env, jcolors, colors, 0);
+
+ gdk_threads_leave ();
+}
+
+#undef CONVERT
+
+static jint
+gdk_color_to_java_color (GdkColor gdk_color)
+{
+ guchar red;
+ guchar green;
+ guchar blue;
+ float factor;
+
+ factor = 255.0 / 65535.0;
+
+ red = (float) gdk_color.red * factor;
+ green = (float) gdk_color.green * factor;
+ blue = (float) gdk_color.blue * factor;
+
+ return (jint) (0xff000000 | (red << 16) | (green << 8) | blue);
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
new file mode 100644
index 00000000000..650d9b6030e
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
@@ -0,0 +1,2181 @@
+/* gtkwindowpeer.c -- Native implementation of GtkWindowPeer
+ Copyright (C) 1998, 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+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_OPENED 200
+#define AWT_WINDOW_CLOSING 201
+#define AWT_WINDOW_CLOSED 202
+#define AWT_WINDOW_ICONIFIED 203
+#define AWT_WINDOW_DEICONIFIED 204
+#define AWT_WINDOW_ACTIVATED 205
+#define AWT_WINDOW_DEACTIVATED 206
+#define AWT_WINDOW_GAINED_FOCUS 207
+#define AWT_WINDOW_LOST_FOCUS 208
+#define AWT_WINDOW_STATE_CHANGED 209
+
+/* Virtual Keys */
+/* This list should be kept in the same order as the VK_ field
+ declarations in KeyEvent.java. */
+#define VK_ENTER '\n'
+#define VK_BACK_SPACE '\b'
+#define VK_TAB '\t'
+#define VK_CANCEL 3
+#define VK_CLEAR 12
+#define VK_SHIFT 16
+#define VK_CONTROL 17
+#define VK_ALT 18
+#define VK_PAUSE 19
+#define VK_CAPS_LOCK 20
+#define VK_ESCAPE 27
+#define VK_SPACE ' '
+#define VK_PAGE_UP 33
+#define VK_PAGE_DOWN 34
+#define VK_END 35
+#define VK_HOME 36
+#define VK_LEFT 37
+#define VK_UP 38
+#define VK_RIGHT 39
+#define VK_DOWN 40
+#define VK_COMMA ','
+#define VK_MINUS '-'
+#define VK_PERIOD '.'
+#define VK_SLASH '/'
+#define VK_0 '0'
+#define VK_1 '1'
+#define VK_2 '2'
+#define VK_3 '3'
+#define VK_4 '4'
+#define VK_5 '5'
+#define VK_6 '6'
+#define VK_7 '7'
+#define VK_8 '8'
+#define VK_9 '9'
+#define VK_SEMICOLON ';'
+#define VK_EQUALS '='
+#define VK_A 'A'
+#define VK_B 'B'
+#define VK_C 'C'
+#define VK_D 'D'
+#define VK_E 'E'
+#define VK_F 'F'
+#define VK_G 'G'
+#define VK_H 'H'
+#define VK_I 'I'
+#define VK_J 'J'
+#define VK_K 'K'
+#define VK_L 'L'
+#define VK_M 'M'
+#define VK_N 'N'
+#define VK_O 'O'
+#define VK_P 'P'
+#define VK_Q 'Q'
+#define VK_R 'R'
+#define VK_S 'S'
+#define VK_T 'T'
+#define VK_U 'U'
+#define VK_V 'V'
+#define VK_W 'W'
+#define VK_X 'X'
+#define VK_Y 'Y'
+#define VK_Z 'Z'
+#define VK_OPEN_BRACKET '['
+#define VK_BACK_SLASH '\\'
+#define VK_CLOSE_BRACKET ']'
+/* See gtkpeer.h */
+/* #define VK_NUMPAD0 96 */
+/* #define VK_NUMPAD1 97 */
+/* #define VK_NUMPAD2 98 */
+/* #define VK_NUMPAD3 99 */
+/* #define VK_NUMPAD4 100 */
+/* #define VK_NUMPAD5 101 */
+/* #define VK_NUMPAD6 102 */
+/* #define VK_NUMPAD7 103 */
+/* #define VK_NUMPAD8 104 */
+/* #define VK_NUMPAD9 105 */
+#define VK_MULTIPLY 106
+#define VK_ADD 107
+#define VK_SEPARATER 108
+#define VK_SEPARATOR 108
+#define VK_SUBTRACT 109
+/* See gtkpeer.h */
+/* #define VK_DECIMAL 110 */
+#define VK_DIVIDE 111
+#define VK_DELETE 127
+#define VK_NUM_LOCK 144
+#define VK_SCROLL_LOCK 145
+#define VK_F1 112
+#define VK_F2 113
+#define VK_F3 114
+#define VK_F4 115
+#define VK_F5 116
+#define VK_F6 117
+#define VK_F7 118
+#define VK_F8 119
+#define VK_F9 120
+#define VK_F10 121
+#define VK_F11 122
+#define VK_F12 123
+#define VK_F13 61440
+#define VK_F14 61441
+#define VK_F15 61442
+#define VK_F16 61443
+#define VK_F17 61444
+#define VK_F18 61445
+#define VK_F19 61446
+#define VK_F20 61447
+#define VK_F21 61448
+#define VK_F22 61449
+#define VK_F23 61450
+#define VK_F24 61451
+#define VK_PRINTSCREEN 154
+#define VK_INSERT 155
+#define VK_HELP 156
+#define VK_META 157
+#define VK_BACK_QUOTE 192
+#define VK_QUOTE 222
+#define VK_KP_UP 224
+#define VK_KP_DOWN 225
+#define VK_KP_LEFT 226
+#define VK_KP_RIGHT 227
+#define VK_DEAD_GRAVE 128
+#define VK_DEAD_ACUTE 129
+#define VK_DEAD_CIRCUMFLEX 130
+#define VK_DEAD_TILDE 131
+#define VK_DEAD_MACRON 132
+#define VK_DEAD_BREVE 133
+#define VK_DEAD_ABOVEDOT 134
+#define VK_DEAD_DIAERESIS 135
+#define VK_DEAD_ABOVERING 136
+#define VK_DEAD_DOUBLEACUTE 137
+#define VK_DEAD_CARON 138
+#define VK_DEAD_CEDILLA 139
+#define VK_DEAD_OGONEK 140
+#define VK_DEAD_IOTA 141
+#define VK_DEAD_VOICED_SOUND 142
+#define VK_DEAD_SEMIVOICED_SOUND 143
+#define VK_AMPERSAND 150
+#define VK_ASTERISK 151
+#define VK_QUOTEDBL 152
+#define VK_LESS 153
+#define VK_GREATER 160
+#define VK_BRACELEFT 161
+#define VK_BRACERIGHT 162
+#define VK_AT 512
+#define VK_COLON 513
+#define VK_CIRCUMFLEX 514
+#define VK_DOLLAR 515
+#define VK_EURO_SIGN 516
+#define VK_EXCLAMATION_MARK 517
+#define VK_INVERTED_EXCLAMATION_MARK 518
+#define VK_LEFT_PARENTHESIS 519
+#define VK_NUMBER_SIGN 520
+#define VK_PLUS 521
+#define VK_RIGHT_PARENTHESIS 522
+#define VK_UNDERSCORE 523
+#define VK_FINAL 24
+#define VK_CONVERT 28
+#define VK_NONCONVERT 29
+#define VK_ACCEPT 30
+#define VK_MODECHANGE 31
+#define VK_KANA 21
+#define VK_KANJI 25
+#define VK_ALPHANUMERIC 240
+#define VK_KATAKANA 241
+#define VK_HIRAGANA 242
+#define VK_FULL_WIDTH 243
+#define VK_HALF_WIDTH 244
+#define VK_ROMAN_CHARACTERS 245
+#define VK_ALL_CANDIDATES 256
+#define VK_PREVIOUS_CANDIDATE 257
+#define VK_CODE_INPUT 258
+#define VK_JAPANESE_KATAKANA 259
+#define VK_JAPANESE_HIRAGANA 260
+#define VK_JAPANESE_ROMAN 261
+#define VK_KANA_LOCK 262
+#define VK_INPUT_METHOD_ON_OFF 263
+#define VK_CUT 65489
+#define VK_COPY 65485
+#define VK_PASTE 65487
+#define VK_UNDO 65483
+#define VK_AGAIN 65481
+#define VK_FIND 65488
+#define VK_PROPS 65482
+#define VK_STOP 65480
+#define VK_COMPOSE 65312
+#define VK_ALT_GRAPH 65406
+#define VK_UNDEFINED 0
+
+#define AWT_KEY_CHAR_UNDEFINED 0
+
+#define AWT_FRAME_STATE_NORMAL 0
+#define AWT_FRAME_STATE_ICONIFIED 1
+#define AWT_FRAME_STATE_MAXIMIZED_HORIZ 2
+#define AWT_FRAME_STATE_MAXIMIZED_VERT 4
+#define AWT_FRAME_STATE_MAXIMIZED_BOTH 6
+
+static jmethodID postKeyEventID;
+static jmethodID postWindowEventID;
+static jmethodID postConfigureEventID;
+static jmethodID postInsetsChangedEventID;
+static jmethodID windowGetWidthID;
+static jmethodID windowGetHeightID;
+static jmethodID setBoundsCallbackID;
+
+void
+cp_gtk_window_init_jni (void)
+{
+ jclass window;
+ jclass gtkwindowpeer;
+
+ window = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(), "java/awt/Window");
+
+ setBoundsCallbackID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), window,
+ "setBoundsCallback",
+ "(IIII)V");
+
+ gtkwindowpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GtkWindowPeer");
+
+ postKeyEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer,
+ "postKeyEvent", "(IJIICI)V");
+
+ postWindowEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer,
+ "postWindowEvent",
+ "(ILjava/awt/Window;I)V");
+
+ postConfigureEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer,
+ "postConfigureEvent", "(IIII)V");
+
+ postInsetsChangedEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer,
+ "postInsetsChangedEvent",
+ "(IIII)V");
+
+ windowGetWidthID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer,
+ "getWidth", "()I");
+
+ windowGetHeightID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkwindowpeer,
+ "getHeight", "()I");
+
+ gtkwindowpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
+ "gnu/java/awt/peer/gtk/GtkWindowPeer");
+}
+
+/* Get the first keyval in the keymap for this event's keycode. The
+ first keyval corresponds roughly to Java's notion of a virtual
+ key. Returns the uppercase version of the first keyval. */
+static guint
+get_first_keyval_from_keymap (GdkEventKey *event)
+{
+ guint keyval;
+ guint *keyvals;
+ gint n_entries;
+
+ if (!gdk_keymap_get_entries_for_keycode (NULL,
+ event->hardware_keycode,
+ NULL,
+ &keyvals,
+ &n_entries))
+ {
+ g_warning ("No keyval found for hardware keycode %d\n",
+ event->hardware_keycode);
+ /* Try to recover by using the keyval in the event structure. */
+ keyvals = &(event->keyval);
+ }
+ keyval = keyvals[0];
+ g_free (keyvals);
+
+ return gdk_keyval_to_upper (keyval);
+}
+
+#ifdef __GNUC__
+__inline
+#endif
+static jint
+keysym_to_awt_keycode (GdkEventKey *event)
+{
+ guint ukeyval;
+ guint state;
+
+ ukeyval = get_first_keyval_from_keymap (event);
+ state = event->state;
+
+ /* VK_A through VK_Z */
+ if (ukeyval >= GDK_A && ukeyval <= GDK_Z)
+ return ukeyval;
+
+ /* VK_0 through VK_9 */
+ if (ukeyval >= GDK_0 && ukeyval <= GDK_9)
+ return ukeyval;
+
+ switch (ukeyval)
+ {
+ case GDK_Return:
+ case GDK_KP_Enter:
+ return VK_ENTER;
+ case GDK_BackSpace:
+ return VK_BACK_SPACE;
+ case GDK_Tab:
+ return VK_TAB;
+ case GDK_Cancel:
+ return VK_CANCEL;
+ case GDK_Clear:
+ return VK_CLEAR;
+ case GDK_Shift_L:
+ case GDK_Shift_R:
+ return VK_SHIFT;
+ case GDK_Control_L:
+ case GDK_Control_R:
+ return VK_CONTROL;
+ case GDK_Alt_L:
+ case GDK_Alt_R:
+ return VK_ALT;
+ case GDK_Pause:
+ return VK_PAUSE;
+ case GDK_Caps_Lock:
+ return VK_CAPS_LOCK;
+ case GDK_Escape:
+ return VK_ESCAPE;
+ case GDK_space:
+ return VK_SPACE;
+ case GDK_KP_Page_Up:
+ /* For keys on the numeric keypad, the JVM produces one of two
+ virtual keys, depending on the num lock state. */
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD9;
+ else
+ return VK_PAGE_UP;
+ case GDK_Page_Up:
+ return VK_PAGE_UP;
+ case GDK_KP_Page_Down:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD3;
+ else
+ return VK_PAGE_DOWN;
+ case GDK_Page_Down:
+ return VK_PAGE_DOWN;
+ case GDK_KP_End:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD1;
+ else
+ return VK_END;
+ case GDK_End:
+ return VK_END;
+ case GDK_KP_Home:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD7;
+ else
+ return VK_HOME;
+ case GDK_Home:
+ return VK_HOME;
+ case GDK_KP_Begin:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD5;
+ else
+ return VK_UNDEFINED;
+ case GDK_Left:
+ return VK_LEFT;
+ case GDK_Up:
+ return VK_UP;
+ case GDK_Right:
+ return VK_RIGHT;
+ case GDK_Down:
+ return VK_DOWN;
+ case GDK_comma:
+ return VK_COMMA;
+ case GDK_minus:
+ return VK_MINUS;
+ case GDK_period:
+ return VK_PERIOD;
+ case GDK_slash:
+ return VK_SLASH;
+ /*
+ return VK_0;
+ return VK_1;
+ return VK_2;
+ return VK_3;
+ return VK_4;
+ return VK_5;
+ return VK_6;
+ return VK_7;
+ return VK_8;
+ return VK_9;
+ */
+ case GDK_semicolon:
+ return VK_SEMICOLON;
+ case GDK_equal:
+ return VK_EQUALS;
+ /*
+ return VK_A;
+ return VK_B;
+ return VK_C;
+ return VK_D;
+ return VK_E;
+ return VK_F;
+ return VK_G;
+ return VK_H;
+ return VK_I;
+ return VK_J;
+ return VK_K;
+ return VK_L;
+ return VK_M;
+ return VK_N;
+ return VK_O;
+ return VK_P;
+ return VK_Q;
+ return VK_R;
+ return VK_S;
+ return VK_T;
+ return VK_U;
+ return VK_V;
+ return VK_W;
+ return VK_X;
+ return VK_Y;
+ return VK_Z;
+ */
+ case GDK_bracketleft:
+ return VK_OPEN_BRACKET;
+ case GDK_backslash:
+ return VK_BACK_SLASH;
+ case GDK_bracketright:
+ return VK_CLOSE_BRACKET;
+ case GDK_KP_0:
+ return VK_NUMPAD0;
+ case GDK_KP_1:
+ return VK_NUMPAD1;
+ case GDK_KP_2:
+ return VK_NUMPAD2;
+ case GDK_KP_3:
+ return VK_NUMPAD3;
+ case GDK_KP_4:
+ return VK_NUMPAD4;
+ case GDK_KP_5:
+ return VK_NUMPAD5;
+ case GDK_KP_6:
+ return VK_NUMPAD6;
+ case GDK_KP_7:
+ return VK_NUMPAD7;
+ case GDK_KP_8:
+ return VK_NUMPAD8;
+ case GDK_KP_9:
+ return VK_NUMPAD9;
+ case GDK_KP_Multiply:
+ return VK_MULTIPLY;
+ case GDK_KP_Add:
+ return VK_ADD;
+ /*
+ return VK_SEPARATER;
+ */
+ case GDK_KP_Separator:
+ return VK_SEPARATOR;
+ case GDK_KP_Subtract:
+ return VK_SUBTRACT;
+ case GDK_KP_Decimal:
+ return VK_DECIMAL;
+ case GDK_KP_Divide:
+ return VK_DIVIDE;
+ case GDK_KP_Delete:
+ if (state & GDK_MOD2_MASK)
+ return VK_DECIMAL;
+ else
+ return VK_DELETE;
+ case GDK_Delete:
+ return VK_DELETE;
+ case GDK_Num_Lock:
+ return VK_NUM_LOCK;
+ case GDK_Scroll_Lock:
+ return VK_SCROLL_LOCK;
+ case GDK_F1:
+ return VK_F1;
+ case GDK_F2:
+ return VK_F2;
+ case GDK_F3:
+ return VK_F3;
+ case GDK_F4:
+ return VK_F4;
+ case GDK_F5:
+ return VK_F5;
+ case GDK_F6:
+ return VK_F6;
+ case GDK_F7:
+ return VK_F7;
+ case GDK_F8:
+ return VK_F8;
+ case GDK_F9:
+ return VK_F9;
+ case GDK_F10:
+ return VK_F10;
+ case GDK_F11:
+ return VK_F11;
+ case GDK_F12:
+ return VK_F12;
+ case GDK_F13:
+ return VK_F13;
+ case GDK_F14:
+ return VK_F14;
+ case GDK_F15:
+ return VK_F15;
+ case GDK_F16:
+ return VK_F16;
+ case GDK_F17:
+ return VK_F17;
+ case GDK_F18:
+ return VK_F18;
+ case GDK_F19:
+ return VK_F19;
+ case GDK_F20:
+ return VK_F20;
+ case GDK_F21:
+ return VK_F21;
+ case GDK_F22:
+ return VK_F22;
+ case GDK_F23:
+ return VK_F23;
+ case GDK_F24:
+ return VK_F24;
+ case GDK_Print:
+ return VK_PRINTSCREEN;
+ case GDK_KP_Insert:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD0;
+ else
+ return VK_INSERT;
+ case GDK_Insert:
+ return VK_INSERT;
+ case GDK_Help:
+ return VK_HELP;
+ case GDK_Meta_L:
+ case GDK_Meta_R:
+ return VK_META;
+ case GDK_grave:
+ return VK_BACK_QUOTE;
+ case GDK_apostrophe:
+ return VK_QUOTE;
+ case GDK_KP_Up:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD8;
+ else
+ return VK_KP_UP;
+ case GDK_KP_Down:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD2;
+ else
+ return VK_KP_DOWN;
+ case GDK_KP_Left:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD4;
+ else
+ return VK_KP_LEFT;
+ case GDK_KP_Right:
+ if (state & GDK_MOD2_MASK)
+ return VK_NUMPAD6;
+ else
+ return VK_KP_RIGHT;
+ case GDK_dead_grave:
+ return VK_DEAD_GRAVE;
+ case GDK_dead_acute:
+ return VK_DEAD_ACUTE;
+ case GDK_dead_circumflex:
+ return VK_DEAD_CIRCUMFLEX;
+ case GDK_dead_tilde:
+ return VK_DEAD_TILDE;
+ case GDK_dead_macron:
+ return VK_DEAD_MACRON;
+ case GDK_dead_breve:
+ return VK_DEAD_BREVE;
+ case GDK_dead_abovedot:
+ return VK_DEAD_ABOVEDOT;
+ case GDK_dead_diaeresis:
+ return VK_DEAD_DIAERESIS;
+ case GDK_dead_abovering:
+ return VK_DEAD_ABOVERING;
+ case GDK_dead_doubleacute:
+ return VK_DEAD_DOUBLEACUTE;
+ case GDK_dead_caron:
+ return VK_DEAD_CARON;
+ case GDK_dead_cedilla:
+ return VK_DEAD_CEDILLA;
+ case GDK_dead_ogonek:
+ return VK_DEAD_OGONEK;
+ case GDK_dead_iota:
+ return VK_DEAD_IOTA;
+ case GDK_dead_voiced_sound:
+ return VK_DEAD_VOICED_SOUND;
+ case GDK_dead_semivoiced_sound:
+ return VK_DEAD_SEMIVOICED_SOUND;
+ case GDK_ampersand:
+ return VK_AMPERSAND;
+ case GDK_asterisk:
+ return VK_ASTERISK;
+ case GDK_quotedbl:
+ return VK_QUOTEDBL;
+ case GDK_less:
+ return VK_LESS;
+ case GDK_greater:
+ return VK_GREATER;
+ case GDK_braceleft:
+ return VK_BRACELEFT;
+ case GDK_braceright:
+ return VK_BRACERIGHT;
+ case GDK_at:
+ return VK_AT;
+ case GDK_colon:
+ return VK_COLON;
+ case GDK_asciicircum:
+ return VK_CIRCUMFLEX;
+ case GDK_dollar:
+ return VK_DOLLAR;
+ case GDK_EuroSign:
+ return VK_EURO_SIGN;
+ case GDK_exclam:
+ return VK_EXCLAMATION_MARK;
+ case GDK_exclamdown:
+ return VK_INVERTED_EXCLAMATION_MARK;
+ case GDK_parenleft:
+ return VK_LEFT_PARENTHESIS;
+ case GDK_numbersign:
+ return VK_NUMBER_SIGN;
+ case GDK_plus:
+ return VK_PLUS;
+ case GDK_parenright:
+ return VK_RIGHT_PARENTHESIS;
+ case GDK_underscore:
+ return VK_UNDERSCORE;
+ /*
+ return VK_FINAL;
+ return VK_CONVERT;
+ return VK_NONCONVERT;
+ return VK_ACCEPT;
+ */
+ case GDK_Mode_switch:
+ return VK_MODECHANGE;
+ /*
+ return VK_KANA;
+ */
+ case GDK_Kanji:
+ return VK_KANJI;
+ /*
+ return VK_ALPHANUMERIC;
+ */
+ case GDK_Katakana:
+ return VK_KATAKANA;
+ case GDK_Hiragana:
+ return VK_HIRAGANA;
+ /*
+ return VK_FULL_WIDTH;
+ return VK_HALF_WIDTH;
+ return VK_ROMAN_CHARACTERS;
+ return VK_ALL_CANDIDATES;
+ */
+ case GDK_PreviousCandidate:
+ return VK_PREVIOUS_CANDIDATE;
+ case GDK_Codeinput:
+ return VK_CODE_INPUT;
+ /*
+ return VK_JAPANESE_KATAKANA;
+ return VK_JAPANESE_HIRAGANA;
+ return VK_JAPANESE_ROMAN;
+ */
+ case GDK_Kana_Lock:
+ return VK_KANA_LOCK;
+ /*
+ return VK_INPUT_METHOD_ON_OFF;
+ return VK_CUT;
+ return VK_COPY;
+ return VK_PASTE;
+ return VK_UNDO;
+ return VK_AGAIN;
+ return VK_FIND;
+ return VK_PROPS;
+ return VK_STOP;
+ return VK_COMPOSE;
+ return VK_ALT_GRAPH;
+ */
+ default:
+ return VK_UNDEFINED;
+ }
+}
+
+static jint
+keysym_to_awt_keylocation (GdkEventKey *event)
+{
+ guint ukeyval;
+
+ ukeyval = get_first_keyval_from_keymap (event);
+
+ /* VK_A through VK_Z */
+ if (ukeyval >= GDK_A && ukeyval <= GDK_Z)
+ return AWT_KEY_LOCATION_STANDARD;
+
+ /* VK_0 through VK_9 */
+ if (ukeyval >= GDK_0 && ukeyval <= GDK_9)
+ return AWT_KEY_LOCATION_STANDARD;
+
+ switch (ukeyval)
+ {
+ case GDK_Shift_L:
+ case GDK_Control_L:
+ case GDK_Alt_L:
+ case GDK_Meta_L:
+ return AWT_KEY_LOCATION_LEFT;
+
+ case GDK_Shift_R:
+ case GDK_Control_R:
+ case GDK_Alt_R:
+ case GDK_Meta_R:
+ return AWT_KEY_LOCATION_RIGHT;
+
+ case GDK_Return:
+ case GDK_BackSpace:
+ case GDK_Tab:
+ case GDK_Cancel:
+ case GDK_Clear:
+ case GDK_Pause:
+ case GDK_Caps_Lock:
+ case GDK_Escape:
+ case GDK_space:
+ case GDK_Page_Up:
+ case GDK_Page_Down:
+ case GDK_End:
+ case GDK_Home:
+ case GDK_Left:
+ case GDK_Up:
+ case GDK_Right:
+ case GDK_Down:
+ case GDK_comma:
+ case GDK_minus:
+ case GDK_period:
+ case GDK_slash:
+ case GDK_semicolon:
+ case GDK_equal:
+ case GDK_bracketleft:
+ case GDK_backslash:
+ case GDK_bracketright:
+ case GDK_Delete:
+ case GDK_Scroll_Lock:
+ case GDK_F1:
+ case GDK_F2:
+ case GDK_F3:
+ case GDK_F4:
+ case GDK_F5:
+ case GDK_F6:
+ case GDK_F7:
+ case GDK_F8:
+ case GDK_F9:
+ case GDK_F10:
+ case GDK_F11:
+ case GDK_F12:
+ case GDK_F13:
+ case GDK_F14:
+ case GDK_F15:
+ case GDK_F16:
+ case GDK_F17:
+ case GDK_F18:
+ case GDK_F19:
+ case GDK_F20:
+ case GDK_F21:
+ case GDK_F22:
+ case GDK_F23:
+ case GDK_F24:
+ case GDK_Print:
+ case GDK_Insert:
+ case GDK_Help:
+ case GDK_grave:
+ case GDK_apostrophe:
+ case GDK_dead_grave:
+ case GDK_dead_acute:
+ case GDK_dead_circumflex:
+ case GDK_dead_tilde:
+ case GDK_dead_macron:
+ case GDK_dead_breve:
+ case GDK_dead_abovedot:
+ case GDK_dead_diaeresis:
+ case GDK_dead_abovering:
+ case GDK_dead_doubleacute:
+ case GDK_dead_caron:
+ case GDK_dead_cedilla:
+ case GDK_dead_ogonek:
+ case GDK_dead_iota:
+ case GDK_dead_voiced_sound:
+ case GDK_dead_semivoiced_sound:
+ case GDK_ampersand:
+ case GDK_asterisk:
+ case GDK_quotedbl:
+ case GDK_less:
+ case GDK_greater:
+ case GDK_braceleft:
+ case GDK_braceright:
+ case GDK_at:
+ case GDK_colon:
+ case GDK_asciicircum:
+ case GDK_dollar:
+ case GDK_EuroSign:
+ case GDK_exclam:
+ case GDK_exclamdown:
+ case GDK_parenleft:
+ case GDK_numbersign:
+ case GDK_plus:
+ case GDK_parenright:
+ case GDK_underscore:
+ case GDK_Mode_switch:
+ case GDK_Kanji:
+ case GDK_Katakana:
+ case GDK_Hiragana:
+ case GDK_PreviousCandidate:
+ case GDK_Codeinput:
+ case GDK_Kana_Lock:
+ return AWT_KEY_LOCATION_STANDARD;
+
+ case GDK_KP_Enter:
+ case GDK_KP_Page_Up:
+ case GDK_KP_Page_Down:
+ case GDK_KP_End:
+ case GDK_KP_Home:
+ case GDK_KP_Begin:
+ case GDK_KP_0:
+ case GDK_KP_1:
+ case GDK_KP_2:
+ case GDK_KP_3:
+ case GDK_KP_4:
+ case GDK_KP_5:
+ case GDK_KP_6:
+ case GDK_KP_7:
+ case GDK_KP_8:
+ case GDK_KP_9:
+ case GDK_KP_Multiply:
+ case GDK_KP_Add:
+ case GDK_KP_Separator:
+ case GDK_KP_Subtract:
+ case GDK_KP_Decimal:
+ case GDK_KP_Divide:
+ case GDK_KP_Delete:
+ case GDK_Num_Lock:
+ case GDK_KP_Insert:
+ case GDK_KP_Up:
+ case GDK_KP_Down:
+ case GDK_KP_Left:
+ case GDK_KP_Right:
+ return AWT_KEY_LOCATION_NUMPAD;
+
+ default:
+ return AWT_KEY_LOCATION_UNKNOWN;
+ }
+}
+
+static jchar
+keyevent_to_awt_keychar (GdkEventKey *event)
+{
+ if (event->length > 0)
+ {
+ /* Translate GDK carriage return to Java linefeed. */
+ if (event->string[0] == 13)
+ return VK_ENTER;
+ else
+ return event->string[0];
+ }
+ else
+ {
+ switch (event->keyval)
+ {
+ case GDK_BackSpace:
+ return VK_BACK_SPACE;
+ case GDK_Tab:
+ return VK_TAB;
+ case GDK_Delete:
+ case GDK_KP_Delete:
+ return VK_DELETE;
+ default:
+ return AWT_KEY_CHAR_UNDEFINED;
+ }
+ }
+}
+
+/* Modifier key events need special treatment. In Sun's peer
+ implementation, when a modifier key is pressed, the KEY_PRESSED
+ event has that modifier in its modifiers list. The corresponding
+ KEY_RELEASED event's modifier list does not contain the modifier.
+ For example, pressing and releasing the shift key will produce a
+ key press event with modifiers=Shift, and a key release event with
+ no modifiers. GDK's key events behave in the exact opposite way,
+ so this translation code is needed. */
+static jint
+keyevent_state_to_awt_mods (GdkEventKey *event)
+{
+ jint result = 0;
+ guint state;
+
+ if (event->type == GDK_KEY_PRESS)
+ {
+ state = event->state;
+
+ if (event->keyval == GDK_Shift_L
+ || event->keyval == GDK_Shift_R)
+ result |= AWT_SHIFT_DOWN_MASK;
+ else
+ {
+ if (state & GDK_SHIFT_MASK)
+ result |= AWT_SHIFT_DOWN_MASK;
+ }
+
+ if (event->keyval == GDK_Control_L
+ || event->keyval == GDK_Control_R)
+ result |= AWT_CTRL_DOWN_MASK;
+ else
+ {
+ if (state & GDK_CONTROL_MASK)
+ result |= AWT_CTRL_DOWN_MASK;
+ }
+
+ if (event->keyval == GDK_Alt_L
+ || event->keyval == GDK_Alt_R)
+ result |= AWT_ALT_DOWN_MASK;
+ else
+ {
+ if (state & GDK_MOD1_MASK)
+ result |= AWT_ALT_DOWN_MASK;
+ }
+ }
+ else if (event->type == GDK_KEY_RELEASE)
+ {
+ state = event->state;
+
+ if (event->keyval != GDK_Shift_L
+ && event->keyval != GDK_Shift_R)
+ {
+ if (state & GDK_SHIFT_MASK)
+ result |= AWT_SHIFT_DOWN_MASK;
+ }
+ if (event->keyval != GDK_Control_L
+ && event->keyval != GDK_Control_R)
+ {
+ if (state & GDK_CONTROL_MASK)
+ result |= AWT_CTRL_DOWN_MASK;
+ }
+
+ if (event->keyval != GDK_Alt_L
+ && event->keyval != GDK_Alt_R)
+ {
+ if (state & GDK_MOD1_MASK)
+ result |= AWT_ALT_DOWN_MASK;
+ }
+ }
+
+ return result;
+}
+
+static gboolean window_configure_cb (GtkWidget *widget,
+ GdkEventConfigure *event,
+ jobject peer);
+
+/* FIXME: we're currently seeing the double-activation that occurs
+ with metacity and GTK. See
+ http://bugzilla.gnome.org/show_bug.cgi?id=140977 for details. */
+
+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,
+ jobject peer);
+static void window_show_cb (GtkWidget *widget, jobject peer);
+static void window_active_state_change_cb (GtkWidget *widget,
+ GParamSpec *pspec,
+ jobject peer);
+static void window_focus_state_change_cb (GtkWidget *widget,
+ GParamSpec *pspec,
+ jobject peer);
+static gboolean window_focus_in_cb (GtkWidget * widget,
+ GdkEventFocus *event,
+ jobject peer);
+static gboolean window_focus_out_cb (GtkWidget * widget,
+ GdkEventFocus *event,
+ jobject peer);
+static gboolean window_window_state_cb (GtkWidget *widget,
+ GdkEvent *event,
+ jobject peer);
+static jint window_get_new_state (GtkWidget *widget);
+static gboolean window_property_changed_cb (GtkWidget *widget,
+ GdkEventProperty *event,
+ jobject peer);
+static void realize_cb (GtkWidget *widget, jobject peer);
+
+static gboolean
+window_configure_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventConfigure *event,
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postConfigureEventID,
+ (jint) event->x,
+ (jint) event->y,
+ (jint) event->width,
+ (jint) event->height);
+
+ gdk_threads_enter ();
+
+ return FALSE;
+}
+
+static gboolean
+key_press_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventKey *event,
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postKeyEventID,
+ (jint) AWT_KEY_PRESSED,
+ (jlong) event->time,
+ keyevent_state_to_awt_mods (event),
+ keysym_to_awt_keycode (event),
+ keyevent_to_awt_keychar (event),
+ keysym_to_awt_keylocation (event));
+
+ gdk_threads_enter ();
+
+ /* FIXME: generation of key typed events needs to be moved
+ to GtkComponentPeer.postKeyEvent. If the key in a key
+ press event is not an "action" key
+ (KeyEvent.isActionKey) and is not a modifier key, then
+ it should generate a key typed event. */
+ return TRUE;
+}
+
+
+static gboolean
+key_release_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventKey *event,
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postKeyEventID,
+ (jint) AWT_KEY_RELEASED,
+ (jlong) event->time,
+ keyevent_state_to_awt_mods (event),
+ keysym_to_awt_keycode (event),
+ keyevent_to_awt_keychar (event),
+ keysym_to_awt_keylocation (event));
+
+ gdk_threads_enter ();
+
+ return TRUE;
+}
+
+/* Union used for type punning. */
+union extents_union
+{
+ guchar **gu_extents;
+ 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)
+{
+ GtkWidget *window_widget;
+ GtkWindow *window;
+ void *window_parent;
+ GtkWidget *fixed;
+
+ gdk_threads_enter ();
+
+ NSA_SET_GLOBAL_REF (env, obj);
+
+ window_widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ window = GTK_WINDOW (window_widget);
+
+ /* Keep this window in front of its parent, if it has one. */
+ if (parent)
+ {
+ window_parent = NSA_GET_PTR (env, parent);
+ gtk_window_set_transient_for (window, GTK_WINDOW(window_parent));
+ }
+
+ gtk_window_set_decorated (window, decorated);
+
+ gtk_window_set_type_hint (window, type);
+
+ gtk_window_group_add_window (cp_gtk_global_window_group, window);
+
+ fixed = gtk_fixed_new ();
+
+ gtk_container_add (GTK_CONTAINER (window_widget), fixed);
+
+ gtk_widget_show (fixed);
+
+ NSA_SET_PTR (env, obj, window_widget);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetTitle
+ (JNIEnv *env, jobject obj, jstring title)
+{
+ const char *c_title;
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ c_title = (*env)->GetStringUTFChars (env, title, NULL);
+
+ gtk_window_set_title (GTK_WINDOW (ptr), c_title);
+
+ (*env)->ReleaseStringUTFChars (env, title, c_title);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetResizable
+ (JNIEnv *env, jobject obj, jboolean resizable)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_window_set_policy (GTK_WINDOW (ptr), resizable, resizable, FALSE);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetModal
+ (JNIEnv *env, jobject obj, jboolean modal)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_window_set_modal (GTK_WINDOW (ptr), modal);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetVisible
+ (JNIEnv *env, jobject obj, jboolean visible)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ if (visible)
+ gtk_widget_show (GTK_WIDGET (ptr));
+ else
+ gtk_widget_hide (GTK_WIDGET (ptr));
+
+ XFlush (GDK_DISPLAY ());
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals
+ (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ jobject *gref;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+ gref = NSA_GET_GLOBAL_REF (env, obj);
+
+ g_signal_connect (G_OBJECT (ptr), "delete-event",
+ G_CALLBACK (window_delete_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "destroy-event",
+ G_CALLBACK (window_destroy_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "show",
+ G_CALLBACK (window_show_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "notify::is-active",
+ G_CALLBACK (window_active_state_change_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "notify::has-toplevel-focus",
+ G_CALLBACK (window_focus_state_change_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "focus-in-event",
+ G_CALLBACK (window_focus_in_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "focus-out-event",
+ G_CALLBACK (window_focus_out_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "window-state-event",
+ G_CALLBACK (window_window_state_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "property-notify-event",
+ G_CALLBACK (window_property_changed_cb), *gref);
+
+ g_signal_connect_after (G_OBJECT (ptr), "realize",
+ G_CALLBACK (realize_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "key-press-event",
+ G_CALLBACK (key_press_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "key-release-event",
+ G_CALLBACK (key_release_cb), *gref);
+
+ g_signal_connect_after (G_OBJECT (ptr), "window-state-event",
+ G_CALLBACK (window_window_state_cb), *gref);
+
+ g_signal_connect (G_OBJECT (ptr), "configure-event",
+ G_CALLBACK (window_configure_cb), *gref);
+
+ cp_gtk_component_connect_expose_signals (ptr, gref);
+ cp_gtk_component_connect_mouse_signals (ptr, gref);
+
+ /* FIXME: override focus signals here to prevent child fixed repaint? */
+
+ gdk_threads_leave ();
+}
+
+/* Realize the window here so that its frame extents are known now.
+ That way Window.pack can operate with the accurate insets returned
+ by the window manager rather than the default estimates. */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_realize (JNIEnv *env, jobject obj)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gtk_widget_realize (GTK_WIDGET (ptr));
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_toBack (JNIEnv *env,
+ jobject obj)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gdk_window_lower (GTK_WIDGET (ptr)->window);
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_toFront (JNIEnv *env,
+ jobject obj)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ gdk_window_raise (GTK_WIDGET (ptr)->window);
+ gdk_flush ();
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setBoundsCallback
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jobject window, jint x, jint y, jint width, jint height)
+{
+ /* Circumvent package-private access to call Window's
+ setBoundsCallback method. */
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), window, setBoundsCallbackID,
+ x, y, width, height);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setSize
+ (JNIEnv *env, jobject obj, jint width, jint height)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ /* Avoid GTK runtime assertion failures. */
+ width = (width < 1) ? 1 : width;
+ height = (height < 1) ? 1 : height;
+
+ gtk_widget_set_size_request (GTK_WIDGET(ptr), width, height);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetBounds
+ (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+ void *ptr;
+
+ gdk_threads_enter ();
+
+ ptr = NSA_GET_PTR (env, obj);
+
+ /* Avoid GTK runtime assertion failures. */
+ width = (width < 1) ? 1 : width;
+ height = (height < 1) ? 1 : height;
+
+ gtk_window_move (GTK_WINDOW(ptr), x, y);
+ /* The call to gdk_window_move is needed in addition to the call to
+ gtk_window_move. If gdk_window_move isn't called, then the
+ following set of operations doesn't give the expected results:
+
+ 1. show a window
+ 2. manually move it to another position on the screen
+ 3. hide the window
+ 4. reposition the window with Component.setLocation
+ 5. show the window
+
+ Instead of being at the position set by setLocation, the window
+ is reshown at the position to which it was moved manually. */
+ if (GTK_WIDGET (ptr)->window != NULL)
+ gdk_window_move (GTK_WIDGET (ptr)->window, x, y);
+
+ /* Need to change the widget's request size. */
+ gtk_widget_set_size_request (GTK_WIDGET(ptr), width, height);
+ /* Also need to call gtk_window_resize. If the resize is requested
+ by the program and the window's "resizable" property is true then
+ the size request will not be honoured. */
+ gtk_window_resize (GTK_WINDOW (ptr), width, height);
+
+ gdk_threads_leave ();
+}
+
+static void
+window_get_frame_extents (GtkWidget *window,
+ int *top, int *left, int *bottom, int *right)
+{
+ unsigned long *extents = NULL;
+ union extents_union gu_ex;
+
+ /* Guess frame extents in case _NET_FRAME_EXTENTS is not
+ supported. */
+ *top = 23;
+ *left = 6;
+ *bottom = 6;
+ *right = 6;
+
+ /* 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
+window_delete_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEvent *event __attribute__((unused)),
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_CLOSING,
+ (jobject) NULL, (jint) 0);
+
+ gdk_threads_enter ();
+
+ /* Prevents that the Window dissappears ("destroy"
+ not being signalled). This is necessary because it
+ should be up to a WindowListener implementation
+ how the AWT Frame responds to close requests. */
+ return TRUE;
+}
+
+static void
+window_destroy_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEvent *event __attribute__((unused)),
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_CLOSED,
+ (jobject) NULL, (jint) 0);
+
+ gdk_threads_enter ();
+}
+
+static void
+window_show_cb (GtkWidget *widget __attribute__((unused)),
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_OPENED,
+ (jobject) NULL, (jint) 0);
+
+ gdk_threads_enter ();
+}
+
+static void
+window_active_state_change_cb (GtkWidget *widget __attribute__((unused)),
+ GParamSpec *pspec __attribute__((unused)),
+ jobject peer __attribute__((unused)))
+{
+ /* FIXME: not sure if this is needed or not. */
+ /* Remove the unused attributes if you fix the below. */
+#if 0
+ gdk_threads_leave ();
+
+ if (GTK_WINDOW (widget)->is_active)
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_GAINED_FOCUS,
+ (jobject) NULL, (jint) 0);
+ else
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_DEACTIVATED,
+ (jobject) NULL, (jint) 0);
+
+ gdk_threads_enter ();
+#endif
+}
+
+static void
+window_focus_state_change_cb (GtkWidget *widget,
+ GParamSpec *pspec __attribute__((unused)),
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ if (GTK_WINDOW (widget)->has_toplevel_focus)
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_ACTIVATED,
+ (jobject) NULL, (jint) 0);
+ else
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_DEACTIVATED,
+ (jobject) NULL, (jint) 0);
+
+ gdk_threads_enter ();
+}
+
+static gboolean
+window_focus_in_cb (GtkWidget * widget __attribute__((unused)),
+ GdkEventFocus *event __attribute__((unused)),
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_GAINED_FOCUS,
+ (jobject) NULL, (jint) 0);
+
+ gdk_threads_enter ();
+
+ return FALSE;
+}
+
+static gboolean
+window_focus_out_cb (GtkWidget * widget __attribute__((unused)),
+ GdkEventFocus *event __attribute__((unused)),
+ jobject peer)
+{
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_LOST_FOCUS,
+ (jobject) NULL, (jint) 0);
+
+ gdk_threads_enter ();
+
+ return FALSE;
+}
+
+static gboolean
+window_window_state_cb (GtkWidget *widget,
+ GdkEvent *event,
+ jobject peer)
+{
+ jint new_state;
+
+ /* Handle WINDOW_ICONIFIED and WINDOW_DEICONIFIED events. */
+ if (event->window_state.changed_mask & GDK_WINDOW_STATE_ICONIFIED)
+ {
+ /* We've either been iconified or deiconified. */
+ if (event->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED)
+ {
+ /* We've been iconified. */
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_ICONIFIED,
+ (jobject) NULL, (jint) 0);
+
+ gdk_threads_enter ();
+ }
+ else
+ {
+ /* We've been deiconified. */
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_DEICONIFIED,
+ (jobject) NULL, (jint) 0);
+
+ gdk_threads_enter ();
+ }
+ }
+
+ /* Post a WINDOW_STATE_CHANGED event, passing the new frame state to
+ GtkWindowPeer. */
+ new_state = AWT_FRAME_STATE_NORMAL;
+
+ if (event->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED)
+ new_state |= AWT_FRAME_STATE_ICONIFIED;
+
+ new_state |= window_get_new_state (widget);
+
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postWindowEventID,
+ (jint) AWT_WINDOW_STATE_CHANGED,
+ (jobject) NULL, new_state);
+
+ gdk_threads_enter ();
+
+ return TRUE;
+}
+
+static jint
+window_get_new_state (GtkWidget *widget)
+{
+ GdkDisplay *display = gtk_widget_get_display(widget);
+ jint new_state = AWT_FRAME_STATE_NORMAL;
+ Atom type;
+ gint format;
+ gulong atom_count;
+ gulong bytes_after;
+ Atom *atom_list = NULL;
+ union atom_list_union alu;
+ gulong i;
+
+ alu.atom_list = &atom_list;
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XID (widget->window),
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
+ 0, G_MAXLONG, False, XA_ATOM, &type, &format, &atom_count,
+ &bytes_after, alu.gu_extents);
+
+ if (type != None)
+ {
+ Atom maxvert = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
+ Atom maxhorz = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
+
+ i = 0;
+ while (i < atom_count)
+ {
+ if (atom_list[i] == maxhorz)
+ new_state |= AWT_FRAME_STATE_MAXIMIZED_HORIZ;
+ else if (atom_list[i] == maxvert)
+ new_state |= AWT_FRAME_STATE_MAXIMIZED_VERT;
+
+ ++i;
+ }
+
+ XFree (atom_list);
+ }
+ return new_state;
+}
+
+static gboolean
+window_property_changed_cb (GtkWidget *widget __attribute__((unused)),
+ GdkEventProperty *event,
+ jobject peer)
+{
+ unsigned long *extents;
+ union extents_union gu_ex;
+
+ gu_ex.extents = &extents;
+ if (gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE) == event->atom
+ && gdk_property_get (event->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))
+ {
+ gdk_threads_leave ();
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postInsetsChangedEventID,
+ (jint) extents[2], /* top */
+ (jint) extents[0], /* left */
+ (jint) extents[3], /* bottom */
+ (jint) extents[1]); /* right */
+
+ gdk_threads_enter ();
+ }
+
+
+ return FALSE;
+}
+
+static void
+realize_cb (GtkWidget *widget, jobject peer)
+{
+ jint top = 0;
+ jint left = 0;
+ jint bottom = 0;
+ jint right = 0;
+ jint width = 0;
+ jint height = 0;
+
+ width = (*cp_gtk_gdk_env())->CallIntMethod (cp_gtk_gdk_env(), peer, windowGetWidthID);
+ height = (*cp_gtk_gdk_env())->CallIntMethod (cp_gtk_gdk_env(), peer, windowGetHeightID);
+
+ window_get_frame_extents (widget, &top, &left, &bottom, &right);
+
+ (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
+ postInsetsChangedEventID,
+ top, left, bottom, right);
+
+ gtk_window_set_default_size (GTK_WINDOW (widget),
+ MAX (1, width - left - right),
+ MAX (1, height - top - bottom));
+
+ /* set the size like we do in nativeSetBounds */
+ gtk_widget_set_size_request (widget,
+ MAX (1, width - left - right),
+ MAX (1, height - top - bottom));
+
+ gtk_window_resize (GTK_WINDOW (widget),
+ MAX (1, width - left - right),
+ MAX (1, height - top - bottom));
+}
+
+/*
+ * This method returns a GDK keyval that corresponds to one of the
+ * keysyms in the X keymap table. The return value is only used to
+ * determine the keyval's corresponding hardware keycode, and doesn't
+ * reflect an accurate translation of a Java virtual key value to a
+ * GDK keyval.
+ */
+#ifdef __GNUC__
+__inline
+#endif
+guint
+cp_gtk_awt_keycode_to_keysym (jint keyCode, jint keyLocation)
+{
+ /* GDK_A through GDK_Z */
+ if (keyCode >= VK_A && keyCode <= VK_Z)
+ return gdk_keyval_to_lower (keyCode);
+
+ /* GDK_0 through GDK_9 */
+ if (keyCode >= VK_0 && keyCode <= VK_9)
+ return keyCode;
+
+ switch (keyCode)
+ {
+ case VK_ENTER:
+ return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Enter : GDK_Return;
+ case VK_BACK_SPACE:
+ return GDK_BackSpace;
+ case VK_TAB:
+ return GDK_Tab;
+ case VK_CANCEL:
+ return GDK_Cancel;
+ case VK_CLEAR:
+ return GDK_Clear;
+ case VK_SHIFT:
+ return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Shift_L : GDK_Shift_R;
+ case VK_CONTROL:
+ return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Control_L : GDK_Control_R;
+ case VK_ALT:
+ return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Alt_L : GDK_Alt_R;
+ case VK_PAUSE:
+ return GDK_Pause;
+ case VK_CAPS_LOCK:
+ return GDK_Caps_Lock;
+ case VK_ESCAPE:
+ return GDK_Escape;
+ case VK_SPACE:
+ return GDK_space;
+ case VK_PAGE_UP:
+ return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Page_Up : GDK_Page_Up;
+ case VK_PAGE_DOWN:
+ return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Page_Down : GDK_Page_Down;
+ case VK_END:
+ return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_End : GDK_End;
+ case VK_HOME:
+ return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Home : GDK_Home;
+ case VK_LEFT:
+ return GDK_Left;
+ case VK_UP:
+ return GDK_Up;
+ case VK_RIGHT:
+ return GDK_Right;
+ case VK_DOWN:
+ return GDK_Down;
+ case VK_COMMA:
+ return GDK_comma;
+ case VK_MINUS:
+ return GDK_minus;
+ case VK_PERIOD:
+ return GDK_period;
+ case VK_SLASH:
+ return GDK_slash;
+ /*
+ case VK_0:
+ case VK_1:
+ case VK_2:
+ case VK_3:
+ case VK_4:
+ case VK_5:
+ case VK_6:
+ case VK_7:
+ case VK_8:
+ case VK_9:
+ */
+ case VK_SEMICOLON:
+ return GDK_semicolon;
+ case VK_EQUALS:
+ return GDK_equal;
+ /*
+ case VK_A:
+ case VK_B:
+ case VK_C:
+ case VK_D:
+ case VK_E:
+ case VK_F:
+ case VK_G:
+ case VK_H:
+ case VK_I:
+ case VK_J:
+ case VK_K:
+ case VK_L:
+ case VK_M:
+ case VK_N:
+ case VK_O:
+ case VK_P:
+ case VK_Q:
+ case VK_R:
+ case VK_S:
+ case VK_T:
+ case VK_U:
+ case VK_V:
+ case VK_W:
+ case VK_X:
+ case VK_Y:
+ case VK_Z:
+ */
+ case VK_OPEN_BRACKET:
+ return GDK_bracketleft;
+ case VK_BACK_SLASH:
+ return GDK_backslash;
+ case VK_CLOSE_BRACKET:
+ return GDK_bracketright;
+ case VK_NUMPAD0:
+ return GDK_KP_0;
+ case VK_NUMPAD1:
+ return GDK_KP_1;
+ case VK_NUMPAD2:
+ return GDK_KP_2;
+ case VK_NUMPAD3:
+ return GDK_KP_3;
+ case VK_NUMPAD4:
+ return GDK_KP_4;
+ case VK_NUMPAD5:
+ return GDK_KP_5;
+ case VK_NUMPAD6:
+ return GDK_KP_6;
+ case VK_NUMPAD7:
+ return GDK_KP_7;
+ case VK_NUMPAD8:
+ return GDK_KP_8;
+ case VK_NUMPAD9:
+ return GDK_KP_9;
+ case VK_MULTIPLY:
+ return GDK_KP_Multiply;
+ case VK_ADD:
+ return GDK_KP_Add;
+ /*
+ case VK_SEPARATER:
+ */
+ case VK_SEPARATOR:
+ return GDK_KP_Separator;
+ case VK_SUBTRACT:
+ return GDK_KP_Subtract;
+ case VK_DECIMAL:
+ return GDK_KP_Decimal;
+ case VK_DIVIDE:
+ return GDK_KP_Divide;
+ case VK_DELETE:
+ return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Delete : GDK_Delete;
+ case VK_NUM_LOCK:
+ return GDK_Num_Lock;
+ case VK_SCROLL_LOCK:
+ return GDK_Scroll_Lock;
+ case VK_F1:
+ return GDK_F1;
+ case VK_F2:
+ return GDK_F2;
+ case VK_F3:
+ return GDK_F3;
+ case VK_F4:
+ return GDK_F4;
+ case VK_F5:
+ return GDK_F5;
+ case VK_F6:
+ return GDK_F6;
+ case VK_F7:
+ return GDK_F7;
+ case VK_F8:
+ return GDK_F8;
+ case VK_F9:
+ return GDK_F9;
+ case VK_F10:
+ return GDK_F10;
+ case VK_F11:
+ return GDK_F11;
+ case VK_F12:
+ return GDK_F12;
+ case VK_F13:
+ return GDK_F13;
+ case VK_F14:
+ return GDK_F14;
+ case VK_F15:
+ return GDK_F15;
+ case VK_F16:
+ return GDK_F16;
+ case VK_F17:
+ return GDK_F17;
+ case VK_F18:
+ return GDK_F18;
+ case VK_F19:
+ return GDK_F19;
+ case VK_F20:
+ return GDK_F20;
+ case VK_F21:
+ return GDK_F21;
+ case VK_F22:
+ return GDK_F22;
+ case VK_F23:
+ return GDK_F23;
+ case VK_F24:
+ return GDK_F24;
+ case VK_PRINTSCREEN:
+ return GDK_Print;
+ case VK_INSERT:
+ return keyLocation == AWT_KEY_LOCATION_NUMPAD ? GDK_KP_Insert : GDK_Insert;
+ case VK_HELP:
+ return GDK_Help;
+ case VK_META:
+ return keyLocation == AWT_KEY_LOCATION_LEFT ? GDK_Meta_L : GDK_Meta_R;
+ case VK_BACK_QUOTE:
+ return GDK_grave;
+ case VK_QUOTE:
+ return GDK_apostrophe;
+ case VK_KP_UP:
+ return GDK_KP_Up;
+ case VK_KP_DOWN:
+ return GDK_KP_Down;
+ case VK_KP_LEFT:
+ return GDK_KP_Left;
+ case VK_KP_RIGHT:
+ return GDK_KP_Right;
+ case VK_DEAD_GRAVE:
+ return GDK_dead_grave;
+ case VK_DEAD_ACUTE:
+ return GDK_dead_acute;
+ case VK_DEAD_CIRCUMFLEX:
+ return GDK_dead_circumflex;
+ case VK_DEAD_TILDE:
+ return GDK_dead_tilde;
+ case VK_DEAD_MACRON:
+ return GDK_dead_macron;
+ case VK_DEAD_BREVE:
+ return GDK_dead_breve;
+ case VK_DEAD_ABOVEDOT:
+ return GDK_dead_abovedot;
+ case VK_DEAD_DIAERESIS:
+ return GDK_dead_diaeresis;
+ case VK_DEAD_ABOVERING:
+ return GDK_dead_abovering;
+ case VK_DEAD_DOUBLEACUTE:
+ return GDK_dead_doubleacute;
+ case VK_DEAD_CARON:
+ return GDK_dead_caron;
+ case VK_DEAD_CEDILLA:
+ return GDK_dead_cedilla;
+ case VK_DEAD_OGONEK:
+ return GDK_dead_ogonek;
+ case VK_DEAD_IOTA:
+ return GDK_dead_iota;
+ case VK_DEAD_VOICED_SOUND:
+ return GDK_dead_voiced_sound;
+ case VK_DEAD_SEMIVOICED_SOUND:
+ return GDK_dead_semivoiced_sound;
+ case VK_AMPERSAND:
+ return GDK_ampersand;
+ case VK_ASTERISK:
+ return GDK_asterisk;
+ case VK_QUOTEDBL:
+ return GDK_quotedbl;
+ case VK_LESS:
+ return GDK_less;
+ case VK_GREATER:
+ return GDK_greater;
+ case VK_BRACELEFT:
+ return GDK_braceleft;
+ case VK_BRACERIGHT:
+ return GDK_braceright;
+ case VK_AT:
+ return GDK_at;
+ case VK_COLON:
+ return GDK_colon;
+ case VK_CIRCUMFLEX:
+ return GDK_asciicircum;
+ case VK_DOLLAR:
+ return GDK_dollar;
+ case VK_EURO_SIGN:
+ return GDK_EuroSign;
+ case VK_EXCLAMATION_MARK:
+ return GDK_exclam;
+ case VK_INVERTED_EXCLAMATION_MARK:
+ return GDK_exclamdown;
+ case VK_LEFT_PARENTHESIS:
+ return GDK_parenleft;
+ case VK_NUMBER_SIGN:
+ return GDK_numbersign;
+ case VK_PLUS:
+ return GDK_plus;
+ case VK_RIGHT_PARENTHESIS:
+ return GDK_parenright;
+ case VK_UNDERSCORE:
+ return GDK_underscore;
+ /*
+ case VK_FINAL:
+ case VK_CONVERT:
+ case VK_NONCONVERT:
+ case VK_ACCEPT:
+ */
+ case VK_MODECHANGE:
+ return GDK_Mode_switch;
+ /*
+ case VK_KANA:
+ */
+ case VK_KANJI:
+ return GDK_Kanji;
+ /*
+ case VK_ALPHANUMERIC:
+ */
+ case VK_KATAKANA:
+ return GDK_Katakana;
+ case VK_HIRAGANA:
+ return GDK_Hiragana;
+ /*
+ case VK_FULL_WIDTH:
+ case VK_HALF_WIDTH:
+ case VK_ROMAN_CHARACTERS:
+ case VK_ALL_CANDIDATES:
+ */
+ case VK_PREVIOUS_CANDIDATE:
+ return GDK_PreviousCandidate;
+ case VK_CODE_INPUT:
+ return GDK_Codeinput;
+ /*
+ case VK_JAPANESE_KATAKANA:
+ case VK_JAPANESE_HIRAGANA:
+ case VK_JAPANESE_ROMAN:
+ */
+ case VK_KANA_LOCK:
+ return GDK_Kana_Lock;
+ /*
+ case VK_INPUT_METHOD_ON_OFF:
+ case VK_CUT:
+ case VK_COPY:
+ case VK_PASTE:
+ case VK_UNDO:
+ case VK_AGAIN:
+ case VK_FIND:
+ case VK_PROPS:
+ case VK_STOP:
+ case VK_COMPOSE:
+ case VK_ALT_GRAPH:
+ */
+ default:
+ return GDK_VoidSymbol;
+ }
+}
diff --git a/libjava/classpath/native/jni/gtk-peer/gthread-jni.c b/libjava/classpath/native/jni/gtk-peer/gthread-jni.c
new file mode 100644
index 00000000000..e673de07d27
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gthread-jni.c
@@ -0,0 +1,2592 @@
+/* gthread-jni.c -- JNI threading routines for GLIB
+ Copyright (C) 1998, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/************************************************************************/
+/* Header */
+/************************************************************************/
+
+/*
+ * @author Julian Dolby (dolby@us.ibm.com)
+ * @date February 7, 2003 implemented for GLIB v.1
+ *
+ *
+ * @author Steven Augart
+ * <steve+classpath at augart dot com>, <augart at watson dot ibm dot com>
+ * @date April 30, 2004 -- May 10 2004: Support new functions for Glib v.2,
+ * fix cond_wait to free and re-acquire the mutex,
+ * replaced trylock stub implementation with a full one.
+ *
+ * This code implements the GThreadFunctions interface for GLIB using
+ * Java threading primitives. All of the locking and conditional variable
+ * functionality required by GThreadFunctions is implemented using the
+ * monitor and wait/notify functionality of Java objects. The thread-
+ * local functionality uses the java.lang.ThreadLocal class.
+ *
+ * Classpath's AWT support uses GTK+ peers. GTK+ uses GLIB. GLIB by default
+ * uses the platform's native threading model -- pthreads in most cases. If
+ * the Java runtime doesn't use the native threading model, then it needs this
+ * code in order to use Classpath's (GTK+-based) AWT routines.
+ *
+ * This code should be portable; I believe it makes no assumptions
+ * about the underlying VM beyond that it implements the JNI functionality
+ * that this code uses.
+ *
+ * Currently, use of this code is governed by the configuration option
+ * --enable-portable-native-sync. We will soon add a VM hook so the VM can
+ * select which threading model it wants to use at run time; at that point,
+ * the configuration option will go away.
+ *
+ * The code in this file uses only JNI 1.1, except for one JNI 1.2 function:
+ * GetEnv, in the JNI Invocation API. (There seems to be no way around using
+ * GetEnv).
+ *
+ * ACKNOWLEDGEMENT:
+ *
+ * I would like to thank Mark Wielaard for his kindness in spending at least
+ * six hours of his own time in reviewing this code and correcting my GNU
+ * coding and commenting style. --Steve Augart
+ *
+ *
+ * NOTES:
+ *
+ * This code has been tested with Jikes RVM and with Kaffe.
+ *
+ * This code should have proper automated unit tests. I manually tested it
+ * by running an application that uses AWT. --Steven Augart
+ *
+ * MINOR NIT:
+ *
+ * - Using a jboolean in the arglist to "throw()" and "rethrow()"
+ * triggers many warnings from GCC's -Wconversion operation, because that
+ * is not the same as the conversion (upcast to an int) that would occur in
+ * the absence of a prototype.
+ *
+ * It would be very slightly more efficient to just pass the jboolean, but
+ * is not worth the clutter of messages. The right solution would be to
+ * turn off the -Wconversion warning for just this file, *except* that
+ * -Wconversion also warns you against constructs such as:
+ * unsigned u = -1;
+ * and that is a useful warning. So I went from a "jboolean" to a
+ * "gboolean" (-Wconversion is not enabled by default for GNU Classpath,
+ * but it is in my own CFLAGS, which, for gcc 3.3.3, read: -pipe -ggdb3 -W
+ * -Wall -Wbad-function-cast -Wcast-align -Wpointer-arith -Wcast-qual
+ * -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
+ * -fkeep-static-consts -fkeep-inline-functions -Wundef -Wwrite-strings
+ * -Wno-aggregate-return -Wmissing-noreturn -Wnested-externs -Wtrigraphs
+ * -Wconversion -Wsign-compare -Wno-float-equal -Wmissing-format-attribute
+ * -Wno-unreachable-code -Wdisabled-optimization )
+ */
+
+#include <config.h>
+
+/************************************************************************/
+/* Configuration */
+/************************************************************************/
+
+/** Tracing and Reporting **/
+#define TRACE_API_CALLS 0 /* announce entry and exit into each method,
+ by printing to stderr. */
+
+#define TRACE_MONITORS 0 /* Every enterMonitor() and exitMonitor() goes
+ to stderr. */
+
+/** Trouble handling. There is a discussion below of this. **/
+#define EXPLAIN_TROUBLE 1 /* Describe any unexpected trouble that
+ happens. This is a superset
+ of EXPLAIN_BROKEN, and if set trumps an
+ unset EXPLAIN_BROKEN. It is not a strict
+ superset, since at the moment there is no
+ TROUBLE that is not also BROKEN.
+
+ Use criticalMsg() to describe the problem.
+ */
+
+#define EXPLAIN_BROKEN 1 /* Describe trouble that is serious enough to
+ be BROKEN. (Right now all trouble is at
+ least BROKEN.) */
+
+/* There is no EXPLAIN_BADLY_BROKEN definition. We always explain
+ BADLY_BROKEN trouble, since there is no other way to report it. */
+
+
+/** Error Handling **/
+#define DIE_IF_BROKEN 1 /* Dies if serious trouble happens. There is
+ really no non-serious trouble, except
+ possibly problems that arise during
+ pthread_create, which are reported by a
+ GError.
+
+ If you do not set DIE_IF_BROKEN, then
+ trouble will raise a Java RuntimeException.
+ We probably do want to die right away,
+ since anything that's BROKEN really
+ indicates a programming error or a
+ system-wide error, and that's what the glib
+ documentation says you should do in case of
+ that kind of error in a glib-style
+ function. But it does work to turn this
+ off. */
+
+#if DIE_IF_BROKEN
+#define DIE_IF_BADLY_BROKEN 1 /* DIE_IF_BROKEN implies DIE_IF_BADLY_BROKEN */
+#else
+#define DIE_IF_BADLY_BROKEN 1 /* Die if the system is badly broken --
+ that is, if we have further trouble while
+ attempting to throw an exception
+ upwards, or if we are unable to generate
+ one of the classes we'll need in order to
+ throw wrapped exceptions upward.
+
+ If unset, we will print a warning message,
+ and limp along anyway. Not that the system
+ is likely to work. */
+#endif
+
+/** Performance tuning parameters **/
+
+#define ENABLE_EXPENSIVE_ASSERTIONS 0 /* Enable expensive assertions? */
+
+#define DELETE_LOCAL_REFS 1 /* Whether to delete local references.
+
+ JNI only guarantees that there wil be 16
+ available. (Jikes RVM provides an number
+ only limited by VM memory.)
+
+ Jikes RVM will probably perform faster if
+ this is turned off, but other VMs may need
+ this to be turned on in order to perform at
+ all, or might need it if things change.
+
+ Remember, we don't know how many of those
+ local refs might have already been used up
+ by higher layers of JNI code that end up
+ calling g_thread_self(),
+ g_thread_set_private(), and so on.
+
+ We set this to 1 for GNU Classpath, since
+ one of our principles is "always go for the
+ most robust implementation" */
+
+#define HAVE_JNI_VERSION_1_2 0 /* Assume we don't. We could
+ dynamically check for this. We will
+ assume JNI 1.2 in later versions of
+ Classpath.
+
+ As it stands, the code in this file
+ already needs one JNI 1.2 function:
+ GetEnv, in the JNI Invocation API.
+
+ TODO This code hasn't been tested yet.
+ And really hasn't been implemented yet.
+ */
+
+/************************************************************************/
+/* Global data */
+/************************************************************************/
+
+#if defined HAVE_STDINT_H
+#include <stdint.h> /* provides intptr_t */
+#elif defined HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include <stdarg.h> /* va_list */
+#include <glib.h>
+#include "gthread-jni.h"
+#include <assert.h> /* assert() */
+
+/* For Java thread priority constants. */
+#include <gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.h>
+
+/* Since not all JNI header generators actually define constants we
+ define them here explicitly. */
+#ifndef gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MIN_PRIORITY
+#define gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MIN_PRIORITY 1
+#endif
+#ifndef gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_NORM_PRIORITY
+#define gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_NORM_PRIORITY 5
+#endif
+#ifndef gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MAX_PRIORITY
+#define gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MAX_PRIORITY 10
+#endif
+
+/* The VM handle. This is set in
+ Java_gnu_java_awt_peer_gtk_GtkMainThread_gtkInit */
+JavaVM *cp_gtk_the_vm;
+
+/* Unions used for type punning. */
+union env_union
+{
+ void **void_env;
+ JNIEnv **jni_env;
+};
+
+union func_union
+{
+ void *void_func;
+ GThreadFunc g_func;
+};
+
+/* Forward Declarations for Functions */
+static int threadObj_set_priority (JNIEnv * env, jobject threadObj,
+ GThreadPriority gpriority);
+static void fatalMsg (const char fmt[], ...)
+ __attribute__ ((format (printf, 1, 2)))
+ __attribute__ ((noreturn));
+
+static void criticalMsg (const char fmt[], ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+static void tracing (const char fmt[], ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+static jint javaPriorityLevel (GThreadPriority priority)
+ __attribute__ ((const));
+
+/************************************************************************/
+/* Trouble-handling, including utilities to reflect exceptions */
+/* back to the VM. Also some status reporting. */
+/************************************************************************/
+
+/* How are we going to handle problems?
+
+ There are several approaches:
+
+ 1) Report them with the GError mechanism.
+
+ (*thread_create)() is the only one of these functions that takes a
+ GError pointer. And the only G_THREAD error defined maps onto EAGAIN.
+ We don't have any errors in our (*thread_create)() implementation that
+ can be mapped to EAGAIN. So this idea is a non-starter.
+
+ 2) Reflect the exception back to the VM, wrapped in a RuntimeException.
+ This will fail sometimes, if we're so broken (BADLY_BROKEN) that we
+ fail to throw the exception.
+
+ 3) Abort execution. This is what the glib functions themselves do for
+ errors that they can't report via GError.
+
+ Enable DIE_IF_BROKEN and/or DIE_IF_BADLY_BROKEN to
+ make this the default for BROKEN and/or BADLY_BROKEN trouble.
+
+ 4) Display messages to stderr. We always do this for BADLY_BROKEN
+ trouble. The glib functions do that for errors they can't report via
+ GError.
+
+ There are some complications.
+
+ When I attempted to report a problem in g_thread_self() using g_critical (a
+ macro around g_log(), I found that g_log in turn looks for thread-private
+ data and calls g_thread_self() again.
+
+ We got a segfault, probably due to stack overflow. So, this code doesn't
+ use the g_critical() and g_error() functions any more. Nor do we use
+ g_assert(); we use the C library's assert() instead.
+*/
+
+
+#define WHERE __FILE__ ":" G_STRINGIFY(__LINE__) ": "
+
+/* This is portable to older compilers that lack variable-argument macros.
+ This used to be just g_critical(), but then we ran into the error reporting
+ problem discussed above.
+*/
+static void
+fatalMsg (const char fmt[], ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+ fputs ("\nAborting execution\n", stderr);
+ abort ();
+}
+
+
+static void
+criticalMsg (const char fmt[], ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+ putc ('\n', stderr);
+}
+
+/* Unlike the other two, this one does not append a newline. This is only
+ used if one of the TRACE_ macros is defined. */
+static void
+tracing (const char fmt[], ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ vfprintf (stderr, fmt, ap);
+ va_end (ap);
+}
+
+#define assert_not_reached() \
+ do \
+ { \
+ fputs(WHERE "You should never get here. Aborting execution.\n", \
+ stderr); \
+ abort(); \
+ } \
+ while(0)
+
+
+#if DIE_IF_BADLY_BROKEN
+#define BADLY_BROKEN fatalMsg
+#else
+#define BADLY_BROKEN criticalMsg
+/* So, the user may still attempt to recover, even though we do not advise
+ this. */
+#endif
+
+/* I find it so depressing to have to use C without varargs macros. */
+#define BADLY_BROKEN_MSG WHERE "Something fundamental" \
+ " to GNU Classpath's AWT JNI broke while we were trying to pass up a Java error message"
+
+#define BADLY_BROKEN0() \
+ BADLY_BROKEN(BADLY_BROKEN_MSG);
+#define BADLY_BROKEN1(msg) \
+ BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg)
+#define BADLY_BROKEN2(msg, arg) \
+ BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg, arg)
+#define BADLY_BROKEN3(msg, arg, arg2) \
+ BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg, arg1, arg2)
+#define BADLY_BROKEN4(msg, arg, arg2, arg3) \
+ BADLY_BROKEN(BADLY_BROKEN_MSG ": " msg, arg1, arg2, arg3)
+
+#define DELETE_LOCAL_REF(env, ref) \
+ do \
+ { \
+ if ( DELETE_LOCAL_REFS ) \
+ { \
+ (*env)->DeleteLocalRef (env, ref); \
+ (ref) = NULL; \
+ } \
+ } \
+ while(0)
+
+/* Cached info for Exception-wrapping */
+
+static jclass runtimeException_class; /* java.lang.RuntimeException */
+static jmethodID runtimeException_ctor; /* constructor for it */
+
+
+/* Throw a new RuntimeException. It may wrap around an existing exception.
+ 1 if we did rethrow, -1 if we had trouble while rethrowing.
+ isBroken is always true in this case. */
+static int
+throw (JNIEnv * env, jthrowable cause, const char *message,
+ gboolean isBroken, const char *file, int line)
+{
+ jstring jmessage;
+ gboolean describedException = FALSE; /* Did we already describe the
+ exception to stderr or the
+ equivalent? */
+ jthrowable wrapper;
+
+ /* allocate local message in Java */
+ const char fmt[] = "In AWT JNI, %s (at %s:%d)";
+ size_t len = strlen (message) + strlen (file) + sizeof fmt + 25;
+ char *buf;
+
+ if (EXPLAIN_TROUBLE || (isBroken && EXPLAIN_BROKEN))
+ {
+ criticalMsg ("%s:%d: AWT JNI failure%s: %s\n", file, line,
+ isBroken ? " (BROKEN)" : "", message);
+ if (cause)
+ {
+ jthrowable currentException = (*env)->ExceptionOccurred (env);
+
+ if (cause == currentException)
+ {
+ criticalMsg ("Description follows to System.err:");
+ (*env)->ExceptionDescribe (env);
+ /* ExceptionDescribe has the side-effect of clearing the pending
+ exception; relaunch it. */
+ describedException = TRUE;
+
+ if ((*env)->Throw (env, cause))
+ {
+ BADLY_BROKEN1
+ ("Relaunching an exception with Throw failed.");
+ return -1;
+ }
+ }
+ else
+ {
+ DELETE_LOCAL_REF (env, currentException);
+ criticalMsg (WHERE
+ "currentException != cause; something else happened"
+ " while handling an exception.");
+ }
+ }
+ } /* if (EXPLAIN_TROUBLE) */
+
+ if (isBroken && DIE_IF_BROKEN)
+ fatalMsg ("%s:%d: Aborting execution; BROKEN: %s\n", file, line, message);
+
+ if ((buf = malloc (len)))
+ {
+ memset (buf, 0, len);
+ g_snprintf (buf, len, fmt, message, file, line);
+ jmessage = (*env)->NewStringUTF (env, buf);
+ free (buf);
+ }
+ else
+ {
+ jmessage = NULL;
+ }
+
+ /* Create the RuntimeException wrapper object and throw it. It is OK for
+ CAUSE to be NULL. */
+ wrapper = (jthrowable) (*env)->NewObject
+ (env, runtimeException_class, runtimeException_ctor, jmessage, cause);
+ DELETE_LOCAL_REF (env, jmessage);
+
+ if (!wrapper)
+ {
+ /* I think this should only happen:
+ - if there are bugs in my JNI code, or
+ - if the VM is broken, or
+ - if we run out of memory.
+ */
+ if (EXPLAIN_TROUBLE)
+ {
+ criticalMsg (WHERE "GNU Classpath: JNI NewObject() could not create"
+ " a new java.lang.RuntimeException.");
+ criticalMsg ("We were trying to warn about the following"
+ " previous failure:");
+ criticalMsg ("%s:%d: %s", file, line, message);
+ criticalMsg ("The latest (NewObject()) exception's description"
+ " follows, to System.err:");
+ (*env)->ExceptionDescribe (env);
+ }
+ BADLY_BROKEN1 ("Failure of JNI NewObject()"
+ " to make a java.lang.RuntimeException");
+ return -1;
+ }
+
+
+ /* throw it */
+ if ((*env)->Throw (env, wrapper))
+ {
+ /* Throw() should just never fail, unless we're in such severe trouble
+ that we might as well die. */
+ BADLY_BROKEN1
+ ("GNU Classpath: Failure of JNI Throw to report an Exception");
+ return -1;
+ }
+
+ DELETE_LOCAL_REF (env, wrapper);
+ return 1;
+}
+
+
+
+/* Rethrow an exception we received, wrapping it with a RuntimeException. 1
+ if we did rethrow, -1 if we had trouble while rethrowing.
+ CAUSE should be identical to the most recent exception that happened, so
+ that ExceptionDescribe will work. (Otherwise nix.) */
+static int
+rethrow (JNIEnv * env, jthrowable cause, const char *message,
+ gboolean isBroken, const char *file, int line)
+{
+ assert (cause);
+ return throw (env, cause, message, isBroken, file, line);
+}
+
+
+/* This function checks for a pending exception, and rethrows it with
+ * a wrapper RuntimeException to deal with possible type problems (in
+ * case some calling piece of code does not expect the exception being
+ * thrown) and to include the given extra message.
+ *
+ * Returns 0 if no problems found (so no exception thrown), 1 if we rethrew an
+ * exception. Returns -1 on failure.
+ */
+static int
+maybe_rethrow (JNIEnv * env, const char *message, gboolean isBroken,
+ const char *file, int line)
+{
+ jthrowable cause = (*env)->ExceptionOccurred (env);
+ int ret = 0;
+
+ /* rethrow if an exception happened */
+ if (cause)
+ {
+ ret = rethrow (env, cause, message, isBroken, file, line);
+ DELETE_LOCAL_REF (env, cause);
+ }
+
+ return 0;
+}
+
+/* MAYBE_TROUBLE() is used to include a source location in the exception
+ message. Once we have run maybe_rethrow, if there WAS trouble,
+ return TRUE, else FALSE.
+
+ MAYBE_TROUBLE() is actually never used; all problems that throw exceptions
+ are BROKEN, at least. Nothing is recoverable :(. See the discussion of
+ possible errors at thread_create_jni_impl(). */
+#define MAYBE_TROUBLE(_env, _message) \
+ maybe_rethrow(_env, _message, FALSE, __FILE__, __LINE__)
+
+/* MAYBE_TROUBLE(), but something would be BROKEN if it were true. */
+#define MAYBE_BROKEN(_env, _message) \
+ maybe_rethrow(_env, _message, TRUE, __FILE__, __LINE__)
+
+/* Like MAYBE_TROUBLE(), TROUBLE() is never used. */
+#define TROUBLE(_env, _message) \
+ rethrow(_env, (*env)->ExceptionOccurred (env), _message, FALSE, \
+ __FILE__, __LINE__)
+
+#define BROKEN(_env, _message) \
+ rethrow (_env, (*env)->ExceptionOccurred (env), _message, TRUE, \
+ __FILE__, __LINE__)
+
+/* Like MAYBE_TROUBLE(), NEW_TROUBLE() is never used. */
+#define NEW_TROUBLE(_env, _message) \
+ throw (_env, NULL, _message, FALSE, __FILE__, __LINE__)
+
+#define NEW_BROKEN(_env, _message) \
+ throw (_env, NULL, _message, TRUE, __FILE__, __LINE__)
+
+/* Like MAYBE_TROUBLE(), RETHROW_CAUSE() is never used. */
+#define RETHROW_CAUSE(_env, _cause, _message) \
+ rethrow (_env, _cause, _message, FALSE, __FILE__, __LINE__)
+
+#define BROKEN_CAUSE(_env, _cause, _message) \
+ rethrow (_env, _cause, _message, TRUE, __FILE__, __LINE__)
+
+/* Macros to handle the possibility that someone might have called one of the
+ GThreadFunctions API functions with a Java exception pending. It is
+ generally discouraged to continue to use JNI after a Java exception has
+ been raised. Sun's JNI book advises that one trap JNI errors immediately
+ and not continue with an exception pending.
+
+ These are #if'd out for these reasons:
+
+ 1) They do not work in the C '89 subset that Classpath is currently
+ (2004 May 10) sticking to; HIDE_OLD_TROUBLE() includes a declaration
+ that should be in scope for the rest of the function, so it needs a
+ language version that lets you mix declarations and statements. (This
+ could be worked around if it were important.)
+
+ 2) They chew up more time and resources.
+
+ 3) There does not ever seem to be old trouble -- the assertion in
+ HIDE_OLD_TROUBLE never goes off.
+
+ You will want to re-enable them if this code needs to be used in a context
+ where old exceptions might be pending when the GThread functions are
+ called.
+
+ The implementations in this file are responsible for skipping around calls
+ to SHOW_OLD_TROUBLE() if they've raised exceptions during the call. So, if
+ we reach SHOW_OLD_TROUBLE, we are guaranteed that there are no exceptions
+ pending. */
+#if 1
+#define HIDE_OLD_TROUBLE(env) \
+ assert ( NULL == (*env)->ExceptionOccurred (env) )
+
+#define SHOW_OLD_TROUBLE() \
+ assert ( NULL == (*env)->ExceptionOccurred (env) )
+#else /* 0 */
+#define HIDE_OLD_TROUBLE(env) \
+ jthrowable savedTrouble = (*env)->ExceptionOccurred (env); \
+ (*env)->ExceptionClear (env);
+
+#define SHOW_OLD_TROUBLE() do \
+{ \
+ assert ( NULL == (*env)->ExceptionOccurred (env) ) \
+ if (savedTrouble) \
+ { \
+ if ((*env)->Throw (env, savedTrouble)) \
+ BADLY_BROKEN ("ReThrowing the savedTrouble failed"); \
+ } \
+ DELETE_LOCAL_REF (env, savedTrouble); \
+} while(0)
+
+#endif /* 0 */
+
+/* Set up the cache of jclass and jmethodID primitives we need
+ in order to throw new exceptions and rethrow exceptions. We do this
+ independently of the other caching. We need to have this cache set up
+ first, so that we can then report errors properly.
+
+ If any errors while setting up the error cache, the world is BADLY_BROKEN.
+
+ May be called more than once.
+
+ Returns -1 if the cache was not initialized properly, 1 if it was.
+*/
+static int
+setup_exception_cache (JNIEnv * env)
+{
+ static int exception_cache_initialized = 0; /* -1 for trouble, 1 for proper
+ init. */
+
+ jclass lcl_class; /* a class used for local refs */
+
+ if (exception_cache_initialized)
+ return exception_cache_initialized;
+ lcl_class = (*env)->FindClass (env, "java/lang/RuntimeException");
+ if ( ! lcl_class )
+ {
+ BADLY_BROKEN1 ("Broken Class library or VM?"
+ " Couldn't find java/lang/RuntimeException");
+ return exception_cache_initialized = -1;
+ }
+ /* Pin it down. */
+ runtimeException_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+ DELETE_LOCAL_REF (env, lcl_class);
+ if (!runtimeException_class)
+ {
+ BADLY_BROKEN1 ("Serious trouble: could not turn"
+ " java.lang.RuntimeException into a global reference");
+ return exception_cache_initialized = -1;
+ }
+
+ runtimeException_ctor =
+ (*env)->GetMethodID (env, runtimeException_class, "<init>",
+ "(Ljava/lang/String;Ljava/lang/Throwable;)V");
+ if ( ! runtimeException_ctor )
+ {
+ BADLY_BROKEN1 ("Serious trouble: classpath couldn't find a"
+ " two-arg constructor for java/lang/RuntimeException");
+ return exception_cache_initialized = -1;
+ }
+
+ return exception_cache_initialized = 1;
+}
+
+
+/**********************************************************/
+/***** The main cache *************************************/
+/**********************************************************/
+
+/** This is a cache of all classes, methods, and field IDs that we use during
+ the run. We maintain a permanent global reference to each of the classes
+ we cache, since otherwise the (local) jclass that refers to that class
+ would go out of scope and possibly be reused in further calls.
+
+ The permanent global reference also achieves the secondary goal of
+ protecting the validity of the methods and field IDs in case the classes
+ were otherwise unloaded and then later loaded again. Obviously, this will
+ never happen to classes such as java.lang.Thread and java.lang.Object, but
+ the primary reason for maintaining permanent global refs is sitll valid.
+
+ The code in jnilink.c has a similar objective. TODO: Consider using that
+ code instead.
+
+ --Steven Augart
+*/
+
+/* All of these are cached classes and method IDs: */
+/* java.lang.Object */
+static jclass obj_class; /* java.lang.Object */
+static jmethodID obj_ctor; /* no-arg Constructor for java.lang.Object */
+static jmethodID obj_notify_mth; /* java.lang.Object.notify() */
+static jmethodID obj_notifyall_mth; /* java.lang.Object.notifyall() */
+static jmethodID obj_wait_mth; /* java.lang.Object.wait() */
+static jmethodID obj_wait_nanotime_mth; /* java.lang.Object.wait(JI) */
+
+/* GThreadMutex and its methods */
+static jclass mutex_class;
+static jmethodID mutex_ctor;
+static jfieldID mutex_lockForPotentialLockers_fld;
+static jfieldID mutex_potentialLockers_fld;
+
+/* java.lang.Thread and its methods*/
+static jclass thread_class; /* java.lang.Thread */
+static jmethodID thread_current_mth; /* Thread.currentThread() */
+static jmethodID thread_equals_mth; /* Thread.equals() */
+static jmethodID thread_join_mth; /* Thread.join() */
+static jmethodID thread_setPriority_mth; /* Thread.setPriority() */
+static jmethodID thread_stop_mth; /* Thread.stop() */
+static jmethodID thread_yield_mth; /* Thread.yield() */
+
+/* java.lang.ThreadLocal and its methods */
+static jclass threadlocal_class; /* java.lang.ThreadLocal */
+static jmethodID threadlocal_ctor; /* Its constructor */
+static jmethodID threadlocal_set_mth; /* ThreadLocal.set() */
+static jmethodID threadlocal_get_mth; /* ThreadLocal.get() */
+
+/* java.lang.Long and its methods */
+static jclass long_class; /* java.lang.Long */
+static jmethodID long_ctor; /* constructor for it: (J) */
+static jmethodID long_longValue_mth; /* longValue()J */
+
+
+/* GThreadNativeMethodRunner */
+static jclass runner_class;
+static jmethodID runner_ctor;
+static jmethodID runner_threadToThreadID_mth;
+static jmethodID runner_threadIDToThread_mth;
+static jmethodID runner_deRegisterJoinable_mth;
+static jmethodID runner_start_mth; /* Inherited Thread.start() */
+
+
+/* java.lang.InterruptedException */
+static jclass interrupted_exception_class;
+
+
+
+
+/* Returns a negative value if there was trouble during initialization.
+ Returns a positive value of the cache was initialized correctly.
+ Never returns zero. */
+static int
+setup_cache (JNIEnv * env)
+{
+ jclass lcl_class;
+ static int initialized = 0; /* 1 means initialized, 0 means uninitialized,
+ -1 means mis-initialized */
+
+ if (initialized)
+ return initialized;
+
+ /* make sure we can report on trouble */
+ if (setup_exception_cache (env) < 0)
+ return initialized = -1;
+
+#ifdef JNI_VERSION_1_2
+ if (HAVE_JNI_VERSION_1_2)
+ assert ( ! (*env)->ExceptionCheck (env));
+ else
+#endif
+ assert ( ! (*env)->ExceptionOccurred (env));
+
+ /* java.lang.Object and its methods */
+ lcl_class = (*env)->FindClass (env, "java/lang/Object");
+ if (!lcl_class)
+ {
+ BROKEN (env, "cannot find java.lang.Object");
+ return initialized = -1;
+ }
+
+ /* Pin it down. */
+ obj_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+ DELETE_LOCAL_REF (env, lcl_class);
+ if (!obj_class)
+ {
+ BROKEN (env, "Cannot get a global reference to java.lang.Object");
+ return initialized = -1;
+ }
+
+ obj_ctor = (*env)->GetMethodID (env, obj_class, "<init>", "()V");
+ if (!obj_ctor)
+ {
+ BROKEN (env, "cannot find constructor for java.lang.Object");
+ return initialized = -1;
+ }
+
+ obj_notify_mth = (*env)->GetMethodID (env, obj_class, "notify", "()V");
+ if ( ! obj_notify_mth )
+ {
+ BROKEN (env, "cannot find java.lang.Object.notify()V");
+ return initialized = -1;
+ }
+
+ obj_notifyall_mth =
+ (*env)->GetMethodID (env, obj_class, "notifyAll", "()V");
+ if ( ! obj_notifyall_mth)
+ {
+ BROKEN (env, "cannot find java.lang.Object.notifyall()V");
+ return initialized = -1;
+ }
+
+ obj_wait_mth = (*env)->GetMethodID (env, obj_class, "wait", "()V");
+ if ( ! obj_wait_mth )
+ {
+ BROKEN (env, "cannot find Object.<wait()V>");
+ return initialized = -1;
+ }
+
+ obj_wait_nanotime_mth =
+ (*env)->GetMethodID (env, obj_class, "wait", "(JI)V");
+ if ( ! obj_wait_nanotime_mth )
+ {
+ BROKEN (env, "cannot find Object.<wait(JI)V>");
+ return initialized = -1;
+ }
+
+ /* GThreadMutex and its methods */
+ lcl_class = (*env)->FindClass (env, "gnu/java/awt/peer/gtk/GThreadMutex");
+ if ( ! lcl_class)
+ {
+ BROKEN (env, "cannot find gnu.java.awt.peer.gtk.GThreadMutex");
+ return initialized = -1;
+ }
+ /* Pin it down. */
+ mutex_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+ DELETE_LOCAL_REF (env, lcl_class);
+ if ( ! mutex_class)
+ {
+ BROKEN (env, "Cannot get a global reference to GThreadMutex");
+ return initialized = -1;
+ }
+
+ mutex_ctor = (*env)->GetMethodID (env, mutex_class, "<init>", "()V");
+ if ( ! mutex_ctor)
+ {
+ BROKEN (env, "cannot find zero-arg constructor for GThreadMutex");
+ return initialized = -1;
+ }
+
+ mutex_potentialLockers_fld = (*env)->GetFieldID
+ (env, mutex_class, "potentialLockers", "I");
+ if ( ! mutex_class )
+ {
+ BROKEN (env, "cannot find GThreadMutex.potentialLockers");
+ return initialized = -1;
+ }
+
+ if (! (mutex_lockForPotentialLockers_fld = (*env)->GetFieldID
+ (env, mutex_class, "lockForPotentialLockers", "Ljava/lang/Object;")))
+ {
+ BROKEN (env, "cannot find GThreadMutex.lockForPotentialLockers");
+ return initialized = -1;
+ }
+
+
+ /* java.lang.Thread */
+ if (! (lcl_class = (*env)->FindClass (env, "java/lang/Thread")))
+ {
+ BROKEN (env, "cannot find java.lang.Thread");
+ return initialized = -1;
+ }
+
+ /* Pin it down. */
+ thread_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+ DELETE_LOCAL_REF (env, lcl_class);
+ if (!thread_class)
+ {
+ BROKEN (env, "Cannot get a global reference to java.lang.Thread");
+ return initialized = -1;
+ }
+
+ thread_current_mth =
+ (*env)->GetStaticMethodID (env, thread_class, "currentThread",
+ "()Ljava/lang/Thread;");
+ if (!thread_current_mth)
+ {
+ BROKEN (env, "cannot find Thread.currentThread() method");
+ return initialized = -1;
+ }
+
+ thread_equals_mth =
+ (*env)->GetMethodID (env, thread_class, "equals", "(Ljava/lang/Object;)Z");
+ if (!thread_equals_mth)
+ {
+ BROKEN (env, "cannot find Thread.equals() method");
+ return initialized = -1;
+ }
+
+ thread_join_mth = (*env)->GetMethodID (env, thread_class, "join", "()V");
+ if (!thread_join_mth)
+ {
+ BROKEN (env, "cannot find Thread.join() method");
+ return initialized = -1;
+ }
+
+ thread_stop_mth = (*env)->GetMethodID (env, thread_class, "stop", "()V");
+ if ( ! thread_stop_mth )
+ {
+ BROKEN (env, "cannot find Thread.stop() method");
+ return initialized = -1;
+ }
+
+ thread_setPriority_mth =
+ (*env)->GetMethodID (env, thread_class, "setPriority", "(I)V");
+ if ( ! thread_setPriority_mth )
+ {
+ BROKEN (env, "cannot find Thread.setPriority() method");
+ return initialized = -1;
+ }
+
+ thread_yield_mth =
+ (*env)->GetStaticMethodID (env, thread_class, "yield", "()V");
+ if ( ! thread_yield_mth )
+ {
+ BROKEN (env, "cannot find Thread.yield() method");
+ return initialized = -1;
+ }
+
+ /* java.lang.ThreadLocal */
+ lcl_class = (*env)->FindClass (env, "java/lang/ThreadLocal");
+ if ( ! lcl_class )
+ {
+ BROKEN (env, "cannot find class java.lang.ThreadLocal");
+ return initialized = -1;
+ }
+
+ /* Pin it down. */
+ threadlocal_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+ DELETE_LOCAL_REF (env, lcl_class);
+ if ( ! threadlocal_class )
+ {
+ BROKEN (env, "Cannot get a global reference to java.lang.ThreadLocal");
+ return initialized = -1;
+ }
+
+ threadlocal_ctor = (*env)->GetMethodID (env, threadlocal_class,
+ "<init>", "()V");
+ if ( ! threadlocal_ctor )
+ {
+ BROKEN (env, "cannot find ThreadLocal.<init>()V");
+ return initialized = -1;
+ }
+
+ threadlocal_get_mth = (*env)->GetMethodID (env, threadlocal_class,
+ "get", "()Ljava/lang/Object;");
+ if ( ! threadlocal_get_mth )
+ {
+ BROKEN (env, "cannot find java.lang.ThreadLocal.get()Object");
+ return initialized = -1;
+ }
+
+ threadlocal_set_mth = (*env)->GetMethodID (env, threadlocal_class,
+ "set", "(Ljava/lang/Object;)V");
+ if ( ! threadlocal_set_mth )
+ {
+ BROKEN (env, "cannot find ThreadLocal.set(Object)V");
+ return initialized = -1;
+ }
+
+ /* java.lang.Long */
+ lcl_class = (*env)->FindClass (env, "java/lang/Long");
+ if ( ! lcl_class )
+ {
+ BROKEN (env, "cannot find class java.lang.Long");
+ return initialized = -1;
+ }
+
+ /* Pin it down. */
+ long_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+ DELETE_LOCAL_REF (env, lcl_class);
+ if (!long_class)
+ {
+ BROKEN (env, "Cannot get a global reference to java.lang.Long");
+ return initialized = -1;
+ }
+
+ long_ctor = (*env)->GetMethodID (env, long_class, "<init>", "(J)V");
+ if (!long_ctor)
+ {
+ BROKEN (env, "cannot find method java.lang.Long.<init>(J)V");
+ return initialized = -1;
+ }
+
+ long_longValue_mth =
+ (*env)->GetMethodID (env, long_class, "longValue", "()J");
+ if (!long_longValue_mth)
+ {
+ BROKEN (env, "cannot find method java.lang.Long.longValue()J");
+ return initialized = -1;
+ }
+
+
+ /* GThreadNativeMethodRunner */
+ lcl_class =
+ (*env)->FindClass (env,
+ "gnu/java/awt/peer/gtk/GThreadNativeMethodRunner");
+ if ( ! lcl_class )
+ {
+ BROKEN (env,
+ "cannot find gnu.java.awt.peer.gtk.GThreadNativeMethodRunner");
+ return initialized = -1;
+ }
+
+ /* Pin it down. */
+ runner_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+ DELETE_LOCAL_REF (env, lcl_class);
+ if (!runner_class)
+ {
+ BROKEN (env,
+ "Cannot get a global reference to the class GThreadNativeMethodRunner");
+ return initialized = -1;
+ }
+
+ runner_ctor = (*env)->GetMethodID (env, runner_class, "<init>", "(JJZ)V");
+ if ( ! runner_ctor )
+ {
+ BROKEN (env,
+ "cannot find method GThreadNativeMethodRunner.<init>(JJZ)");
+ return initialized = -1;
+ }
+
+ runner_start_mth = (*env)->GetMethodID (env, runner_class, "start", "()V");
+ if ( ! runner_start_mth )
+ {
+ BROKEN (env, "cannot find method GThreadNativeMethodRunner.start()V");
+ return initialized = -1;
+ }
+
+
+ runner_threadToThreadID_mth =
+ (*env)->GetStaticMethodID (env, runner_class,
+ "threadToThreadID", "(Ljava/lang/Thread;)I");
+ if ( ! runner_threadToThreadID_mth )
+ {
+ BROKEN (env,
+ "cannot find method GThreadNativeMethodRunner.threadToThreadID(java.lang.Thread)I");
+ return initialized = -1;
+ }
+
+
+ runner_threadIDToThread_mth =
+ (*env)->GetStaticMethodID (env, runner_class,
+ "threadIDToThread", "(I)Ljava/lang/Thread;");
+ if ( ! runner_threadIDToThread_mth )
+ {
+ BROKEN (env,
+ "cannot find method GThreadNativeMethodRunner.threadIDToThread(I)java.lang.Thread");
+ return initialized = -1;
+ }
+
+
+ runner_deRegisterJoinable_mth =
+ (*env)->GetStaticMethodID (env, runner_class, "deRegisterJoinable",
+ "(Ljava/lang/Thread;)V");
+ if (!runner_deRegisterJoinable_mth)
+ {
+ BROKEN (env,
+ "cannot find method GThreadNativeMethodRunner.deRegisterJoinable(java.lang.Thread)V");
+ return initialized = -1;
+ }
+
+
+ /* java.lang.InterruptedException */
+ lcl_class = (*env)->FindClass (env, "java/lang/InterruptedException");
+ if ( ! lcl_class )
+ {
+ BROKEN (env, "cannot find class java.lang.InterruptedException");
+ return initialized = -1;
+ }
+
+ /* Pin it down. */
+ interrupted_exception_class = (jclass) (*env)->NewGlobalRef (env, lcl_class);
+ DELETE_LOCAL_REF (env, lcl_class);
+ if (!interrupted_exception_class)
+ {
+ BROKEN (env, "Cannot make a global reference"
+ " to java.lang.InterruptedException");
+ return initialized = -1;
+ }
+
+#ifdef JNI_VERSION_1_2
+ if (HAVE_JNI_VERSION_1_2)
+ assert ( ! (*env)->ExceptionCheck (env));
+ else
+#endif
+ assert ( ! (*env)->ExceptionOccurred (env));
+
+
+ return initialized = 1;
+}
+
+
+
+
+
+/************************************************************************/
+/* Utilities to allocate and free java.lang.Objects */
+/************************************************************************/
+
+/* The condition variables are java.lang.Object objects,
+ * which this method allocates and returns a global ref. Note that global
+ * refs must be explicitly freed (isn't C fun?).
+ */
+static jobject
+allocatePlainObject (JNIEnv * env)
+{
+ jobject lcl_obj, global_obj;
+
+ lcl_obj = (*env)->NewObject (env, obj_class, obj_ctor);
+ if (!lcl_obj)
+ {
+ BROKEN (env, "cannot allocate object");
+ return NULL;
+ }
+
+ global_obj = (*env)->NewGlobalRef (env, lcl_obj);
+ DELETE_LOCAL_REF (env, lcl_obj);
+ if (!global_obj)
+ {
+ NEW_BROKEN (env, "cannot make global ref for a new plain Java object");
+ /* Deliberate fall-through */
+ }
+
+ return global_obj;
+}
+
+/* Frees any Java object given a global ref (isn't C fun?) */
+static void
+freeObject (JNIEnv * env, jobject obj)
+{
+ if (obj)
+ {
+ (*env)->DeleteGlobalRef (env, obj);
+ /* DeleteGlobalRef can never fail */
+ }
+}
+
+
+/************************************************************************/
+/* Utilities to allocate and free Java mutexes */
+/************************************************************************/
+
+/* The mutexes are gnu.java.awt.peer.gtk.GThreadMutex objects,
+ * which this method allocates and returns a global ref. Note that global
+ * refs must be explicitly freed (isn't C fun?).
+ *
+ * Free this with freeObject()
+ */
+static jobject
+allocateMutexObject (JNIEnv * env)
+{
+ jobject lcl_obj, global_obj;
+
+ lcl_obj = (*env)->NewObject (env, mutex_class, mutex_ctor);
+ if (!lcl_obj)
+ {
+ BROKEN (env, "cannot allocate a GThreadMutex");
+ return NULL;
+ }
+
+ global_obj = (*env)->NewGlobalRef (env, lcl_obj);
+ DELETE_LOCAL_REF (env, lcl_obj);
+ if (!global_obj)
+ {
+ NEW_BROKEN (env, "cannot make global ref");
+ /* Deliberate fallthrough */
+ }
+
+ return global_obj;
+}
+
+
+/************************************************************************/
+/* Locking code */
+/************************************************************************/
+
+/* Lock a Java object */
+#define ENTER_MONITOR(env, m) \
+ enterMonitor(env, m, G_STRINGIFY(m))
+
+/* Return -1 on failure, 0 on success. */
+static int
+enterMonitor (JNIEnv * env, jobject monitorObj, const char monName[])
+{
+ if (TRACE_MONITORS)
+ tracing (" <MonitorEnter(%s)>", monName);
+ assert (monitorObj);
+ if ((*env)->MonitorEnter (env, monitorObj) < 0)
+ {
+ BROKEN (env, "cannot enter monitor");
+ return -1;
+ }
+ return 0;
+}
+
+
+/* Unlock a Java object */
+#define EXIT_MONITOR(env, m) \
+ exitMonitor(env, m, G_STRINGIFY(m))
+
+static int
+exitMonitor (JNIEnv * env, jobject mutexObj, const char monName[])
+{
+ if (TRACE_MONITORS)
+ tracing (" <MonitorExit(%s)>", monName);
+ assert (mutexObj);
+ if ((*env)->MonitorExit (env, mutexObj) < 0)
+ {
+ BROKEN (env, "cannot exit monitor ");
+ return -1;
+ }
+ return 0;
+}
+
+
+/************************************************************************/
+/* Miscellaneous utilities */
+/************************************************************************/
+
+/* Get the Java Thread object that corresponds to a particular thread ID.
+ A negative thread Id gives us a null object.
+
+ Returns a local reference.
+*/
+static jobject
+getThreadFromThreadID (JNIEnv * env, gpointer gThreadID)
+{
+ jint threadNum = (jint) gThreadID;
+ jobject thread;
+
+ if (threadNum < 0)
+ {
+ NEW_BROKEN (env, "getThreadFromThreadID asked to look up"
+ " a negative thread index");
+ return NULL;
+ }
+
+ thread = (*env)->CallStaticObjectMethod
+ (env, runner_class, runner_threadIDToThread_mth, threadNum);
+
+ if (MAYBE_BROKEN (env, "cannot get Thread for threadID "))
+ return NULL;
+
+ return thread;
+}
+
+/** Return the unique threadID of THREAD.
+
+ Error handling: Return (gpointer) -1 on all failures,
+ and propagate an exception.
+*/
+static gpointer
+getThreadIDFromThread (JNIEnv * env, jobject thread)
+{
+ jint threadNum;
+
+ if (ENABLE_EXPENSIVE_ASSERTIONS)
+ assert ((*env)->IsInstanceOf (env, thread, thread_class));
+
+ HIDE_OLD_TROUBLE (env);
+
+ threadNum = (*env)->CallStaticIntMethod
+ (env, runner_class, runner_threadToThreadID_mth, thread);
+
+ if (MAYBE_BROKEN (env, "cannot get ThreadID for a Thread "))
+ {
+ threadNum = -1;
+ goto done;
+ }
+
+
+ SHOW_OLD_TROUBLE ();
+
+done:
+ return (gpointer) threadNum;
+}
+
+
+/************************************************************************/
+/* The Actual JNI functions that we pass to the function vector. */
+/************************************************************************/
+
+
+/************************************************************************/
+/* Mutex Functions */
+/************************************************************************/
+
+/*** Mutex Utilities ****/
+struct mutexObj_cache
+{
+ jobject lockForPotentialLockersObj; /* Lock for the potentialLockers
+ field. Local reference. */
+ jobject lockObj; /* The real lock we use. This is a GLOBAL
+ reference and must not be freed. */
+};
+
+/* Initialize the cache of sub-locks for a particular mutex object.
+
+ -1 on error, 0 on success. The caller is not responsible for freeing the
+ partially-populated cache in case of failure (but in practice does anyway)
+ (This actually never fails, though, since GetObjectField allegedly never
+ fails.)
+
+ Guaranteed to leave all fields of the cache initialized, even if only to
+ zero.
+*/
+static int
+populate_mutexObj_cache (JNIEnv * env, jobject mutexObj,
+ struct mutexObj_cache *mcache)
+{
+ mcache->lockObj = mutexObj; /* the mutexObj is its own lock. */
+ assert (mcache->lockObj);
+
+ mcache->lockForPotentialLockersObj = (*env)->GetObjectField
+ (env, mutexObj, mutex_lockForPotentialLockers_fld);
+ /* GetObjectField can never fail. */
+
+ /* Retrieving a NULL object could only happen if we somehow got a
+ a mutex object that was not properly intialized. */
+ assert (mcache->lockForPotentialLockersObj);
+
+ return 0;
+}
+
+
+/* Clean out the mutexObj_cache, even if it was never populated. */
+static void
+clean_mutexObj_cache (JNIEnv * env, struct mutexObj_cache *mcache)
+{
+ /* OK to pass NULL refs to DELETE_LOCAL_REF */
+ DELETE_LOCAL_REF (env, mcache->lockForPotentialLockersObj);
+ /* mcache->lockObj is a GLOBAL reference. */
+ mcache->lockObj = NULL;
+}
+
+/* -1 on failure, 0 on success.
+ The mutexObj_cache is already populated for this particular object. */
+static int
+mutexObj_lock (JNIEnv * env, jobject mutexObj, struct mutexObj_cache *mcache)
+{
+ jint potentialLockers;
+
+ if (ENTER_MONITOR (env, mcache->lockForPotentialLockersObj))
+ return -1;
+
+ assert(mutexObj);
+ potentialLockers =
+ (*env)->GetIntField (env, mutexObj, mutex_potentialLockers_fld);
+ /* GetIntField() never fails. */
+
+ ++potentialLockers;
+
+ (*env)->SetIntField
+ (env, mutexObj, mutex_potentialLockers_fld, potentialLockers);
+
+ if (EXIT_MONITOR (env, mcache->lockForPotentialLockersObj))
+ return -1;
+
+ if (ENTER_MONITOR (env, mcache->lockObj))
+ return -1;
+
+ SHOW_OLD_TROUBLE ();
+
+ return 0;
+}
+
+/* Unlock a GMutex, once we're already in JNI and have already gotten the
+ mutexObj for it. This skips the messages that TRACE_API_CALLS would
+ print.
+
+ Returns -1 on error, 0 on success. */
+static int
+mutexObj_unlock (JNIEnv * env, jobject mutexObj,
+ struct mutexObj_cache *mcache)
+{
+ jint potentialLockers;
+ int ret = -1; /* assume failure until we suceed. */
+
+ /* Free the lock first, so that someone waiting for the lock can get it
+ ASAP. */
+ /* This is guaranteed not to block. */
+ if (EXIT_MONITOR (env, mcache->lockObj) < 0)
+ goto done;
+
+ /* Kick down potentialLockers by one. We do this AFTER we free the lock, so
+ that we hold it no longer than necessary. */
+ if (ENTER_MONITOR (env, mcache->lockForPotentialLockersObj) < 0)
+ goto done;
+
+ potentialLockers = (*env)->GetIntField
+ (env, mutexObj, mutex_potentialLockers_fld);
+ /* GetIntField never fails */
+
+ assert (potentialLockers >= 1);
+ --potentialLockers;
+
+ (*env)->SetIntField
+ (env, mutexObj, mutex_potentialLockers_fld, potentialLockers);
+ /* Never fails, so the JNI book says. */
+
+ /* Clean up. */
+ if (EXIT_MONITOR (env, mcache->lockForPotentialLockersObj) < 0)
+ goto done;
+ ret = 0;
+
+done:
+ return ret;
+}
+
+/*** Mutex Implementations ****/
+
+/* Create a mutex, which is a java.lang.Object for us.
+ In case of failure, we'll return NULL. Which will implicitly
+ cause future calls to fail. */
+static GMutex *
+mutex_new_jni_impl (void)
+{
+ jobject mutexObj;
+ JNIEnv *env;
+ union env_union e;
+
+ if (TRACE_API_CALLS)
+ tracing ("mutex_new_jni_impl()");
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+
+ if (setup_cache (env) < 0)
+ {
+ mutexObj = NULL;
+ goto done;
+ }
+
+ mutexObj = allocateMutexObject (env);
+
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> %p \n", mutexObj);
+
+ return (GMutex *) mutexObj;
+
+}
+
+/* Lock a mutex. */
+static void
+mutex_lock_jni_impl (GMutex * mutex)
+{
+ struct mutexObj_cache mcache;
+ jobject mutexObj = (jobject) mutex;
+ JNIEnv *env;
+ union env_union e;
+
+ if (TRACE_API_CALLS)
+ tracing ("mutex_lock_jni_impl( mutexObj = %p )", mutexObj);
+
+ assert (mutexObj);
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+
+ if (setup_cache (env) < 0)
+ goto done;
+
+ HIDE_OLD_TROUBLE (env);
+
+ if (populate_mutexObj_cache (env, mutexObj, &mcache) < 0)
+ goto done;
+
+ mutexObj_lock (env, mutexObj, &mcache);
+ /* No need to error check; we've already reported it in any case. */
+
+done:
+ clean_mutexObj_cache (env, &mcache);
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID \n");
+}
+
+
+/* Try to lock a mutex. Return TRUE if we succeed, FALSE if we fail.
+ FALSE on error. */
+static gboolean
+mutex_trylock_jni_impl (GMutex * gmutex)
+{
+ jobject mutexObj = (jobject) gmutex;
+ jint potentialLockers;
+ gboolean ret = FALSE;
+ JNIEnv *env;
+ union env_union e;
+ struct mutexObj_cache mcache;
+
+ if (TRACE_API_CALLS)
+ tracing ("mutex_trylock_jni_impl(mutexObj=%p)", mutexObj);
+
+ assert (mutexObj);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ if (populate_mutexObj_cache (env, mutexObj, &mcache) < 0)
+ goto done;
+
+ if (ENTER_MONITOR (env, mcache.lockForPotentialLockersObj))
+ goto done;
+
+ potentialLockers = (*env)->GetIntField
+ (env, mutexObj, mutex_potentialLockers_fld);
+
+ assert (potentialLockers >= 0);
+
+ if (potentialLockers)
+ {
+ /* Already locked. Clean up and leave. */
+ EXIT_MONITOR (env, mcache.lockForPotentialLockersObj);
+ /* Ignore any error code from EXIT_MONITOR; there's nothing we could do
+ at this level, in any case. */
+ goto done;
+ }
+
+ /* Guaranteed not to block. */
+ if (ENTER_MONITOR (env, mcache.lockObj))
+ {
+ /* Clean up the existing lock. */
+ EXIT_MONITOR (env, mcache.lockForPotentialLockersObj);
+ /* Ignore any error code from EXIT_MONITOR; there's nothing we could do
+ at this level, in any case. */
+ goto done;
+ }
+
+
+ /* We have the monitor. Record that fact. */
+ potentialLockers = 1;
+ (*env)->SetIntField
+ (env, mutexObj, mutex_potentialLockers_fld, potentialLockers);
+ /* Set*Field() never fails */
+
+ ret = TRUE; /* We have the lock. */
+
+ /* Clean up. */
+ if (EXIT_MONITOR (env, mcache.lockForPotentialLockersObj))
+ goto done; /* If we fail at this point, still keep the
+ main lock. */
+
+ SHOW_OLD_TROUBLE ();
+done:
+ clean_mutexObj_cache (env, &mcache);
+ if (TRACE_API_CALLS)
+ tracing (" ==> %s\n", ret ? "TRUE" : "FALSE");
+ return ret;
+}
+
+
+/* Unlock a mutex. */
+static void
+mutex_unlock_jni_impl (GMutex * gmutex)
+{
+ jobject mutexObj = (jobject) gmutex;
+ struct mutexObj_cache mcache;
+ JNIEnv *env;
+ union env_union e;
+
+ if (TRACE_API_CALLS)
+ tracing ("mutex_unlock_jni_impl(mutexObj=%p)", mutexObj);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ assert (mutexObj);
+
+ if ( populate_mutexObj_cache (env, mutexObj, &mcache) < 0)
+ goto done;
+
+ (void) mutexObj_unlock (env, mutexObj, &mcache);
+
+ SHOW_OLD_TROUBLE ();
+
+done:
+ clean_mutexObj_cache (env, &mcache);
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID\n");
+}
+
+
+
+/* Free a mutex (isn't C fun?). OK this time for it to be NULL.
+ No failure conditions, for a change. */
+static void
+mutex_free_jni_impl (GMutex * mutex)
+{
+ jobject mutexObj = (jobject) mutex;
+ JNIEnv *env;
+ union env_union e;
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+
+ if (TRACE_API_CALLS)
+ tracing ("mutex_free_jni_impl(%p)", mutexObj);
+
+ freeObject (env, mutexObj);
+
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID\n");
+}
+
+
+
+
+/************************************************************************/
+/* Condition variable code */
+/************************************************************************/
+
+/* Create a new condition variable. This is a java.lang.Object for us. */
+static GCond *
+cond_new_jni_impl (void)
+{
+ jobject condObj;
+ JNIEnv *env;
+ union env_union e;
+
+ if (TRACE_API_CALLS)
+ tracing ("mutex_free_jni_impl()");
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+
+ condObj = allocatePlainObject (env);
+
+ if (TRACE_API_CALLS)
+ tracing (" ==> %p\n", condObj);
+
+ return (GCond *) condObj;
+}
+
+/* Signal on a condition variable. This is simply calling Object.notify
+ * for us.
+ */
+static void
+cond_signal_jni_impl (GCond * gcond)
+{
+ JNIEnv *env;
+ union env_union e;
+ jobject condObj = (jobject) gcond;
+
+ if (TRACE_API_CALLS)
+ tracing ("cond_signal_jni_impl(condObj = %p)", condObj);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ assert (condObj);
+
+ /* Must have locked an object to call notify */
+ if (ENTER_MONITOR (env, condObj))
+ goto done;
+
+ (*env)->CallVoidMethod (env, condObj, obj_notify_mth);
+ if (MAYBE_BROKEN (env, "cannot signal mutex with Object.notify()"))
+ {
+ if (EXIT_MONITOR (env, condObj))
+ BADLY_BROKEN1 ("Failed to unlock a monitor; the VM may deadlock.");
+ goto done;
+ }
+
+ EXIT_MONITOR (env, condObj);
+
+ SHOW_OLD_TROUBLE ();
+
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID\n");
+}
+
+/* Broadcast to all waiting on a condition variable. This is simply
+ * calling Object.notifyAll for us.
+ */
+static void
+cond_broadcast_jni_impl (GCond * gcond)
+{
+ jobject condObj = (jobject) gcond;
+ JNIEnv *env;
+ union env_union e;
+
+ if (TRACE_API_CALLS)
+ tracing ("cond_broadcast_jni_impl(condObj=%p)", condObj);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ assert (condObj);
+ /* Must have locked an object to call notifyAll */
+ if (ENTER_MONITOR (env, condObj))
+ goto done;
+
+ (*env)->CallVoidMethod (env, condObj, obj_notifyall_mth);
+ if (MAYBE_BROKEN (env, "cannot broadcast to mutex with Object.notify()"))
+ {
+ EXIT_MONITOR (env, condObj);
+ goto done;
+ }
+
+ EXIT_MONITOR (env, condObj);
+
+ SHOW_OLD_TROUBLE ();
+
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID\n");
+}
+
+
+/* Wait on a condition variable. For us, this simply means calling
+ * Object.wait.
+ *
+ * Throws a Java exception on trouble; may leave the mutexes set arbitrarily.
+ * XXX TODO: Further improve error recovery.
+ */
+static void
+cond_wait_jni_impl (GCond * gcond, GMutex * gmutex)
+{
+ struct mutexObj_cache cache;
+ jobject condObj = (jobject) gcond;
+ jobject mutexObj = (jobject) gmutex;
+ JNIEnv *env;
+ union env_union e;
+
+ if (TRACE_API_CALLS)
+ tracing ("cond_wait_jni_impl(condObj=%p, mutexObj=%p)",
+ condObj, mutexObj);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ assert (condObj);
+ assert (mutexObj);
+ /* Must have locked a Java object to call wait on it */
+ if (ENTER_MONITOR (env, condObj) < 0)
+ goto done;
+
+ /* Our atomicity is now guaranteed; we're protected by the Java monitor on
+ condObj. Unlock the GMutex. */
+ if (mutexObj_unlock (env, mutexObj, &cache))
+ goto done;
+
+ (*env)->CallVoidMethod (env, condObj, obj_wait_mth);
+ if (MAYBE_BROKEN (env, "cannot wait on condObj"))
+ {
+ EXIT_MONITOR (env, condObj); /* ignore err checking */
+ goto done;
+ }
+
+ /* Re-acquire the lock on the GMutex. Do this while we're protected by the
+ Java monitor on condObj. */
+ if (mutexObj_lock (env, mutexObj, &cache))
+ goto done;
+
+ EXIT_MONITOR (env, condObj);
+
+ SHOW_OLD_TROUBLE ();
+
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID\n");
+}
+
+
+/** Wait on a condition variable until a timeout. This is a little tricky
+ * for us. We first call Object.wait(J) giving it the appropriate timeout
+ * value. On return, we check whether an InterruptedException happened. If
+ * so, that is Java-speak for wait timing out.
+ *
+ * We return FALSE if we timed out. Return TRUE if the condition was
+ * signalled first, before we timed out.
+ *
+ * In case of trouble we throw a Java exception. Whether we return FALSE or
+ * TRUE depends upon whether the condition was raised before the trouble
+ * happened.
+ *
+ * I believe that this function goes to the proper lengths to try to unlock
+ * all of the locked mutexes and monitors, as appropriate, and that it further
+ * tries to make sure that the thrown exception is the current one, not any
+ * future cascaded one from something like a failure to unlock the monitors.
+ */
+static gboolean
+cond_timed_wait_jni_impl (GCond * gcond, GMutex * gmutex, GTimeVal * end_time)
+{
+ JNIEnv *env;
+ union env_union e;
+ jlong time_millisec;
+ jint time_nanosec;
+ jthrowable cause;
+ jobject condObj = (jobject) gcond;
+ jobject mutexObj = (jobject) gmutex;
+ gboolean condRaised = FALSE; /* Condition has not been raised yet. */
+ struct mutexObj_cache cache;
+ gboolean interrupted;
+
+ if (TRACE_API_CALLS)
+ {
+ tracing ("cond_timed_wait_jni_impl(cond=%p, mutex=%p,"
+ " end_time=< sec=%lu, usec=%lu >)", condObj, mutexObj,
+ (unsigned long) end_time->tv_sec,
+ (unsigned long) end_time->tv_usec);
+ }
+
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ time_millisec = end_time->tv_sec * 1000 + end_time->tv_usec / 1000;
+ time_nanosec = 1000 * (end_time->tv_usec % 1000);
+
+ /* Must have locked an object to call wait */
+ if (ENTER_MONITOR (env, condObj) < 0)
+ goto done;
+
+ if (mutexObj_unlock (env, mutexObj, &cache) < 0)
+ {
+ if (EXIT_MONITOR (env, condObj) < 0)
+ criticalMsg
+ ("Unable to unlock an existing lock on a condition; your proram may deadlock");
+ goto done;
+ }
+
+
+ (*env)->CallVoidMethod (env, condObj, obj_wait_nanotime_mth,
+ time_millisec, time_nanosec);
+
+ /* If there was trouble, save that fact, and the reason for the trouble. We
+ want to respond to this condition as fast as possible. */
+ cause = (*env)->ExceptionOccurred (env);
+
+ if ( ! cause )
+ {
+ condRaised = TRUE; /* condition was signalled */
+ }
+ else if ((*env)->IsInstanceOf (env, cause, interrupted_exception_class))
+ {
+ condRaised = FALSE; /* Condition was not raised before timeout.
+ (This is redundant with the initialization
+ of condRaised above) */
+ (*env)->ExceptionClear (env); /* Clear the InterruptedException. */
+ cause = NULL; /* no pending cause now. */
+ }
+ else
+ {
+ interrupted = FALSE; /* Trouble, but not because of
+ InterruptedException. Assume the condition
+ was not raised. */
+ /* Leave condRaised set to FALSE */
+ }
+
+ /* Irrespective of whether there is a pending problem to report, go ahead
+ and try to clean up. This may end up throwing an exception that is
+ different from the one that was thrown by the call to Object.wait().
+ So we will override it with the first exception (don't want to have
+ cascading problems). */
+ if (mutexObj_lock (env, mutexObj, &cache) && !cause)
+ {
+ cause = (*env)->ExceptionOccurred (env);
+ assert (cause);
+ }
+
+ if (EXIT_MONITOR (env, condObj) && !cause)
+ {
+ cause = (*env)->ExceptionOccurred (env);
+ assert (cause);
+ }
+
+ if (cause) /* Raise the first cause. */
+ {
+ BROKEN_CAUSE (env, cause, "error in timed wait or during its cleanup");
+ goto done;
+ }
+
+ SHOW_OLD_TROUBLE ();
+
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> condRaised = %s\n", condRaised ? "TRUE" : "FALSE");
+ return condRaised;
+}
+
+
+/* Free a condition variable. (isn't C fun?). Can not fail. */
+static void
+cond_free_jni_impl (GCond * cond)
+{
+ jobject condObj = (jobject) cond;
+ JNIEnv *env;
+ union env_union e;
+
+ if (TRACE_API_CALLS)
+ tracing ("cond_free_jni_impl(condObj = %p)", condObj);
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+
+ freeObject (env, condObj);
+
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID\n");
+}
+
+
+/************************************************************************/
+/* Thread-local data code */
+/************************************************************************/
+
+/* Create a new thread-local key. We use java.lang.ThreadLocal objects
+ * for this. This returns the pointer representation of a Java global
+ * reference.
+ *
+ * We will throw a Java exception and return NULL in case of failure.
+ */
+static GPrivate *
+private_new_jni_impl (GDestroyNotify notify __attribute__ ((unused)))
+{
+ JNIEnv *env;
+ union env_union e;
+ jobject lcl_key;
+ jobject global_key;
+ GPrivate *gkey = NULL; /* Error return code */
+
+ if (TRACE_API_CALLS)
+ tracing ("private_new_jni_impl()");
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ lcl_key = (*env)->NewObject (env, threadlocal_class, threadlocal_ctor);
+ if ( ! lcl_key )
+ {
+ BROKEN (env, "cannot allocate a ThreadLocal");
+ goto done;
+ }
+
+ global_key = ((*env)->NewGlobalRef (env, lcl_key));
+ DELETE_LOCAL_REF (env, lcl_key);
+ if ( ! global_key)
+ {
+ NEW_BROKEN (env, "cannot create a GlobalRef to a new ThreadLocal");
+ goto done;
+ }
+
+ gkey = (GPrivate *) global_key;
+ SHOW_OLD_TROUBLE ();
+
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> %p\n", (void *) gkey);
+
+ return gkey;
+}
+
+/* Get this thread's value for a thread-local key. This is simply
+ * ThreadLocal.get for us. Return NULL if no value. (I can't think of
+ * anything else to do.)
+ */
+static gpointer
+private_get_jni_impl (GPrivate * gkey)
+{
+ JNIEnv *env;
+ union env_union e;
+ jobject val_wrapper;
+ jobject keyObj = (jobject) gkey;
+ gpointer thread_specific_data = NULL; /* Init to the error-return value */
+
+ jlong val;
+
+ if (TRACE_API_CALLS)
+ tracing ("private_get_jni_impl(keyObj=%p)", keyObj);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ val_wrapper = (*env)->CallObjectMethod (env, keyObj, threadlocal_get_mth);
+ if (MAYBE_BROKEN (env, "cannot find thread-local object"))
+ goto done;
+
+ if (! val_wrapper )
+ {
+ /* It's Java's "null" object. No ref found. This is OK; we must never
+ have set a value in this thread. Note that this next statement is
+ not necessary, strictly speaking, since we're already initialized to
+ NULL. A good optimizing C compiler will detect that and optimize out
+ this statement. */
+ thread_specific_data = NULL;
+ goto done;
+ }
+
+ val = (*env)->CallLongMethod (env, val_wrapper, long_longValue_mth);
+
+ if (MAYBE_BROKEN (env, "cannot get thread local value"))
+ goto done;
+
+ thread_specific_data = (gpointer) (intptr_t) val;
+
+ /* Only re-raise the old pending exception if a new one hasn't come along to
+ supersede it. */
+ SHOW_OLD_TROUBLE ();
+
+done:
+
+ if (TRACE_API_CALLS)
+ tracing (" ==> %p\n", thread_specific_data);
+
+ return thread_specific_data;
+}
+
+/* Set this thread's value for a thread-local key. This is simply
+ * ThreadLocal.set() for us.
+ */
+static void
+private_set_jni_impl (GPrivate * gkey, gpointer thread_specific_data)
+{
+ JNIEnv *env;
+ union env_union e;
+ jobject val_wrapper;
+ jobject keyObj = (jobject) gkey;
+
+
+ if (TRACE_API_CALLS)
+ tracing ("private_set_jni_impl(keyObj=%p, thread_specific_data=%p)",
+ keyObj, thread_specific_data);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ /* We are just going to always use a Java long to represent a C pointer.
+ Otherwise all of the code would end up being conditionalized for various
+ pointer sizes, and that seems like too much of a hassle, in order to save
+ a paltry few bytes, especially given the horrendous overhead of JNI in
+ any case.
+ */
+
+ val_wrapper = (*env)->NewObject (env, long_class, long_ctor,
+ (jlong) (intptr_t) thread_specific_data);
+ if ( ! val_wrapper )
+ {
+ BROKEN (env, "cannot create a java.lang.Long");
+ goto done;
+ }
+
+ /* At this point, we now have set lcl_obj as a numeric class that wraps
+ around the thread-specific data we were given. */
+ (*env)->CallVoidMethod (env, keyObj, threadlocal_set_mth, val_wrapper);
+ if (MAYBE_BROKEN (env, "cannot set thread local value"))
+ goto done;
+
+ SHOW_OLD_TROUBLE ();
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID\n");
+}
+
+
+/** Create an object of type gnu.java.awt.peer.gtk.GThreadNativeMethodRunner.
+ Run it.
+
+ We need to create joinable threads. We handle the notion of a joinable
+ thread by determining whether or not we are going to maintain a permanent
+ hard reference to it until it croaks.
+
+ Posix does not appear to have a Java-like concept of daemon threads, where
+ the JVM will exit when there are only daemon threads running.
+
+ Error handling:
+
+ To quote from the glib guide:
+ "GError should only be used to report recoverable runtime errors, never
+ to report programming errors."
+
+ So how do we consider the failure to create a thread? Well, each of the
+ failure cases in this function are discussed, and none of them are really
+ recoverable.
+
+ The glib library is really designed so that you should fail
+ catastrophically in case of "programming errors". The only error defined
+ for the GThread functions is G_THREAD_ERROR_AGAIN, and that for
+ thread_create.
+
+ Most of these GThread functions could fail if we run out of memory, for
+ example, but the only one capable of reporting that fact is
+ thread_create. */
+static void
+thread_create_jni_impl (GThreadFunc func,
+ gpointer data,
+ gulong stack_size __attribute__((unused)),
+ gboolean joinable,
+ gboolean bound __attribute__((unused)),
+ GThreadPriority gpriority,
+ /* This prototype is horrible. threadIDp is actually
+ a gpointer to the thread's thread-ID. Which is,
+ of course, itself a gpointer-typed value. Ouch. */
+ gpointer threadIDp,
+ /* Do not touch the GError stuff unless you have
+ RECOVERABLE trouble. There is no recoverable
+ trouble in this implementation. */
+ GError **errorp __attribute__((unused)))
+{
+ JNIEnv *env;
+ union env_union e;
+ union func_union f;
+ jboolean jjoinable = joinable;
+ jobject newThreadObj;
+ gpointer threadID; /* to be filled in */
+
+ if (TRACE_API_CALLS)
+ {
+ f.g_func = func;
+ tracing ("thread_create_jni_impl(func=%p, data=%p, joinable=%s,"
+ " threadIDp=%p, *(int *) threadIDp = %d)",
+ f.void_func, data, joinable ? "TRUE" : "FALSE",
+ threadIDp, *(int *) threadIDp);
+ }
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ {
+ /* The failed call to setup the cache is certainly not recoverable;
+ not appropriate for G_THREAD_ERROR_AGAIN. */
+ *(gpointer *) threadIDp = NULL;
+ goto done;
+ }
+ HIDE_OLD_TROUBLE (env);
+
+ /* If a thread is joinable, then notify its constructor. The constructor
+ will enter a hard reference for it, and the hard ref. won't go away until
+ the thread has been joined. */
+ newThreadObj =
+ (*env)->NewObject (env, runner_class, runner_ctor,
+ (jlong) (intptr_t) func, (jlong) (intptr_t) data,
+ jjoinable);
+ if ( ! newThreadObj )
+ {
+ BROKEN (env, "creating a new thread failed in the constructor");
+ *(gpointer *) threadIDp = NULL;
+ /* The failed call to the constructor does not throw any errors such
+ that G_THREAD_ERROR_AGAIN is appropriate. No other recoverable
+ errors defined. Once again, we go back to the VM. */
+ goto done;
+ }
+
+ if (threadObj_set_priority (env, newThreadObj, gpriority) < 0)
+ {
+ *(gpointer *) threadIDp = NULL;
+ /* None of these possible exceptions from Thread.setPriority() are
+ recoverable, so they are not appropriate for EAGAIN. So we should
+ fail. */
+ goto done;
+ }
+
+ (*env)->CallVoidMethod (env, runner_class, runner_start_mth);
+
+ if (MAYBE_BROKEN (env, "starting a new thread failed"))
+ {
+ *(gpointer *) threadIDp = NULL;
+ /* The only exception Thread.start() throws is
+ IllegalStateException. And that would indicate a programming error.
+
+ So there are no situations such that G_THREAD_ERROR_AGAIN would be
+ OK.
+
+ So, we don't use g_set_error() here to perform any error reporting.
+ */
+ goto done;
+ }
+
+ threadID = getThreadIDFromThread (env, newThreadObj);
+
+ *(gpointer *) threadIDp = threadID;
+ SHOW_OLD_TROUBLE ();
+
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> (threadID = %p) \n", threadID);
+}
+
+
+/* Wraps a call to g_thread_yield. */
+static void
+thread_yield_jni_impl (void)
+{
+ JNIEnv *env;
+ union env_union e;
+
+ if (TRACE_API_CALLS)
+ tracing ("thread_yield_jni_impl()");
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ (*env)->CallStaticVoidMethod (env, thread_class, thread_yield_mth);
+ if (MAYBE_BROKEN (env, "Thread.yield() failed"))
+ goto done;
+
+ SHOW_OLD_TROUBLE ();
+
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID\n");
+}
+
+
+static void
+thread_join_jni_impl (gpointer threadID)
+{
+ JNIEnv *env;
+ union env_union e;
+ jobject threadObj = NULL;
+
+ if ( TRACE_API_CALLS )
+ tracing ("thread_join_jni_impl(threadID=%p) ", threadID);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+ HIDE_OLD_TROUBLE (env);
+
+ threadObj = getThreadFromThreadID (env, threadID);
+ if ( ! threadObj ) /* Already reported with BROKEN */
+ goto done;
+
+ (*env)->CallVoidMethod (env, threadObj, thread_join_mth);
+ if (MAYBE_BROKEN (env, "Thread.join() failed"))
+ goto done;
+
+
+ (*env)->CallStaticVoidMethod
+ (env, runner_class, runner_deRegisterJoinable_mth, threadObj);
+ if (MAYBE_BROKEN (env, "Thread.deRegisterJoinableThread() failed"))
+ goto done;
+
+ SHOW_OLD_TROUBLE ();
+
+done:
+ DELETE_LOCAL_REF (env, threadObj);
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID \n");
+}
+
+/* Terminate the current thread. Unlike pthread_exit(), here we do not need
+ to bother with a return value or exit value for the thread which is about
+ to croak. (The gthreads abstraction doesn't use it.) However, we *do*
+ need to bail immediately. We handle this with Thread.stop(), which is
+ a deprecated method.
+
+ It's deprecated since we might leave objects protected by monitors in
+ half-constructed states on the way out -- Thread.stop() throws a
+ ThreadDeath exception, which is usually unchecked. There is no good
+ solution that I can see. */
+static void
+thread_exit_jni_impl (void)
+{
+ JNIEnv *env;
+ union env_union e;
+ jobject this_thread;
+
+ if (TRACE_API_CALLS)
+ tracing ("thread_exit_jni_impl() ");
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ goto done;
+
+ HIDE_OLD_TROUBLE (env);
+
+ this_thread = (*env)->
+ CallStaticObjectMethod (env, thread_class, thread_current_mth);
+
+ if ( ! this_thread )
+ {
+ BROKEN (env, "cannot get current thread");
+ goto done;
+ }
+
+ (*env)->CallVoidMethod (env, this_thread, thread_stop_mth);
+ if (MAYBE_BROKEN (env, "cannot call Thread.stop() on current thread"))
+ goto done;
+
+ SHOW_OLD_TROUBLE ();
+
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID \n");
+}
+
+
+/* Translate a GThreadPriority to a Java priority level. */
+static jint
+javaPriorityLevel (GThreadPriority priority)
+{
+ /* We have these fields in java.lang.Thread to play with:
+
+ static int MIN_PRIORITY The minimum priority that a thread can have.
+ static int NORM_PRIORITY The default priority that is assigned to a
+ thread.
+ static int MAX_PRIORITY The maximum priority that a thread can have.
+
+ We get these from the header file generated by javah, even though they're
+ documented as being 1, 5, and 10.
+ */
+ static const jint minJPri =
+ gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MIN_PRIORITY;
+ static const jint normJPri =
+ gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_NORM_PRIORITY;
+ static const jint maxJPri =
+ gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_MAX_PRIORITY;
+
+ switch (priority)
+ {
+ case G_THREAD_PRIORITY_LOW:
+ return minJPri;
+ break;
+
+ default:
+ assert_not_reached ();
+ /* Deliberate fall-through if assertions are turned off; also shuts up
+ GCC warnings if they're turned on. */
+ case G_THREAD_PRIORITY_NORMAL:
+ return normJPri;
+ break;
+
+ case G_THREAD_PRIORITY_HIGH:
+ return (normJPri + maxJPri) / 2;
+ break;
+
+ case G_THREAD_PRIORITY_URGENT:
+ return maxJPri;
+ break;
+ }
+}
+
+
+/** It would be safe not to implement this, according to the JNI docs, since
+ not all platforms do thread priorities. However, we might as well
+ provide the hint for those who want it.
+*/
+static void
+thread_set_priority_jni_impl (gpointer gThreadID, GThreadPriority gpriority)
+{
+ jobject threadObj = NULL;
+ JNIEnv *env;
+ union env_union e;
+
+ if (TRACE_API_CALLS)
+ tracing ("thread_set_priority_jni_impl(gThreadID=%p, gpriority = %u) ",
+ gThreadID, gpriority);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+
+ if (setup_cache (env) < 0)
+ goto done;
+
+ HIDE_OLD_TROUBLE (env);
+
+
+ threadObj = getThreadFromThreadID (env, gThreadID);
+ if ( ! threadObj) /* Reported with BROKEN already. */
+ goto done;
+
+ if (threadObj_set_priority (env, threadObj, gpriority))
+ goto done;
+
+ SHOW_OLD_TROUBLE ();
+
+done:
+ DELETE_LOCAL_REF (env, threadObj);
+
+ if (TRACE_API_CALLS)
+ tracing (" ==> VOID\n");
+}
+
+
+/** It would be safe not to implement this, according to the JNI docs, since
+ not all platforms do thread priorities. However, we might as well
+ provide the hint for those who want it.
+
+ -1 on failure, 0 on success. */
+static int
+threadObj_set_priority (JNIEnv * env, jobject threadObj,
+ GThreadPriority gpriority)
+{
+ jint javaPriority = javaPriorityLevel (gpriority);
+ (*env)->CallVoidMethod (env, threadObj, thread_setPriority_mth,
+ javaPriority);
+ return MAYBE_BROKEN (env, "Thread.setPriority() failed");
+}
+
+
+/** Return the result of Thread.currentThread(), a static method. */
+static void
+thread_self_jni_impl (/* Another confusing glib prototype. This is
+ actually a gpointer to the thread's thread-ID.
+ Which is, of course, a gpointer. */
+ gpointer my_thread_IDp)
+{
+ JNIEnv *env;
+ union env_union e;
+ jobject this_thread;
+ gpointer my_threadID;
+
+ if (TRACE_API_CALLS)
+ tracing ("thread_self_jni_impl(my_thread_IDp=%p)", my_thread_IDp);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+
+ if (setup_cache (env) < 0)
+ return;
+
+ HIDE_OLD_TROUBLE (env);
+
+ this_thread = (*env)->
+ CallStaticObjectMethod (env, thread_class, thread_current_mth);
+ if (! this_thread )
+ {
+ BROKEN (env, "cannot get current thread");
+ my_threadID = NULL;
+ goto done;
+ }
+
+ my_threadID = getThreadIDFromThread (env, this_thread);
+ SHOW_OLD_TROUBLE ();
+
+done:
+ if (TRACE_API_CALLS)
+ tracing (" ==> (my_threadID = %p) \n", my_threadID);
+
+ *(gpointer *) my_thread_IDp = my_threadID;
+}
+
+
+static gboolean
+thread_equal_jni_impl (gpointer thread1, gpointer thread2)
+{
+ JNIEnv *env;
+ union env_union e;
+
+ gpointer threadID1 = *(gpointer *) thread1;
+ gpointer threadID2 = *(gpointer *) thread2;
+
+ jobject thread1_obj = NULL;
+ jobject thread2_obj = NULL;
+ gboolean ret;
+
+ if (TRACE_API_CALLS)
+ tracing ("thread_equal_jni_impl(threadID1=%p, threadID2=%p)",
+ threadID1, threadID2);
+
+ e.jni_env = &env;
+ (*cp_gtk_the_vm)->GetEnv (cp_gtk_the_vm, e.void_env, JNI_VERSION_1_1);
+ if (setup_cache (env) < 0)
+ {
+ ret = FALSE; /* what is safer? We really don't ever want
+ to return from here. */
+ goto done;
+ }
+
+ HIDE_OLD_TROUBLE (env);
+ thread1_obj = getThreadFromThreadID (env, threadID1);
+ thread2_obj = getThreadFromThreadID (env, threadID2);
+
+ ret = (*env)->CallBooleanMethod (env, thread1_obj,
+ thread_equals_mth, thread2_obj);
+
+ if (MAYBE_BROKEN (env, "Thread.equals() failed"))
+ {
+ ret = FALSE;
+ goto done;
+ }
+
+ SHOW_OLD_TROUBLE ();
+
+
+done:
+ DELETE_LOCAL_REF (env, thread1_obj);
+ DELETE_LOCAL_REF (env, thread2_obj);
+
+ if (TRACE_API_CALLS)
+ tracing (" ==> %s\n", ret ? "TRUE" : "FALSE");
+
+ return ret;
+}
+
+
+
+
+/************************************************************************/
+/* GLIB interface */
+/************************************************************************/
+
+/* set of function pointers to give to glib. */
+GThreadFunctions cp_gtk_portable_native_sync_jni_functions = {
+ mutex_new_jni_impl, /* mutex_new */
+ mutex_lock_jni_impl, /* mutex_lock */
+ mutex_trylock_jni_impl, /* mutex_trylock */
+ mutex_unlock_jni_impl, /* mutex_unlock */
+ mutex_free_jni_impl, /* mutex_free */
+ cond_new_jni_impl, /* cond_new */
+ cond_signal_jni_impl, /* cond_signal */
+ cond_broadcast_jni_impl, /* cond_broadcast */
+ cond_wait_jni_impl, /* cond_wait */
+ cond_timed_wait_jni_impl, /* cond_timed_wait */
+ cond_free_jni_impl, /* cond_free */
+ private_new_jni_impl, /* private_new */
+ private_get_jni_impl, /* private_get */
+ private_set_jni_impl, /* private_set */
+ thread_create_jni_impl, /* thread_create */
+ thread_yield_jni_impl, /* thread_yield */
+ thread_join_jni_impl, /* thread_join */
+ thread_exit_jni_impl, /* thread_exit */
+ thread_set_priority_jni_impl, /* thread_set_priority */
+ thread_self_jni_impl, /* thread_self */
+ thread_equal_jni_impl, /* thread_equal */
+};
+
+
+/* Keep c-font-lock-extra-types in alphabetical order. */
+/* Local Variables: */
+/* c-file-style: "gnu" */
+/* c-font-lock-extra-types: ("\\sw+_t" "gboolean" "GError" "gpointer"
+ "GPrivate" "GThreadFunc" "GThreadFunctions" "GThreadPriority"
+ "gulong"
+ "JNIEnv"
+ "jboolean" "jclass" "jfieldID" "jint" "jlong" "jmethodID" "jobject" "jstring" "jthrowable" ) */
+/* End: */
diff --git a/libjava/classpath/native/jni/gtk-peer/gthread-jni.h b/libjava/classpath/native/jni/gtk-peer/gthread-jni.h
new file mode 100644
index 00000000000..3d052dc106e
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gthread-jni.h
@@ -0,0 +1,48 @@
+/* gthread-jni.h
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef __GTHREADJNI_H__
+#define __GTHREADJNI_H__
+
+#include <jni.h>
+#include <glib.h>
+#include "gtkpeer.h"
+
+extern GThreadFunctions cp_gtk_portable_native_sync_jni_functions;
+extern JavaVM *cp_gtk_the_vm;
+
+#endif /* __GTHREADJNI_H__ */
diff --git a/libjava/classpath/native/jni/gtk-peer/gtkcairopeer.h b/libjava/classpath/native/jni/gtk-peer/gtkcairopeer.h
new file mode 100644
index 00000000000..dee843c8a70
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gtkcairopeer.h
@@ -0,0 +1,93 @@
+#ifndef __GTKCAIROPEER_H__
+#define __GTKCAIROPEER_H__
+
+/* gtkcairopeer.h -- Some global variables and #defines
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "gtkpeer.h"
+#include <cairo.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+/*
+ A graphics2d struct is both simpler and uglier than a graphics
+ struct.
+
+ Most of the graphics2d drawing state is held in the referenced cairo_t
+ and corresponding cairo_surface_t, so we can ignore it.
+
+ In addition to the cairo_t, we need to hold an extra reference to the
+ underlying GdkDrawable so its refcount matches the lifecycle of the java
+ Graphics object which is peering with us; also a reference to a byte
+ buffer and cairo_surface_t which contain the pattern you're drawing from
+ (if it exists).
+
+ Finally, it is possible that we are using a non-RENDER capable X server,
+ therefore we will be drawing to an cairo_surface_t which is actually a
+ pixbuf. When this is the case, the pointer to a GdkPixbuf will be
+ non-NULL and any drawing operation needs to be bracketed by pixbuf
+ load/save operations. If the GdkPixbuf pointer is NULL, we will treat
+ the cairo_surface_t as RENDER-capable.
+ */
+
+struct graphics2d
+{
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ GdkDrawable *drawable;
+ GdkWindow *win;
+ GdkPixbuf *drawbuf;
+ char *pattern_pixels;
+ cairo_surface_t *pattern_surface;
+ cairo_pattern_t *pattern;
+ gboolean debug;
+ enum
+ {
+ MODE_DRAWABLE_WITH_RENDER,
+ MODE_DRAWABLE_NO_RENDER,
+ MODE_JAVA_ARRAY
+ }
+ mode;
+
+ /* Support for MODE_JAVA_ARRAY */
+ jintArray jarray;
+ jint width, height;
+ jint *javabuf;
+ jint *javabuf_copy;
+ jboolean isCopy;
+};
+
+#endif /* __GTKCAIROPEER_H */
diff --git a/libjava/classpath/native/jni/gtk-peer/gtkpeer.h b/libjava/classpath/native/jni/gtk-peer/gtkpeer.h
new file mode 100644
index 00000000000..f291d82ef4b
--- /dev/null
+++ b/libjava/classpath/native/jni/gtk-peer/gtkpeer.h
@@ -0,0 +1,206 @@
+/* gtkpeer.h -- Some global variables and #defines
+ Copyright (C) 1998, 1999, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <config.h>
+#include "native_state.h"
+
+#include <jni.h>
+
+#ifndef __GTKPEER_H__
+#define __GTKPEER_H__
+
+#ifndef __GNUC__
+#define __attribute__(x) /* nothing */
+#endif
+
+extern struct state_table *cp_gtk_native_state_table;
+extern struct state_table *cp_gtk_native_global_ref_table;
+
+#define NSA_INIT(env, clazz) \
+ do {cp_gtk_native_state_table = cp_gtk_init_state_table (env, clazz); \
+ cp_gtk_native_global_ref_table = cp_gtk_init_state_table (env, clazz);} while (0)
+
+#define NSA_GET_PTR(env, obj) \
+ cp_gtk_get_state (env, obj, cp_gtk_native_state_table)
+
+#define NSA_SET_PTR(env, obj, ptr) \
+ cp_gtk_set_state (env, obj, cp_gtk_native_state_table, (void *)ptr)
+
+#define NSA_DEL_PTR(env, obj) \
+ cp_gtk_remove_state_slot (env, obj, cp_gtk_native_state_table)
+
+#define NSA_GET_GLOBAL_REF(env, obj) \
+ cp_gtk_get_state (env, obj, cp_gtk_native_global_ref_table)
+
+#define NSA_SET_GLOBAL_REF(env, obj) \
+ do {jobject *globRefPtr; \
+ globRefPtr = (jobject *) malloc (sizeof (jobject)); \
+ *globRefPtr = (*env)->NewGlobalRef (env, obj); \
+ cp_gtk_set_state (env, obj, cp_gtk_native_global_ref_table, (void *)globRefPtr);} while (0)
+
+#define NSA_DEL_GLOBAL_REF(env, obj) \
+ do {jobject *globRefPtr = cp_gtk_get_state (env, obj, cp_gtk_native_global_ref_table); \
+ cp_gtk_remove_state_slot (env, obj, cp_gtk_native_global_ref_table); \
+ (*env)->DeleteGlobalRef (env, *globRefPtr); \
+ free (globRefPtr);} while (0)
+
+#define SWAPU32(w) \
+ (((w) << 24) | (((w) & 0xff00) << 8) | (((w) >> 8) & 0xff00) | ((w) >> 24))
+
+struct graphics
+{
+ GdkDrawable *drawable;
+ GdkGC *gc;
+ GdkColormap *cm;
+ PangoFontDescription *pango_font;
+ PangoContext *pango_context;
+ PangoLayout *pango_layout;
+ jint x_offset, y_offset;
+};
+
+#define AWT_SHIFT_DOWN_MASK (1 << 6)
+#define AWT_CTRL_DOWN_MASK (1 << 7)
+#define AWT_META_DOWN_MASK (1 << 8)
+#define AWT_ALT_DOWN_MASK (1 << 9)
+
+#define AWT_BUTTON1_MASK (1 << 4)
+#define AWT_BUTTON2_MASK (1 << 3)
+#define AWT_BUTTON3_MASK (1 << 2)
+
+#define AWT_ITEM_SELECTED 1
+#define AWT_ITEM_DESELECTED 2
+
+#define AWT_KEY_TYPED 400
+#define AWT_KEY_PRESSED 401
+#define AWT_KEY_RELEASED 402
+
+#define AWT_KEY_LOCATION_UNKNOWN 0
+#define AWT_KEY_LOCATION_STANDARD 1
+#define AWT_KEY_LOCATION_LEFT 2
+#define AWT_KEY_LOCATION_RIGHT 3
+#define AWT_KEY_LOCATION_NUMPAD 4
+
+#define AWT_STYLE_PLAIN 0
+#define AWT_STYLE_BOLD 1
+#define AWT_STYLE_ITALIC 2
+
+/* Used in GtkComponentPeer and GtkWindowPeer */
+#define VK_NUMPAD0 96
+#define VK_NUMPAD1 97
+#define VK_NUMPAD2 98
+#define VK_NUMPAD3 99
+#define VK_NUMPAD4 100
+#define VK_NUMPAD5 101
+#define VK_NUMPAD6 102
+#define VK_NUMPAD7 103
+#define VK_NUMPAD8 104
+#define VK_NUMPAD9 105
+#define VK_DECIMAL 110
+
+JNIEnv *cp_gtk_gdk_env(void);
+
+/* Global variables */
+extern double cp_gtk_dpi_conversion_factor;
+extern GtkWindowGroup *cp_gtk_global_window_group;
+
+/* Union used for type punning. */
+union widget_union
+{
+ void **void_widget;
+ GtkWidget **widget;
+};
+
+/* Keycode helpers */
+guint cp_gtk_awt_keycode_to_keysym (jint keyCode, jint keyLocation);
+
+/* Image helpers */
+GdkPixbuf *cp_gtk_image_get_pixbuf (JNIEnv *env, jobject obj);
+GdkPixmap *cp_gtk_image_get_pixmap (JNIEnv *env, jobject obj);
+jboolean cp_gtk_image_is_offscreen (JNIEnv *env, jobject obj);
+
+/* JNI initialization functions */
+#if GTK_CAIRO
+void cp_gtk_graphics2d_init_jni (void);
+#endif
+void cp_gtk_graphics_init_jni (void);
+void cp_gtk_button_init_jni (void);
+void cp_gtk_checkbox_init_jni (void);
+void cp_gtk_choice_init_jni (void);
+void cp_gtk_component_init_jni (void);
+void cp_gtk_list_init_jni (void);
+void cp_gtk_menuitem_init_jni (void);
+void cp_gtk_scrollbar_init_jni (void);
+void cp_gtk_textcomponent_init_jni (void);
+void cp_gtk_window_init_jni (void);
+
+/* Signal connection convience functions */
+void cp_gtk_component_connect_expose_signals (GObject *ptr, jobject *gref);
+void cp_gtk_component_connect_focus_signals (GObject *ptr, jobject *gref);
+void cp_gtk_component_connect_mouse_signals (GObject *ptr, jobject *gref);
+void cp_gtk_component_connect_signals (GObject *ptr, jobject *gref);
+void cp_gtk_textcomponent_connect_signals (GObject *ptr, jobject *gref);
+
+/* Debugging */
+void cp_gtk_print_current_thread (void);
+
+#define DEBUG_LOCKING 0
+
+#if DEBUG_LOCKING
+#define gdk_threads_enter() \
+{ \
+ g_print ("locking: %s, %d\n", __FILE__, __LINE__); \
+ cp_gtk_print_current_thread (); \
+ gdk_threads_enter (); \
+ g_print ("locked: %s, %d\n", __FILE__, __LINE__); \
+ cp_gtk_print_current_thread (); \
+}
+#define gdk_threads_leave() \
+{ \
+ g_print ("unlocking: %s, %d\n", __FILE__, __LINE__); \
+ cp_gtk_print_current_thread (); \
+ gdk_threads_leave (); \
+ g_print ("unlocked: %s, %d\n", __FILE__, __LINE__); \
+ cp_gtk_print_current_thread (); \
+}
+#endif
+
+#endif /* __GTKPEER_H */
diff --git a/libjava/classpath/native/jni/java-io/.cvsignore b/libjava/classpath/native/jni/java-io/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/jni/java-io/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/java-io/Makefile.am b/libjava/classpath/native/jni/java-io/Makefile.am
new file mode 100644
index 00000000000..5ed8a1baf4c
--- /dev/null
+++ b/libjava/classpath/native/jni/java-io/Makefile.am
@@ -0,0 +1,13 @@
+pkglib_LTLIBRARIES = libjavaio.la
+
+libjavaio_la_SOURCES = javaio.h \
+ javaio.c \
+ java_io_VMFile.c \
+ java_io_VMObjectInputStream.c \
+ java_io_VMObjectStreamClass.c
+
+libjavaio_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo
+
+AM_LDFLAGS = @CLASSPATH_MODULE@
+AM_CPPFLAGS = @CLASSPATH_INCLUDES@
+AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
diff --git a/libjava/classpath/native/jni/java-io/java_io_VMFile.c b/libjava/classpath/native/jni/java-io/java_io_VMFile.c
new file mode 100644
index 00000000000..b32c29477e0
--- /dev/null
+++ b/libjava/classpath/native/jni/java-io/java_io_VMFile.c
@@ -0,0 +1,734 @@
+/* java_io_VMFile.c - Native methods for java.io.File class
+ Copyright (C) 1998, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "target_native.h"
+#ifndef WITHOUT_FILESYSTEM
+#include "target_native_file.h"
+#endif
+#include "target_native_math_int.h"
+
+#include "javaio.h"
+
+#include "java_io_VMFile.h"
+
+/*************************************************************************/
+
+/*
+ * Method to create an empty file.
+ *
+ * Class: java_io_VMFile
+ * Method: create
+ * Signature: (Ljava/lang/String;)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_create (JNIEnv * env,
+ jclass clazz __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int fd;
+ int result;
+
+ filename = JCL_jstring_to_cstring (env, name);
+ if (filename == NULL)
+ {
+ return (0);
+ }
+
+ TARGET_NATIVE_FILE_OPEN_CREATE (filename, fd, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ /* XXX ??? NYI */
+ if (errno != EEXIST)
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ JCL_free_cstring (env, name, filename);
+ return (0);
+ }
+ TARGET_NATIVE_FILE_CLOSE (fd, result);
+
+ JCL_free_cstring (env, name, filename);
+ return (1);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method checks to see if we have read permission on a file.
+ *
+ * Class: java_io_VMFile
+ * Method: canRead
+ * Signature: (Ljava/lang/String;)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_canRead (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int fd;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+ if (filename == NULL)
+ {
+ return (0);
+ }
+
+ /* The lazy man's way out. We actually do open the file for reading
+ briefly to verify it can be done */
+ TARGET_NATIVE_FILE_OPEN_READ (filename, fd, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+ if (result != TARGET_NATIVE_OK)
+ {
+ return (0);
+ }
+ TARGET_NATIVE_FILE_CLOSE (fd, result);
+
+ return (1);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method checks to see if we have write permission on a file.
+ *
+ * Class: java_io_VMFile
+ * Method: canWrite
+ * Signature: (Ljava/lang/String;)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_canWrite (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int fd;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+ if (filename == NULL)
+ {
+ return (0);
+ }
+
+ /* The lazy man's way out. We actually do open the file for writing
+ briefly to verify it can be done */
+ TARGET_NATIVE_FILE_OPEN_READWRITE (filename, fd, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+ if (result != TARGET_NATIVE_OK)
+ {
+ return (0);
+ }
+ TARGET_NATIVE_FILE_CLOSE (fd, result);
+
+ return (1);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method makes a file read only.
+ *
+ * Class: java_io_VMFile
+ * Method: setReadOnly
+ * Signature: (Ljava/lang/String;)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_setReadOnly (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+ if (filename == NULL)
+ {
+ return (0);
+ }
+
+ TARGET_NATIVE_FILE_SET_MODE_READONLY (filename, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+
+ return ((result == TARGET_NATIVE_OK) ? 1 : 0);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method checks to see if a file exists.
+ *
+ * Class: java_io_VMFile
+ * Method: exists
+ * Signature: (Ljava/lang/String;)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_exists (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+ if (filename == NULL)
+ {
+ return (0);
+ }
+
+ TARGET_NATIVE_FILE_EXISTS (filename, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+
+ return ((result == TARGET_NATIVE_OK) ? 1 : 0);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method checks to see if a file is a "plain" file; that is, not
+ * a directory, pipe, etc.
+ *
+ * Class: java_io_VMFile
+ * Method: isFile
+ * Signature: (Ljava/lang/String;)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_isFile (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+ if (filename == NULL)
+ {
+ return (0);
+ }
+
+ TARGET_NATIVE_FILE_IS_FILE (filename, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+
+ return ((result == TARGET_NATIVE_OK) ? 1 : 0);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method checks to see if a file is a directory or not.
+ *
+ * Class: java_io_VMFile
+ * Method: isDirectory
+ * Signature: (Ljava/lang/String;)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_isDirectory (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+ if (filename == NULL)
+ {
+ return (0);
+ }
+
+ TARGET_NATIVE_FILE_IS_DIRECTORY (filename, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+
+ return ((result == TARGET_NATIVE_OK) ? 1 : 0);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method returns the length of the file.
+ *
+ * Class: java_io_VMFile
+ * Method: length
+ * Signature: (Ljava/lang/String;)J
+ */
+
+JNIEXPORT jlong JNICALL
+Java_java_io_VMFile_length (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int tmpfd;
+ jlong length;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+ if (filename == NULL)
+ {
+ return (TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+ }
+
+ /* open file for reading, get size and close file */
+ TARGET_NATIVE_FILE_OPEN_READ (filename, tmpfd, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ return (TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+ }
+ TARGET_NATIVE_FILE_SIZE (tmpfd, length, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ TARGET_NATIVE_FILE_CLOSE (tmpfd, result);
+ return (TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+ }
+ TARGET_NATIVE_FILE_CLOSE (tmpfd, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+
+ return ((result ==
+ TARGET_NATIVE_OK) ? length : TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+#else /* not WITHOUT_FILESYSTEM */
+ return (TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method returns the modification date of the file.
+ *
+ * Class: java_io_VMFile
+ * Method: lastModified
+ * Signature: (Ljava/lang/String;)J
+ */
+
+JNIEXPORT jlong JNICALL
+Java_java_io_VMFile_lastModified (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ jlong mtime;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+ if (filename == NULL)
+ {
+ return (TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+ }
+
+ TARGET_NATIVE_FILE_GET_LAST_MODIFIED (filename, mtime, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+
+ return ((result ==
+ TARGET_NATIVE_OK) ? mtime : TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+#else /* not WITHOUT_FILESYSTEM */
+ return (TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method sets the modification date of the file.
+ *
+ * Class: java_io_VMFile
+ * Method: setLastModified
+ * Signature: (Ljava/lang/String;J)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_setLastModified (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name, jlong newtime)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+ if (filename == NULL)
+ {
+ return (0);
+ }
+
+ TARGET_NATIVE_FILE_SET_LAST_MODIFIED (filename, newtime, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+
+ return ((result == TARGET_NATIVE_OK) ? 1 : 0);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method deletes a file (actually a name for a file - additional
+ * links could exist).
+ *
+ * Class: java_io_VMFile
+ * Method: delete
+ * Signature: (Ljava/lang/String;)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_delete (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ filename = (*env)->GetStringUTFChars (env, name, 0);
+ if (filename == NULL)
+ {
+ return (0);
+ }
+
+ TARGET_NATIVE_FILE_DELETE (filename, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+
+ return ((result == TARGET_NATIVE_OK) ? 1 : 0);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method creates a directory.
+ *
+ * Class: java_io_VMFile
+ * Method: mkdir
+ * Signature: (Ljava/lang/String;)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_mkdir (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *pathname;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ pathname = (*env)->GetStringUTFChars (env, name, 0);
+ if (pathname == NULL)
+ {
+ return (0);
+ }
+
+ TARGET_NATIVE_FILE_MAKE_DIR (pathname, result);
+ (*env)->ReleaseStringUTFChars (env, name, pathname);
+
+ return ((result == TARGET_NATIVE_OK) ? 1 : 0);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method renames a (link to a) file.
+ *
+ * Class: java_io_VMFile
+ * Method: renameTo
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)Z
+ */
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMFile_renameTo (JNIEnv * env,
+ jobject obj __attribute__ ((__unused__)),
+ jstring t, jstring d)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *old_filename, *new_filename;
+ int result;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ old_filename = (*env)->GetStringUTFChars (env, t, 0);
+ if (old_filename == NULL)
+ {
+ return (0);
+ }
+
+ new_filename = (*env)->GetStringUTFChars (env, d, 0);
+ if (new_filename == NULL)
+ {
+ (*env)->ReleaseStringUTFChars (env, t, old_filename);
+ return (0);
+ }
+
+ TARGET_NATIVE_FILE_RENAME (old_filename, new_filename, result);
+ (*env)->ReleaseStringUTFChars (env, d, new_filename);
+ (*env)->ReleaseStringUTFChars (env, t, old_filename);
+
+ return ((result == TARGET_NATIVE_OK) ? 1 : 0);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * This method returns an array of String representing all the files
+ * in a directory except "." and "..".
+ *
+ * Class: java_io_VMFile
+ * Method: list
+ * Signature: (Ljava/lang/String;)[Ljava/lang/String;
+ */
+
+JNIEXPORT jobjectArray JNICALL
+Java_java_io_VMFile_list (JNIEnv * env, jobject obj
+ __attribute__ ((__unused__)), jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const int REALLOC_SIZE = 10;
+
+ const char *dirname;
+ int result;
+ char **filelist;
+ void *handle;
+ const char *filename;
+ unsigned long int filelist_count, max_filelist_count;
+ char **tmp_filelist;
+ jclass str_clazz;
+ jobjectArray filearray;
+ unsigned long int i;
+ jstring str;
+
+ /* Don't use the JCL convert function because it throws an exception
+ on failure */
+ dirname = (*env)->GetStringUTFChars (env, name, 0);
+ if (dirname == NULL)
+ {
+ return (0);
+ }
+
+ /* open directory for reading */
+ TARGET_NATIVE_FILE_OPEN_DIR (dirname, handle, result);
+
+ (*env)->ReleaseStringUTFChars (env, name, dirname);
+
+ if (result != TARGET_NATIVE_OK)
+ {
+ return (0);
+ }
+
+ /* allocate filelist */
+ filelist = (char **) JCL_malloc (env, sizeof (char *) * REALLOC_SIZE);
+ if (filelist == NULL)
+ {
+ TARGET_NATIVE_FILE_CLOSE_DIR (handle, result);
+ return (0);
+ }
+ filelist_count = 0;
+ max_filelist_count = REALLOC_SIZE;
+
+ /* read the files from the directory */
+ TARGET_NATIVE_FILE_READ_DIR (handle, filename, result);
+ while (result == TARGET_NATIVE_OK)
+ {
+ if ((strcmp (filename, ".") != 0) && (strcmp (filename, "..") != 0))
+ {
+ /* allocate more memory if necessary */
+ if (filelist_count >= max_filelist_count)
+ {
+ tmp_filelist = (char **) JCL_realloc (env,
+ filelist,
+ (max_filelist_count +
+ REALLOC_SIZE) *
+ sizeof (char *));
+ if (tmp_filelist == NULL)
+ {
+ for (i = 0; i < filelist_count; i++)
+ {
+ JCL_free (env, filelist[i]);
+ }
+ JCL_free (env, filelist);
+ TARGET_NATIVE_FILE_CLOSE_DIR (handle, result);
+ return (0);
+ }
+ filelist = tmp_filelist;
+ max_filelist_count += REALLOC_SIZE;
+ }
+
+ /* save entry in list (avoid strdup, because it is not ANSI C, thus difficult to port) */
+ filelist[filelist_count] =
+ (char *) JCL_malloc (env, strlen (filename) + 1);
+ assert (filelist[filelist_count] != NULL);
+ strcpy (filelist[filelist_count], filename);
+ filelist_count++;
+ }
+
+ /* read next directory entry */
+ TARGET_NATIVE_FILE_READ_DIR (handle, filename, result);
+ }
+
+ /* close directory */
+ TARGET_NATIVE_FILE_CLOSE_DIR (handle, result);
+
+ /* put the list of files into a Java String array and return it */
+ str_clazz = (*env)->FindClass (env, "java/lang/String");
+ if (str_clazz == NULL)
+ {
+ for (i = 0; i < filelist_count; i++)
+ {
+ JCL_free (env, filelist[i]);
+ }
+ JCL_free (env, filelist);
+ return (0);
+ }
+ filearray = (*env)->NewObjectArray (env, filelist_count, str_clazz, 0);
+ if (filearray == NULL)
+ {
+ for (i = 0; i < filelist_count; i++)
+ {
+ JCL_free (env, filelist[i]);
+ }
+ JCL_free (env, filelist);
+ return (0);
+ }
+ for (i = 0; i < filelist_count; i++)
+ {
+ /* create new string */
+ str = (*env)->NewStringUTF (env, filelist[i]);
+ if (str == NULL)
+ {
+ /* We don't clean up everything here, but if this failed,
+ something serious happened anyway */
+ for (i = 0; i < filelist_count; i++)
+ {
+ JCL_free (env, filelist[i]);
+ }
+ JCL_free (env, filelist);
+ return (0);
+ }
+
+ /* save into array */
+ (*env)->SetObjectArrayElement (env, filearray, i, str);
+
+ /* delete local reference */
+ (*env)->DeleteLocalRef (env, str);
+ }
+
+ /* free resources */
+ for (i = 0; i < filelist_count; i++)
+ {
+ JCL_free (env, filelist[i]);
+ }
+ JCL_free (env, filelist);
+
+ return (filearray);
+#else /* not WITHOUT_FILESYSTEM */
+ return (0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
diff --git a/libjava/classpath/native/jni/java-io/java_io_VMObjectInputStream.c b/libjava/classpath/native/jni/java-io/java_io_VMObjectInputStream.c
new file mode 100644
index 00000000000..d8d80714989
--- /dev/null
+++ b/libjava/classpath/native/jni/java-io/java_io_VMObjectInputStream.c
@@ -0,0 +1,69 @@
+/* java_io_VMObjectInputStream.c -- Native methods for ObjectInputStream class
+ Copyright (C) 1998, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+/* TODO: check exceptions */
+/* comments */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "java_io_VMObjectInputStream.h"
+
+/*
+ * Class: java_io_VMObjectInputStream
+ * Method: allocateObject
+ * Signature: (Ljava/lang/Class;)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL
+Java_java_io_VMObjectInputStream_allocateObject (JNIEnv * env,
+ jclass clazz
+ __attribute__((__unused__)),
+ jclass target_clazz,
+ jclass constr_clazz,
+ jobject constructor)
+{
+ jobject obj = (*env)->AllocObject (env, target_clazz);
+ jmethodID id = (*env)->FromReflectedMethod (env, constructor);
+
+ (*env)->CallNonvirtualVoidMethod (env, obj, constr_clazz, id);
+
+ return obj;
+}
diff --git a/libjava/classpath/native/jni/java-io/java_io_VMObjectStreamClass.c b/libjava/classpath/native/jni/java-io/java_io_VMObjectStreamClass.c
new file mode 100644
index 00000000000..8c2556bcf30
--- /dev/null
+++ b/libjava/classpath/native/jni/java-io/java_io_VMObjectStreamClass.c
@@ -0,0 +1,381 @@
+/* java_io_VMObjectStreamClass.c -- Native methods for VMObjectStreamClass.java
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include <jni.h>
+#include <jcl.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "java_io_VMObjectStreamClass.h"
+
+/*
+ * Class: java_io_VMObjectOutputStream
+ * Method: hasClassInitializer
+ * Signature: (Ljava/lang/Class;)Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_java_io_VMObjectStreamClass_hasClassInitializer (JNIEnv * env,
+ jclass vmosklass
+ __attribute__ ((__unused__)), jclass klass)
+{
+ jmethodID mid = (*env)->GetStaticMethodID (env, klass, "<clinit>", "()V");
+ if (mid == NULL)
+ {
+ (*env)->ExceptionClear (env);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+static void
+throwInternalError (JNIEnv * env)
+{
+ jclass internalErrorClass;
+ jthrowable previousException, newException;
+ jmethodID initException, getMessageID, initCauseID;
+ jstring message;
+
+ internalErrorClass = (*env)->FindClass (env, "java/lang/InternalError");
+ /** Just give up if this also fails. */
+ if (internalErrorClass == NULL)
+ return;
+
+ previousException = (*env)->ExceptionOccurred (env);
+
+ if (previousException == NULL)
+ {
+ (*env)->ThrowNew (env, internalErrorClass,
+ "Unknown error raised by the VM");
+ return;
+ }
+
+ initException = (*env)->GetMethodID
+ (env, internalErrorClass, "<init>", "(Ljava/lang/String;)V");
+ getMessageID = (*env)->GetMethodID
+ (env, (*env)->GetObjectClass (env, previousException),
+ "getMessage", "()Ljava/lang/String;");
+ initCauseID = (*env)->GetMethodID
+ (env, internalErrorClass, "initCause", "(Ljava/lang/Throwable;)V");
+
+ message = (*env)->CallObjectMethod (env, previousException, getMessageID);
+
+ newException = (*env)->NewObject (env, internalErrorClass, initException,
+ message);
+ (*env)->CallVoidMethod (env, newException, initCauseID, previousException);
+
+ (*env)->ExceptionClear (env);
+ (*env)->Throw (env, newException);
+}
+
+static jfieldID
+getFieldReference (JNIEnv * env, jobject field, const char *type)
+{
+ jclass classClass;
+ jclass fieldClass;
+ jclass declaringClass;
+ jclass typeClass;
+ jfieldID fid;
+ const char *field_name;
+ const char *type_name;
+ int type_len;
+ jmethodID mid;
+ jstring name;
+ jstring tname;
+ int i;
+
+ fieldClass = (*env)->GetObjectClass (env, field);
+
+ mid =
+ (*env)->GetMethodID (env, fieldClass, "getName", "()Ljava/lang/String;");
+ if (mid == NULL || (*env)->ExceptionOccurred (env) != NULL)
+ {
+ throwInternalError (env);
+ return NULL;
+ }
+
+ name = (*env)->CallObjectMethod (env, field, mid);
+ field_name = (*env)->GetStringUTFChars (env, name, NULL);
+
+ mid = (*env)->GetMethodID (env, fieldClass,
+ "getDeclaringClass", "()Ljava/lang/Class;");
+ if (mid == NULL || (*env)->ExceptionOccurred (env) != NULL)
+ {
+ throwInternalError (env);
+ return NULL;
+ }
+
+ declaringClass = (*env)->CallObjectMethod (env, field, mid);
+
+ /* Do we need to find out the exact type descriptor of the field? */
+ if (type == NULL)
+ {
+ char *the_type;
+
+ mid = (*env)->GetMethodID (env, fieldClass,
+ "getType", "()Ljava/lang/Class;");
+
+ if (mid == NULL || (*env)->ExceptionOccurred (env) != NULL)
+ {
+ throwInternalError (env);
+ return NULL;
+ }
+
+ typeClass = (*env)->CallObjectMethod (env, field, mid);
+ classClass = (*env)->FindClass (env, "java/lang/Class");
+
+ mid = (*env)->GetMethodID (env, classClass,
+ "getName", "()Ljava/lang/String;");
+
+ if (mid == NULL || (*env)->ExceptionOccurred (env) != NULL)
+ {
+ throwInternalError (env);
+ return NULL;
+ }
+
+ tname = (*env)->CallObjectMethod (env, typeClass, mid);
+ type_name = (*env)->GetStringUTFChars (env, tname, NULL);
+
+ /*
+ * If it isn't an array class then the actual field type descriptor
+ * starts with 'L', ends with ';' and has '/' instead of '.'.
+ */
+ type_len = strlen ((char *) type_name);
+ if (type_name[0] != '[')
+ {
+ /* XXX - FIXME - should not use dynamic allocation in core lib. */
+ the_type = (char *) malloc (type_len + 3);
+ the_type[0] = 'L';
+ the_type[type_len + 1] = ';';
+ the_type[type_len + 2] = '\0';
+ the_type++;
+ }
+ else
+ {
+ /* XXX - FIXME - should not use dynamic allocation in core lib. */
+ the_type = (char *) malloc (type_len + 1);
+ the_type[type_len] = '\0';
+ }
+
+ for (i = 0; i < type_len; i++)
+ if (type_name[i] == '.')
+ the_type[i] = '/';
+ else
+ the_type[i] = type_name[i];
+
+ if (type_name[0] != '[')
+ the_type--;
+
+ (*env)->ReleaseStringUTFChars (env, tname, type_name);
+ fid = (*env)->GetFieldID (env, declaringClass, field_name, the_type);
+ free (the_type);
+ }
+ else
+ {
+ type_len = -1;
+ fid = (*env)->GetFieldID (env, declaringClass, field_name, type);
+ }
+
+ if (fid == NULL)
+ {
+ throwInternalError (env);
+ return NULL;
+ }
+ (*env)->ReleaseStringUTFChars (env, name, field_name);
+
+ return fid;
+}
+
+/*
+ * Class: java_io_VMObjectOutputStream
+ * Method: setBooleanNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;Z)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setBooleanNative (JNIEnv * env,
+ jclass vmosklass
+ __attribute__ ((__unused__)), jobject field, jobject object, jboolean value)
+{
+ jfieldID fid = getFieldReference (env, field, "Z");
+
+ if (fid != NULL)
+ (*env)->SetBooleanField (env, object, fid, value);
+}
+
+/*
+ * Class: java_io_VMObjectOutputStream
+ * Method: setCharNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;C)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setCharNative (JNIEnv * env,
+ jclass vmosklass
+ __attribute__ ((__unused__)),
+ jobject field,
+ jobject object, jchar value)
+{
+ jfieldID fid = getFieldReference (env, field, "C");
+
+ if (fid != NULL)
+ (*env)->SetCharField (env, object, fid, value);
+}
+
+/*
+ * Class: java_io_VMObjectOutputStream
+ * Method: setByteNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;B)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setByteNative (JNIEnv * env,
+ jclass vmosklass
+ __attribute__ ((__unused__)),
+ jobject field,
+ jobject object, jbyte value)
+{
+ jfieldID fid = getFieldReference (env, field, "B");
+
+ if (fid != NULL)
+ (*env)->SetByteField (env, object, fid, value);
+}
+
+
+/*
+ * Class: java_io_VMObjectOutputStream
+ * Method: setShortNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;S)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setShortNative (JNIEnv * env,
+ jclass vmosklass
+ __attribute__ ((__unused__)),
+ jobject field,
+ jobject object, jshort value)
+{
+ jfieldID fid = getFieldReference (env, field, "S");
+
+ if (fid != NULL)
+ (*env)->SetShortField (env, object, fid, value);
+}
+
+/*
+ * Class: java_io_VMObjectOutputStream
+ * Method: setIntNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;I)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setIntNative (JNIEnv * env,
+ jclass vmosklass
+ __attribute__ ((__unused__)),
+ jobject field,
+ jobject object, jint value)
+{
+ jfieldID fid = getFieldReference (env, field, "I");
+
+ if (fid != NULL)
+ (*env)->SetIntField (env, object, fid, value);
+}
+
+
+/*
+ * Class: java_io_VMObjectOutputStream
+ * Method: setLongNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;J)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setLongNative (JNIEnv * env,
+ jclass vmosklass
+ __attribute__ ((__unused__)),
+ jobject field,
+ jobject object, jlong value)
+{
+ jfieldID fid = getFieldReference (env, field, "J");
+
+ if (fid != NULL)
+ (*env)->SetLongField (env, object, fid, value);
+}
+
+
+/*
+ * Class: java_io_VMObjectOutputStream
+ * Method: setFloatNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;F)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setFloatNative (JNIEnv * env,
+ jclass vmosklass
+ __attribute__ ((__unused__)),
+ jobject field,
+ jobject object, jfloat value)
+{
+ jfieldID fid = getFieldReference (env, field, "F");
+
+ if (fid != NULL)
+ (*env)->SetFloatField (env, object, fid, value);
+}
+
+/*
+ * Class: java_io_VMObjectOutputStream
+ * Method: setDoubleNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;D)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setDoubleNative (JNIEnv * env,
+ jclass vmosklass
+ __attribute__ ((__unused__)), jobject field, jobject object, jdouble value)
+{
+ jfieldID fid = getFieldReference (env, field, "D");
+
+ if (fid != NULL)
+ (*env)->SetDoubleField (env, object, fid, value);
+}
+
+/*
+ * Class: java_io_VMObjectOutputStream
+ * Method: setObjectNative
+ * Signature: (Ljava/lang/reflect/Field;Ljava/lang/Object;Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_io_VMObjectStreamClass_setObjectNative (JNIEnv * env,
+ jclass vmosklass
+ __attribute__ ((__unused__)), jobject field, jobject object, jobject value)
+{
+ jfieldID fid = getFieldReference (env, field, NULL);
+
+ if (fid != NULL)
+ (*env)->SetObjectField (env, object, fid, value);
+}
diff --git a/libjava/classpath/native/jni/java-io/javaio.c b/libjava/classpath/native/jni/java-io/javaio.c
new file mode 100644
index 00000000000..6dc3de8f041
--- /dev/null
+++ b/libjava/classpath/native/jni/java-io/javaio.c
@@ -0,0 +1,363 @@
+/* javaio.c - Common java.io native functions
+ Copyright (C) 1998, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "target_native.h"
+#ifndef WITHOUT_FILESYSTEM
+#include "target_native_file.h"
+#endif
+#include "target_native_math_int.h"
+
+#include "javaio.h"
+
+/*
+ * Function to open a file
+ */
+
+jint
+_javaio_open_read (JNIEnv * env, jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int fd;
+ int result;
+
+ filename = JCL_jstring_to_cstring (env, name);
+ if (filename == NULL)
+ return (-1);
+
+ TARGET_NATIVE_FILE_OPEN_READ (filename, fd, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+ if (result != TARGET_NATIVE_OK)
+ {
+ if (TARGET_NATIVE_LAST_ERROR () == TARGET_NATIVE_ERROR_NO_SUCH_FILE)
+ JCL_ThrowException (env,
+ "java/io/FileNotFoundException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ else
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ }
+
+ JCL_free_cstring (env, name, filename);
+ return (fd);
+#else /* not WITHOUT_FILESYSTEM */
+ return (-1);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*
+ * Function to open a file for reading/writing
+ */
+
+jint
+_javaio_open_readwrite (JNIEnv * env, jstring name)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *filename;
+ int fd;
+ int result;
+
+ filename = JCL_jstring_to_cstring (env, name);
+ if (filename == NULL)
+ return (-1);
+
+ TARGET_NATIVE_FILE_OPEN_READWRITE (filename, fd, result);
+ (*env)->ReleaseStringUTFChars (env, name, filename);
+ if (result != TARGET_NATIVE_OK)
+ {
+ if (TARGET_NATIVE_LAST_ERROR () == TARGET_NATIVE_ERROR_NO_SUCH_FILE)
+ JCL_ThrowException (env,
+ "java/io/FileNotFoundException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ else
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ }
+
+ JCL_free_cstring (env, name, filename);
+ return (fd);
+#else /* not WITHOUT_FILESYSTEM */
+ return (-1);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * Function to close a file
+ */
+
+void
+_javaio_close (JNIEnv * env, jint fd)
+{
+#ifndef WITHOUT_FILESYSTEM
+ int result;
+
+ if (fd != -1)
+ {
+ TARGET_NATIVE_FILE_CLOSE (fd, result);
+ if (result != TARGET_NATIVE_OK)
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ }
+#else /* not WITHOUT_FILESYSTEM */
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * Skips bytes in a file
+ */
+
+jlong
+_javaio_skip_bytes (JNIEnv * env, jint fd, jlong num_bytes)
+{
+#ifndef WITHOUT_FILESYSTEM
+ jlong current_offset, new_offset;
+ int result;
+
+ TARGET_NATIVE_FILE_SEEK_CURRENT (fd, TARGET_NATIVE_MATH_INT_INT64_CONST_0,
+ current_offset, result);
+ if (result != TARGET_NATIVE_OK)
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+
+ TARGET_NATIVE_FILE_SEEK_CURRENT (fd, num_bytes, new_offset, result);
+ if (result != TARGET_NATIVE_OK)
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+
+ return (TARGET_NATIVE_MATH_INT_INT64_SUB (new_offset, current_offset));
+#else /* not WITHOUT_FILESYSTEM */
+ return (TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * Gets the size of the file
+ */
+
+jlong
+_javaio_get_file_length (JNIEnv * env, jint fd)
+{
+#ifndef WITHOUT_FILESYSTEM
+ jlong length;
+ int result;
+
+ TARGET_NATIVE_FILE_SIZE (fd, length, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1);
+ }
+
+ return (length);
+#else /* not WITHOUT_FILESYSTEM */
+ return (TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * Reads data from a file
+ */
+
+jint
+_javaio_read (JNIEnv * env, jint fd, jarray buf, jint offset, jint len)
+{
+#ifndef WITHOUT_FILESYSTEM
+ jbyte *bufptr;
+ int bytesRead;
+ int result;
+
+ assert (offset >= 0);
+ assert (len >= 0);
+
+ if (len == 0)
+ return 0; /* Nothing todo, and GetByteArrayElements() seems undefined. */
+
+ bufptr = (*env)->GetByteArrayElements (env, buf, JNI_FALSE);
+ if (bufptr == NULL)
+ {
+ JCL_ThrowException (env, "java/io/IOException",
+ "Internal Error: get byte array fail");
+ return (-1);
+ }
+
+ TARGET_NATIVE_FILE_READ (fd, (bufptr + offset), len, bytesRead, result);
+ (*env)->ReleaseByteArrayElements (env, buf, bufptr, 0);
+ if (result != TARGET_NATIVE_OK)
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+
+ if (bytesRead == 0)
+ return (-1);
+
+ return (bytesRead);
+#else /* not WITHOUT_FILESYSTEM */
+ jbyte *bufptr;
+ int bytesRead;
+
+ assert (offset >= 0);
+ assert (len >= 0);
+
+ if ((fd == 0) || (fd == 1) || (fd == 2))
+ {
+ if (len == 0)
+ return 0; /* Nothing todo, and GetByteArrayElements() seems undefined. */
+
+ bufptr = (*env)->GetByteArrayElements (env, buf, JNI_FALSE);
+ if (bufptr == NULL)
+ {
+ JCL_ThrowException (env, "java/io/IOException",
+ "Internal Error: get byte array");
+ return (-1);
+ }
+
+ TARGET_NATIVE_FILE_READ (fd, (bufptr + offset), len, bytesRead, result);
+ (*env)->ReleaseByteArrayElements (env, buf, bufptr, 0);
+ if (result != TARGET_NATIVE_OK)
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+
+ if (bytesRead == 0)
+ return (-1);
+
+ return (bytesRead);
+ }
+ else
+ {
+ return (-1);
+ }
+#endif /* not WITHOUT_FILESYSTEM */
+}
+
+/*************************************************************************/
+
+/*
+ * Writes data to a file
+ */
+
+jint
+_javaio_write (JNIEnv * env, jint fd, jarray buf, jint offset, jint len)
+{
+#ifndef WITHOUT_FILESYSTEM
+ jbyte *bufptr;
+ int bytes_written;
+ int result;
+
+ if (len == 0)
+ return 0; /* Nothing todo, and GetByteArrayElements() seems undefined. */
+
+ bufptr = (*env)->GetByteArrayElements (env, buf, 0);
+ if (bufptr == NULL)
+ {
+ JCL_ThrowException (env, "java/io/IOException",
+ "Internal Error: get byte array");
+ return (-1);
+ }
+
+ TARGET_NATIVE_FILE_WRITE (fd, (bufptr + offset), len, bytes_written,
+ result);
+ (*env)->ReleaseByteArrayElements (env, buf, bufptr, 0);
+ if (result != TARGET_NATIVE_OK)
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+
+ if (bytes_written == 0)
+ return (-1);
+
+ return (bytes_written);
+#else /* not WITHOUT_FILESYSTEM */
+ jbyte *bufptr;
+ int bytesWritten;
+
+ if ((fd == 0) || (fd == 1) || (fd == 2))
+ {
+ if (len == 0)
+ return 0; /* Nothing todo, and GetByteArrayElements() seems undefined. */
+
+ bufptr = (*env)->GetByteArrayElements (env, buf, 0);
+ if (bufptr == NULL)
+ {
+ JCL_ThrowException (env, "java/io/IOException", "Internal Error");
+ return (-1);
+ }
+
+ TARGET_NATIVE_FILE_WRITE (fd, (bufptr + offset), len, bytes_written,
+ result);
+ (*env)->ReleaseByteArrayElements (env, buf, bufptr, 0);
+
+ if (bytes_written == -1)
+ JCL_ThrowException (env,
+ "java/io/IOException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+
+ if (bytes_written == 0)
+ return (-1);
+
+ return (bytes_written);
+ }
+ else
+ {
+ return (-1);
+ }
+#endif /* not WITHOUT_FILESYSTEM */
+}
diff --git a/libjava/classpath/native/jni/java-io/javaio.h b/libjava/classpath/native/jni/java-io/javaio.h
new file mode 100644
index 00000000000..2e4a8d1037f
--- /dev/null
+++ b/libjava/classpath/native/jni/java-io/javaio.h
@@ -0,0 +1,58 @@
+/* javaio.h - Declaration for common java.io native functions
+ Copyright (C) 1998, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#ifndef JAVAIO_H_INCLUDED
+#define JAVAIO_H_INCLUDED
+
+#include <stddef.h>
+
+/*
+ * Function Prototypes
+ */
+
+extern jlong _javaio_get_file_length(JNIEnv *, jint);
+extern jlong _javaio_skip_bytes(JNIEnv *, jint, jlong);
+extern jint _javaio_open(JNIEnv *, jstring, int);
+extern jint _javaio_open_read(JNIEnv *, jstring);
+extern jint _javaio_open_readwrite(JNIEnv *, jstring);
+extern void _javaio_close(JNIEnv *, jint fd);
+extern jint _javaio_read(JNIEnv *, jint, jarray, jint, jint);
+extern jint _javaio_write(JNIEnv *, jint, jarray, jint, jint);
+
+#endif /* JAVAIO_H_INCLUDED */
+
diff --git a/libjava/classpath/native/jni/java-lang/.cvsignore b/libjava/classpath/native/jni/java-lang/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/jni/java-lang/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/java-lang/Makefile.am b/libjava/classpath/native/jni/java-lang/Makefile.am
new file mode 100644
index 00000000000..34ffe00fba7
--- /dev/null
+++ b/libjava/classpath/native/jni/java-lang/Makefile.am
@@ -0,0 +1,16 @@
+pkglib_LTLIBRARIES = libjavalang.la libjavalangreflect.la
+
+libjavalang_la_SOURCES = java_lang_VMSystem.c \
+ java_lang_VMFloat.c \
+ java_lang_VMDouble.c \
+ java_lang_Math.c \
+ java_lang_VMProcess.c
+
+libjavalang_la_LIBADD = $(wildcard $(top_builddir)/native/fdlibm/*.lo) \
+ $(top_builddir)/native/jni/classpath/jcl.lo
+
+libjavalangreflect_la_SOURCES = java_lang_reflect_Array.c
+
+AM_LDFLAGS = @CLASSPATH_MODULE@
+AM_CPPFLAGS = @CLASSPATH_INCLUDES@ -I$(top_srcdir)/native/fdlibm
+AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
diff --git a/libjava/classpath/native/jni/java-lang/java_lang_Math.c b/libjava/classpath/native/jni/java-lang/java_lang_Math.c
new file mode 100644
index 00000000000..b4b88a77537
--- /dev/null
+++ b/libjava/classpath/native/jni/java-lang/java_lang_Math.c
@@ -0,0 +1,161 @@
+/* Math.c - java.lang.Math native functions
+ Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include <config.h>
+#include <java_lang_Math.h>
+#include <fdlibm.h>
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_sin
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return sin (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_cos
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return cos (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_tan
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return tan (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_asin
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return asin (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_acos
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return acos (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_atan
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return atan (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_atan2
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble y, jdouble x)
+{
+ return atan2 (y, x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_exp
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return exp (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_log
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return log (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_sqrt
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return sqrt (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_pow
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x, jdouble y)
+{
+ return pow (x, y);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_IEEEremainder
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x, jdouble y)
+{
+ return remainder (x, y);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_ceil
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return ceil (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_floor
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return floor (x);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_java_lang_Math_rint
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble x)
+{
+ return rint (x);
+}
diff --git a/libjava/classpath/native/jni/java-lang/java_lang_VMDouble.c b/libjava/classpath/native/jni/java-lang/java_lang_VMDouble.c
new file mode 100644
index 00000000000..6b4aed42d27
--- /dev/null
+++ b/libjava/classpath/native/jni/java-lang/java_lang_VMDouble.c
@@ -0,0 +1,381 @@
+/* VMDouble.c - java.lang.VMDouble native functions
+ Copyright (C) 1998, 1999, 2001, 2003, 2004i, 2005
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include <config.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "mprec.h"
+#include "fdlibm.h"
+#include "jcl.h"
+
+#include "java_lang_VMDouble.h"
+
+static jclass clsDouble;
+static jmethodID isNaNID;
+static jdouble NEGATIVE_INFINITY;
+static jdouble POSITIVE_INFINITY;
+static jdouble NaN;
+
+/*
+ * Class: java_lang_VMDouble
+ * Method: initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_lang_VMDouble_initIDs (JNIEnv * env, jclass cls __attribute__ ((__unused__)))
+{
+ jfieldID negInfID;
+ jfieldID posInfID;
+ jfieldID nanID;
+
+ clsDouble = (*env)->FindClass (env, "java/lang/Double");
+ if (clsDouble == NULL)
+ {
+ DBG ("unable to get class java.lang.Double\n") return;
+ }
+ isNaNID = (*env)->GetStaticMethodID (env, clsDouble, "isNaN", "(D)Z");
+ if (isNaNID == NULL)
+ {
+ DBG ("unable to determine method id of isNaN\n") return;
+ }
+ negInfID = (*env)->GetStaticFieldID (env, clsDouble, "NEGATIVE_INFINITY", "D");
+ if (negInfID == NULL)
+ {
+ DBG ("unable to determine field id of NEGATIVE_INFINITY\n") return;
+ }
+ posInfID = (*env)->GetStaticFieldID (env, clsDouble, "POSITIVE_INFINITY", "D");
+ if (posInfID == NULL)
+ {
+ DBG ("unable to determine field id of POSITIVE_INFINITY\n") return;
+ }
+ nanID = (*env)->GetStaticFieldID (env, clsDouble, "NaN", "D");
+ if (posInfID == NULL)
+ {
+ DBG ("unable to determine field id of NaN\n") return;
+ }
+ POSITIVE_INFINITY = (*env)->GetStaticDoubleField (env, clsDouble, posInfID);
+ NEGATIVE_INFINITY = (*env)->GetStaticDoubleField (env, clsDouble, negInfID);
+ NaN = (*env)->GetStaticDoubleField (env, clsDouble, nanID);
+
+#ifdef DEBUG
+ fprintf (stderr, "java.lang.Double.initIDs() POSITIVE_INFINITY = %g\n",
+ POSITIVE_INFINITY);
+ fprintf (stderr, "java.lang.Double.initIDs() NEGATIVE_INFINITY = %g\n",
+ NEGATIVE_INFINITY);
+ fprintf (stderr, "java.lang.Double.initIDs() NaN = %g\n", NaN);
+#endif
+}
+
+/*
+ * Class: java_lang_VMDouble
+ * Method: doubleToLongBits
+ * Signature: (D)J
+ */
+JNIEXPORT jlong JNICALL
+Java_java_lang_VMDouble_doubleToLongBits
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble doubleValue)
+{
+ jvalue val;
+ jlong e, f;
+ val.d = doubleValue;
+
+ e = val.j & 0x7ff0000000000000LL;
+ f = val.j & 0x000fffffffffffffLL;
+
+ if (e == 0x7ff0000000000000LL && f != 0L)
+ val.j = 0x7ff8000000000000LL;
+
+ return val.j;
+}
+
+/*
+ * Class: java_lang_VMDouble
+ * Method: doubleToRawLongBits
+ * Signature: (D)J
+ */
+JNIEXPORT jlong JNICALL
+Java_java_lang_VMDouble_doubleToRawLongBits
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jdouble doubleValue)
+{
+ jvalue val;
+ val.d = doubleValue;
+ return val.j;
+}
+
+/*
+ * Class: java_lang_VMDouble
+ * Method: longBitsToDouble
+ * Signature: (J)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_java_lang_VMDouble_longBitsToDouble
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jlong longValue)
+{
+ jvalue val;
+ val.j = longValue;
+ return val.d;
+}
+
+/*
+ * Class: java_lang_VMDouble
+ * Method: toString
+ * Signature: (DZ)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_java_lang_VMDouble_toString
+ (JNIEnv * env, jclass cls __attribute__ ((__unused__)), jdouble value, jboolean isFloat)
+{
+ char buffer[50], result[50];
+ int decpt, sign;
+ char *s, *d;
+ int i;
+
+#ifdef DEBUG
+ fprintf (stderr, "java.lang.VMDouble.toString (%g)\n", value);
+#endif
+
+ if ((*env)->CallStaticBooleanMethod (env, clsDouble, isNaNID, value))
+ return (*env)->NewStringUTF (env, "NaN");
+
+ if (value == POSITIVE_INFINITY)
+ return (*env)->NewStringUTF (env, "Infinity");
+
+ if (value == NEGATIVE_INFINITY)
+ return (*env)->NewStringUTF (env, "-Infinity");
+
+ _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int) isFloat);
+
+ value = fabs (value);
+
+ s = buffer;
+ d = result;
+
+ if (sign)
+ *d++ = '-';
+
+ if ((value >= 1e-3 && value < 1e7) || (value == 0))
+ {
+ if (decpt <= 0)
+ *d++ = '0';
+ else
+ {
+ for (i = 0; i < decpt; i++)
+ if (*s)
+ *d++ = *s++;
+ else
+ *d++ = '0';
+ }
+
+ *d++ = '.';
+
+ if (*s == 0)
+ {
+ *d++ = '0';
+ decpt++;
+ }
+
+ while (decpt++ < 0)
+ *d++ = '0';
+
+ while (*s)
+ *d++ = *s++;
+
+ *d = 0;
+
+ return (*env)->NewStringUTF (env, result);
+ }
+
+ *d++ = *s++;
+ decpt--;
+ *d++ = '.';
+
+ if (*s == 0)
+ *d++ = '0';
+
+ while (*s)
+ *d++ = *s++;
+
+ *d++ = 'E';
+
+ if (decpt < 0)
+ {
+ *d++ = '-';
+ decpt = -decpt;
+ }
+
+ {
+ char exp[4];
+ char *e = exp + sizeof exp;
+
+ *--e = 0;
+ do
+ {
+ *--e = '0' + decpt % 10;
+ decpt /= 10;
+ }
+ while (decpt > 0);
+
+ while (*e)
+ *d++ = *e++;
+ }
+
+ *d = 0;
+
+ return (*env)->NewStringUTF (env, result);
+}
+
+/*
+ * Class: java_lang_VMDouble
+ * Method: parseDouble
+ * Signature: (Ljava/lang/String;)D
+ */
+JNIEXPORT jdouble JNICALL
+Java_java_lang_VMDouble_parseDouble
+ (JNIEnv * env, jclass cls __attribute__ ((__unused__)), jstring str)
+{
+ jboolean isCopy;
+ const char *buf;
+ char *endptr;
+ jdouble val = 0.0;
+
+ if (str == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/NullPointerException", "null");
+ return val;
+ }
+
+ buf = (char *) (*env)->GetStringUTFChars (env, str, &isCopy);
+ if (buf == NULL)
+ {
+ /* OutOfMemoryError already thrown */
+ }
+ else
+ {
+ const char *p = buf, *end, *last_non_ws, *temp;
+ int ok = 1;
+
+#ifdef DEBUG
+ fprintf (stderr, "java.lang.VMDouble.parseDouble (%s)\n", buf);
+#endif
+
+ /* Trim the buffer, similar to String.trim(). First the leading
+ characters. */
+ while (*p && *p <= ' ')
+ ++p;
+
+ /* Find the last non-whitespace character. This method is safe
+ even with multi-byte UTF-8 characters. */
+ end = p;
+ last_non_ws = NULL;
+ while (*end)
+ {
+ if (*end > ' ')
+ last_non_ws = end;
+ ++end;
+ }
+
+ if (last_non_ws == NULL)
+ last_non_ws = p + strlen (p);
+ else
+ {
+ /* Skip past the last non-whitespace character. */
+ ++last_non_ws;
+ }
+
+ /* Check for infinity and NaN */
+ temp = p;
+ if (temp[0] == '+' || temp[0] == '-')
+ temp++;
+ if (strncmp ("Infinity", temp, (size_t) 8) == 0)
+ {
+ if (p[0] == '-')
+ return NEGATIVE_INFINITY;
+ return POSITIVE_INFINITY;
+ }
+ if (strncmp ("NaN", temp, (size_t) 3) == 0)
+ return NaN;
+
+ /* Skip a trailing `f' or `d'. */
+ if (last_non_ws > p
+ && (last_non_ws[-1] == 'f'
+ || last_non_ws[-1] == 'F'
+ || last_non_ws[-1] == 'd' || last_non_ws[-1] == 'D'))
+ --last_non_ws;
+
+ if (last_non_ws > p)
+ {
+ struct _Jv_reent reent;
+ memset (&reent, 0, sizeof reent);
+
+#ifdef KISSME_LINUX_USER
+ /* FIXME: The libc strtod may not be reliable. */
+ val = strtod (p, &endptr);
+#else
+ val = _strtod_r (&reent, p, &endptr);
+#endif
+
+#ifdef DEBUG
+ fprintf (stderr, "java.lang.VMDouble.parseDouble val = %g\n", val);
+ fprintf (stderr, "java.lang.VMDouble.parseDouble %i != %i ???\n",
+ endptr, last_non_ws);
+#endif
+ if (endptr != last_non_ws)
+ ok = 0;
+ }
+ else
+ ok = 0;
+
+ if (!ok)
+ {
+ val = 0.0;
+ JCL_ThrowException (env,
+ "java/lang/NumberFormatException",
+ "unable to parse double");
+ }
+
+ (*env)->ReleaseStringUTFChars (env, str, buf);
+ }
+
+ return val;
+}
diff --git a/libjava/classpath/native/jni/java-lang/java_lang_VMFloat.c b/libjava/classpath/native/jni/java-lang/java_lang_VMFloat.c
new file mode 100644
index 00000000000..7bff629fc89
--- /dev/null
+++ b/libjava/classpath/native/jni/java-lang/java_lang_VMFloat.c
@@ -0,0 +1,93 @@
+/* VMFloat.c - java.lang.VMFloat native functions
+ Copyright (C) 1998, 1999, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include <config.h>
+
+#include "java_lang_VMFloat.h"
+
+/*
+ * Class: java_lang_VMFloat
+ * Method: floatToIntBits
+ * Signature: (F)I
+ */
+JNIEXPORT jint JNICALL
+Java_java_lang_VMFloat_floatToIntBits
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jfloat value)
+{
+ jvalue u;
+ jint e, f;
+ u.f = value;
+ e = u.i & 0x7f800000;
+ f = u.i & 0x007fffff;
+
+ if (e == 0x7f800000 && f != 0)
+ u.i = 0x7fc00000;
+
+ return u.i;
+}
+
+/*
+ * Class: java_lang_VMFloat
+ * Method: floatToRawIntBits
+ * Signature: (F)I
+ */
+JNIEXPORT jint JNICALL
+Java_java_lang_VMFloat_floatToRawIntBits
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jfloat value)
+{
+ jvalue u;
+ u.f = value;
+ return u.i;
+}
+
+/*
+ * Class: java_lang_VMFloat
+ * Method: intBitsToFloat
+ * Signature: (I)F
+ */
+JNIEXPORT jfloat JNICALL
+Java_java_lang_VMFloat_intBitsToFloat
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass cls __attribute__ ((__unused__)), jint bits)
+{
+ jvalue u;
+ u.i = bits;
+ return u.f;
+}
diff --git a/libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c b/libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c
new file mode 100644
index 00000000000..c1090ed3736
--- /dev/null
+++ b/libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c
@@ -0,0 +1,494 @@
+/* java_lang_VMProcess.c -- native code for java.lang.VMProcess
+ Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <config.h>
+
+#include "java_lang_VMProcess.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+#include "target_native.h"
+#include "target_native_misc.h"
+
+/* Internal functions */
+static char *copy_string (JNIEnv * env, jobject string);
+static char *copy_elem (JNIEnv * env, jobject stringArray, jint i);
+
+/* Some O/S's don't declare 'environ' */
+#if HAVE_CRT_EXTERNS_H
+/* Darwin does not have a variable named environ
+ but has a function which you can get the environ
+ variable with. */
+#include <crt_externs.h>
+#define environ (*_NSGetEnviron())
+#else
+extern char **environ;
+#endif /* HAVE_CRT_EXTERNS_H */
+
+/*
+ * Internal helper function to copy a String in UTF-8 format.
+ */
+static char *
+copy_string (JNIEnv * env, jobject string)
+{
+ char errbuf[64];
+ const char *utf;
+ jclass clazz;
+ char *copy;
+
+ /* Check for null */
+ if (string == NULL)
+ {
+ clazz = (*env)->FindClass (env, "java/lang/NullPointerException");
+ if ((*env)->ExceptionOccurred (env))
+ return NULL;
+ (*env)->ThrowNew (env, clazz, NULL);
+ (*env)->DeleteLocalRef (env, clazz);
+ return NULL;
+ }
+
+ /* Extract UTF-8 */
+ utf = (*env)->GetStringUTFChars (env, string, NULL);
+ if ((*env)->ExceptionOccurred (env))
+ return NULL;
+
+ /* Copy it */
+ if ((copy = strdup (utf)) == NULL)
+ {
+ TARGET_NATIVE_MISC_FORMAT_STRING1 (errbuf, sizeof (errbuf),
+ "strdup: %s", strerror (errno));
+ clazz = (*env)->FindClass (env, "java/lang/InternalError");
+ if ((*env)->ExceptionOccurred (env))
+ return NULL;
+ (*env)->ThrowNew (env, clazz, errbuf);
+ (*env)->DeleteLocalRef (env, clazz);
+ }
+
+ /* Done */
+ (*env)->ReleaseStringUTFChars (env, string, utf);
+ return copy;
+}
+
+/*
+ * Internal helper function to copy a String[] element in UTF-8 format.
+ */
+static char *
+copy_elem (JNIEnv * env, jobject stringArray, jint i)
+{
+ jobject elem;
+ char *rtn;
+
+ elem = (*env)->GetObjectArrayElement (env, stringArray, i);
+ if ((*env)->ExceptionOccurred (env))
+ return NULL;
+ if ((rtn = copy_string (env, elem)) == NULL)
+ return NULL;
+ (*env)->DeleteLocalRef (env, elem);
+ return rtn;
+}
+
+/*
+ * private final native void nativeSpawn(String[], String[], File)
+ * throws java/io/IOException
+ */
+JNIEXPORT void JNICALL
+Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this,
+ jobjectArray cmdArray,
+ jobjectArray envArray, jobject dirFile)
+{
+ int fds[3][2] = { {-1, -1}, {-1, -1}, {-1, -1} };
+ jobject streams[3] = { NULL, NULL, NULL };
+ jobject dirString = NULL;
+ char **newEnviron = NULL;
+ jsize cmdArrayLen = 0;
+ jsize envArrayLen = 0;
+ char **strings = NULL;
+ int num_strings = 0;
+ char *dir = NULL;
+ pid_t pid = -1;
+ char errbuf[64];
+ jmethodID method;
+ jclass clazz;
+ int i;
+
+ /* Check for null */
+ if (cmdArray == NULL)
+ goto null_pointer_exception;
+
+ /* Invoke dirFile.getPath() */
+ if (dirFile != NULL)
+ {
+ clazz = (*env)->FindClass (env, "java/io/File");
+ if ((*env)->ExceptionOccurred (env))
+ return;
+ method = (*env)->GetMethodID (env,
+ clazz, "getPath", "()Ljava/lang/String;");
+ if ((*env)->ExceptionOccurred (env))
+ return;
+ dirString = (*env)->CallObjectMethod (env, dirFile, method);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+ (*env)->DeleteLocalRef (env, clazz);
+ }
+
+ /*
+ * Allocate array of C strings. We put all the C strings we need to
+ * handle the command parameters, the new environment, and the new
+ * directory into a single array for simplicity of (de)allocation.
+ */
+ cmdArrayLen = (*env)->GetArrayLength (env, cmdArray);
+ if (cmdArrayLen == 0)
+ goto null_pointer_exception;
+ if (envArray != NULL)
+ envArrayLen = (*env)->GetArrayLength (env, envArray);
+ if ((strings = malloc (((cmdArrayLen + 1)
+ + (envArray != NULL ? envArrayLen + 1 : 0)
+ + (dirString !=
+ NULL ? 1 : 0)) * sizeof (*strings))) == NULL)
+ {
+ TARGET_NATIVE_MISC_FORMAT_STRING1 (errbuf,
+ sizeof (errbuf), "malloc: %s",
+ strerror (errno));
+ goto out_of_memory;
+ }
+
+ /* Extract C strings from the various String parameters */
+ for (i = 0; i < cmdArrayLen; i++)
+ {
+ if ((strings[num_strings++] = copy_elem (env, cmdArray, i)) == NULL)
+ goto done;
+ }
+ strings[num_strings++] = NULL; /* terminate array with NULL */
+ if (envArray != NULL)
+ {
+ newEnviron = strings + num_strings;
+ for (i = 0; i < envArrayLen; i++)
+ {
+ if ((strings[num_strings++] = copy_elem (env, envArray, i)) == NULL)
+ goto done;
+ }
+ strings[num_strings++] = NULL; /* terminate array with NULL */
+ }
+ if (dirString != NULL)
+ {
+ if ((dir = copy_string (env, dirString)) == NULL)
+ goto done;
+ strings[num_strings++] = dir;
+ }
+
+ /* Create inter-process pipes */
+ for (i = 0; i < 3; i++)
+ {
+ if (pipe (fds[i]) == -1)
+ {
+ TARGET_NATIVE_MISC_FORMAT_STRING1 (errbuf,
+ sizeof (errbuf), "pipe: %s",
+ strerror (errno));
+ goto system_error;
+ }
+ }
+
+ /* Set close-on-exec flag for parent's ends of pipes */
+ (void) fcntl (fds[0][1], F_SETFD, 1);
+ (void) fcntl (fds[1][0], F_SETFD, 1);
+ (void) fcntl (fds[2][0], F_SETFD, 1);
+
+ /* Fork into parent and child processes */
+ if ((pid = fork ()) == (pid_t) - 1)
+ {
+ TARGET_NATIVE_MISC_FORMAT_STRING1 (errbuf,
+ sizeof (errbuf), "fork: %s",
+ strerror (errno));
+ goto system_error;
+ }
+
+ /* Child becomes the new process */
+ if (pid == 0)
+ {
+ char *const path = strings[0];
+
+ /* Move file descriptors to standard locations */
+ if (fds[0][0] != 0)
+ {
+ if (dup2 (fds[0][0], 0) == -1)
+ {
+ fprintf (stderr, "dup2: %s", strerror (errno));
+ exit (127);
+ }
+ close (fds[0][0]);
+ }
+ if (fds[1][1] != 1)
+ {
+ if (dup2 (fds[1][1], 1) == -1)
+ {
+ fprintf (stderr, "dup2: %s", strerror (errno));
+ exit (127);
+ }
+ close (fds[1][1]);
+ }
+ if (fds[2][1] != 2)
+ {
+ if (dup2 (fds[2][1], 2) == -1)
+ {
+ fprintf (stderr, "dup2: %s", strerror (errno));
+ exit (127);
+ }
+ close (fds[2][1]);
+ }
+
+ /* Change into destination directory */
+ if (dir != NULL && chdir (dir) == -1)
+ {
+ fprintf (stderr, "%s: %s", dir, strerror (errno));
+ exit (127);
+ }
+
+ /* Make argv[0] last component of executable pathname */
+ /* XXX should use "file.separator" property here XXX */
+ for (i = strlen (path); i > 0 && path[i - 1] != '/'; i--);
+ strings[0] = path + i;
+
+ /* Set new environment */
+ if (newEnviron != NULL)
+ environ = newEnviron;
+
+ /* Execute new program (this will close the parent end of the pipes) */
+ execvp (path, strings);
+
+ /* Failed */
+ fprintf (stderr, "%s: %s", path, strerror (errno));
+ exit (127);
+ }
+
+ /* Create Input/OutputStream objects around parent file descriptors */
+ clazz = (*env)->FindClass (env, "gnu/java/nio/channels/FileChannelImpl");
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+ method = (*env)->GetMethodID (env, clazz, "<init>", "(II)V");
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+ for (i = 0; i < 3; i++)
+ {
+ /* Mode is WRITE (2) for in and READ (1) for out and err. */
+ const int fd = fds[i][i == 0];
+ const int mode = (i == 0) ? 2 : 1;
+ jclass sclazz;
+ jmethodID smethod;
+
+ jobject channel = (*env)->NewObject (env, clazz, method, fd, mode);
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+
+ if (mode == 2)
+ sclazz = (*env)->FindClass (env, "java/io/FileOutputStream");
+ else
+ sclazz = (*env)->FindClass (env, "java/io/FileInputStream");
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+
+ smethod = (*env)->GetMethodID (env, sclazz, "<init>",
+ "(Lgnu/java/nio/channels/FileChannelImpl;)V");
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+
+ streams[i] = (*env)->NewObject (env, sclazz, smethod, channel);
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+
+ (*env)->DeleteLocalRef (env, sclazz);
+ }
+ (*env)->DeleteLocalRef (env, clazz);
+
+ /* Invoke VMProcess.setProcessInfo() to update VMProcess object */
+ method = (*env)->GetMethodID (env,
+ (*env)->GetObjectClass (env, this),
+ "setProcessInfo",
+ "(Ljava/io/OutputStream;Ljava/io/InputStream;Ljava/io/InputStream;J)V");
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+ (*env)->CallVoidMethod (env, this, method,
+ streams[0], streams[1], streams[2], (jlong) pid);
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+ (*env)->DeleteLocalRef (env, clazz);
+
+done:
+ /*
+ * We get here in both the success and failure cases in the
+ * parent process. Our goal is to clean up the mess we created.
+ */
+
+ /* Close child's ends of pipes */
+ for (i = 0; i < 3; i++)
+ {
+ const int fd = fds[i][i != 0];
+
+ if (fd != -1)
+ close (fd);
+ }
+
+ /*
+ * Close parent's ends of pipes if Input/OutputStreams never got created.
+ * This can only happen in a failure case. If a Stream object
+ * was created for a file descriptor, we don't close it because it
+ * will get closed when the Stream object is finalized.
+ */
+ for (i = 0; i < 3; i++)
+ {
+ const int fd = fds[i][i == 0];
+
+ if (fd != -1 && streams[i] == NULL)
+ close (fd);
+ }
+
+ /* Free C strings */
+ while (num_strings > 0)
+ free (strings[--num_strings]);
+ free (strings);
+
+ /* Done */
+ return;
+
+null_pointer_exception:
+ clazz = (*env)->FindClass (env, "java/lang/NullPointerException");
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+ (*env)->ThrowNew (env, clazz, NULL);
+ (*env)->DeleteLocalRef (env, clazz);
+ goto done;
+
+out_of_memory:
+ clazz = (*env)->FindClass (env, "java/lang/InternalError");
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+ (*env)->ThrowNew (env, clazz, errbuf);
+ (*env)->DeleteLocalRef (env, clazz);
+ goto done;
+
+system_error:
+ clazz = (*env)->FindClass (env, "java/io/IOException");
+ if ((*env)->ExceptionOccurred (env))
+ goto done;
+ (*env)->ThrowNew (env, clazz, errbuf);
+ (*env)->DeleteLocalRef (env, clazz);
+ goto done;
+}
+
+/*
+ * private static final native boolean nativeReap()
+ */
+JNIEXPORT jboolean JNICALL
+Java_java_lang_VMProcess_nativeReap (JNIEnv * env, jclass clazz)
+{
+ char ebuf[64];
+ jfieldID field;
+ jint status;
+ pid_t pid;
+
+ /* Try to reap a child process, but don't block */
+ if ((pid = waitpid ((pid_t) - 1, &status, WNOHANG)) == 0)
+ return JNI_FALSE;
+
+ /* Check result from waitpid() */
+ if (pid == (pid_t) - 1)
+ {
+ if (errno == ECHILD || errno == EINTR)
+ return JNI_FALSE;
+ TARGET_NATIVE_MISC_FORMAT_STRING2 (ebuf,
+ sizeof (ebuf), "waitpid(%ld): %s",
+ (long) pid, strerror (errno));
+ clazz = (*env)->FindClass (env, "java/lang/InternalError");
+ if ((*env)->ExceptionOccurred (env))
+ return JNI_FALSE;
+ (*env)->ThrowNew (env, clazz, ebuf);
+ (*env)->DeleteLocalRef (env, clazz);
+ return JNI_FALSE;
+ }
+
+ /* Get exit code; for signal termination return negative signal value XXX */
+ if (WIFEXITED (status))
+ status = (jint) (jbyte) WEXITSTATUS (status);
+ else if (WIFSIGNALED (status))
+ status = -(jint) WTERMSIG (status);
+ else
+ return JNI_FALSE; /* process merely stopped; ignore */
+
+ /* Return process pid and exit status */
+ field = (*env)->GetStaticFieldID (env, clazz, "reapedPid", "J");
+ if ((*env)->ExceptionOccurred (env))
+ return JNI_FALSE;
+ (*env)->SetStaticLongField (env, clazz, field, (jlong) pid);
+ if ((*env)->ExceptionOccurred (env))
+ return JNI_FALSE;
+ field = (*env)->GetStaticFieldID (env, clazz, "reapedExitValue", "I");
+ if ((*env)->ExceptionOccurred (env))
+ return JNI_FALSE;
+ (*env)->SetStaticIntField (env, clazz, field, status);
+ if ((*env)->ExceptionOccurred (env))
+ return JNI_FALSE;
+
+ /* Done */
+ return JNI_TRUE;
+}
+
+/*
+ * private static final native void nativeKill(long)
+ */
+JNIEXPORT void JNICALL
+Java_java_lang_VMProcess_nativeKill (JNIEnv * env, jclass clazz, jlong pid)
+{
+ char ebuf[64];
+
+ if (kill ((pid_t) pid, SIGKILL) == -1)
+ {
+ TARGET_NATIVE_MISC_FORMAT_STRING2 (ebuf,
+ sizeof (ebuf), "kill(%ld): %s",
+ (long) pid, strerror (errno));
+ clazz = (*env)->FindClass (env, "java/lang/InternalError");
+ if ((*env)->ExceptionOccurred (env))
+ return;
+ (*env)->ThrowNew (env, clazz, ebuf);
+ (*env)->DeleteLocalRef (env, clazz);
+ }
+}
diff --git a/libjava/classpath/native/jni/java-lang/java_lang_VMSystem.c b/libjava/classpath/native/jni/java-lang/java_lang_VMSystem.c
new file mode 100644
index 00000000000..0edbb2e965a
--- /dev/null
+++ b/libjava/classpath/native/jni/java-lang/java_lang_VMSystem.c
@@ -0,0 +1,156 @@
+/* System.c -- native code for java.lang.System
+ Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "java_lang_VMSystem.h"
+
+#include <jcl.h>
+
+#include <sys/time.h>
+#include <stdlib.h>
+
+/*
+ * Class: java_lang_VMSystem
+ * Method: setIn0
+ * Signature: (Ljava/io/InputStream;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_lang_VMSystem_setIn (JNIEnv * env,
+ jclass thisClass __attribute__ ((__unused__)),
+ jobject obj)
+{
+ jclass cls;
+ jfieldID field;
+
+ cls = JCL_FindClass (env, "java/lang/System");
+ if (!cls)
+ return;
+
+ field = (*env)->GetStaticFieldID (env, cls, "in", "Ljava/io/InputStream;");
+ if (!field)
+ return;
+ (*env)->SetStaticObjectField (env, cls, field, obj);
+}
+
+/*
+ * Class: java_lang_VMSystem
+ * Method: setOut0
+ * Signature: (Ljava/io/PrintStream;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_lang_VMSystem_setOut (JNIEnv * env,
+ jclass thisClass __attribute__ ((__unused__)),
+ jobject obj)
+{
+ jclass cls;
+ jfieldID field;
+
+ cls = JCL_FindClass (env, "java/lang/System");
+ if (!cls)
+ return;
+
+ field = (*env)->GetStaticFieldID (env, cls, "out", "Ljava/io/PrintStream;");
+ if (!field)
+ return;
+ (*env)->SetStaticObjectField (env, cls, field, obj);
+}
+
+/*
+ * Class: java_lang_VMSystem
+ * Method: setErr0
+ * Signature: (Ljava/io/PrintStream;)V
+ */
+JNIEXPORT void JNICALL
+Java_java_lang_VMSystem_setErr (JNIEnv * env,
+ jclass thisClass __attribute__ ((__unused__)),
+ jobject obj)
+{
+ jclass cls;
+ jfieldID field;
+
+ cls = JCL_FindClass (env, "java/lang/System");
+ if (!cls)
+ return;
+
+ field = (*env)->GetStaticFieldID (env, cls, "err", "Ljava/io/PrintStream;");
+ if (!field)
+ return;
+ (*env)->SetStaticObjectField (env, cls, field, obj);
+}
+
+/*
+ * Class: java_lang_VMSystem
+ * Method: currentTimeMillis
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL
+Java_java_lang_VMSystem_currentTimeMillis
+ (JNIEnv * env __attribute__ ((__unused__)),
+ jclass thisClass __attribute__ ((__unused__)))
+{
+ /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
+ jlong result;
+ struct timeval tp;
+
+ if (gettimeofday (&tp, NULL) == -1)
+ (*env)->FatalError (env, "gettimeofday call failed.");
+
+ result = (jlong) tp.tv_sec;
+ result *= 1000;
+ result += (tp.tv_usec / 1000);
+
+ return result;
+}
+
+JNIEXPORT jstring JNICALL
+Java_java_lang_VMSystem_getenv (JNIEnv * env,
+ jclass klass __attribute__ ((__unused__)),
+ jstring jname)
+{
+ const char *cname;
+ const char *envname;
+
+ cname = JCL_jstring_to_cstring (env, jname);
+ if (cname == NULL)
+ return NULL;
+
+ envname = getenv (cname);
+ if (envname == NULL)
+ return NULL;
+
+ JCL_free_cstring (env, jname, cname);
+ return (*env)->NewStringUTF (env, envname);
+}
diff --git a/libjava/classpath/native/jni/java-lang/java_lang_reflect_Array.c b/libjava/classpath/native/jni/java-lang/java_lang_reflect_Array.c
new file mode 100644
index 00000000000..0bd23c16ffc
--- /dev/null
+++ b/libjava/classpath/native/jni/java-lang/java_lang_reflect_Array.c
@@ -0,0 +1,61 @@
+/* java.lang.reflect.Array native functions
+ Copyright (C) 1998, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+ * java.lang.reflect.Array native functions.
+ * Author: John Keiser
+ * Version: 1.1.0
+ * Date: 2 Jun 1998
+ */
+
+#include <stddef.h>
+
+#include "java_lang_reflect_Array.h"
+
+/*
+ * Class: java_lang_reflect_Array
+ * Method: createObjectArray
+ * Signature: (Ljava/lang/Class;I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL
+Java_java_lang_reflect_Array_createObjectArray
+ (JNIEnv * env,
+ jclass thisClass __attribute__ ((__unused__)),
+ jclass arrayType, jint arrayLength)
+{
+ return (jobject) (*env)->NewObjectArray (env, arrayLength, arrayType, NULL);
+}
diff --git a/libjava/classpath/native/jni/java-net/.cvsignore b/libjava/classpath/native/jni/java-net/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/java-net/Makefile.am b/libjava/classpath/native/jni/java-net/Makefile.am
new file mode 100644
index 00000000000..3e8c863a9a9
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/Makefile.am
@@ -0,0 +1,14 @@
+pkglib_LTLIBRARIES = libjavanet.la
+
+libjavanet_la_SOURCES = javanet.c \
+ javanet.h \
+ java_net_VMInetAddress.c \
+ java_net_VMNetworkInterface.c \
+ gnu_java_net_PlainDatagramSocketImpl.c \
+ gnu_java_net_PlainSocketImpl.c
+
+libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo
+
+AM_LDFLAGS = @CLASSPATH_MODULE@
+AM_CPPFLAGS = @CLASSPATH_INCLUDES@
+AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
diff --git a/libjava/classpath/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c b/libjava/classpath/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c
new file mode 100644
index 00000000000..5bc284f6426
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c
@@ -0,0 +1,452 @@
+/* PlainDatagramSocketImpl.c - Native methods for PlainDatagramSocketImpl class
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "javanet.h"
+
+#include "target_native.h"
+#ifndef WITHOUT_NETWORK
+#include "target_native_network.h"
+#endif /* WITHOUT_NETWORK */
+
+#include "gnu_java_net_PlainDatagramSocketImpl.h"
+
+/*
+ * Note that most of the functions in this module simply redirect to another
+ * internal function. Why? Because many of these functions are shared
+ * with PlainSocketImpl.
+ */
+
+/*************************************************************************/
+
+/*
+ * Creates a new datagram socket
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_create (JNIEnv * env, jobject obj)
+{
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ _javanet_create (env, obj, 0);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Close the socket.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_close (JNIEnv * env, jobject obj)
+{
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ _javanet_close (env, obj, 0);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method binds the specified address to the specified local port.
+ * Note that we have to set the local address and local port public instance
+ * variables.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_bind (JNIEnv * env, jobject obj,
+ jint port, jobject addr)
+{
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ _javanet_bind (env, obj, addr, port, 0);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method sets the specified option for a socket
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_setOption (JNIEnv * env,
+ jobject obj,
+ jint option_id,
+ jobject val)
+{
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ _javanet_set_option (env, obj, option_id, val);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method sets the specified option for a socket
+ */
+JNIEXPORT jobject JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_getOption (JNIEnv * env,
+ jobject obj,
+ jint option_id)
+{
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ return (_javanet_get_option (env, obj, option_id));
+#else /* not WITHOUT_NETWORK */
+ return NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Reads a buffer from a remote host
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_receive0 (JNIEnv * env, jobject obj,
+ jobject packet)
+{
+#ifndef WITHOUT_NETWORK
+ int addr, port, bytes_read;
+ unsigned int maxlen, offset;
+ jclass cls, addr_cls;
+ jfieldID fid;
+ jmethodID mid;
+ jarray arr;
+ unsigned char octets[4];
+ char ip_str[16];
+ jobject ip_str_obj, addr_obj;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ addr = 0;
+ port = 0;
+ maxlen = 0;
+ offset = 0;
+ bytes_read = 0;
+
+ if (packet == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/NullPointerException",
+ "Null datagram packet");
+ return;
+ }
+
+ /* Get the buffer from the packet */
+ cls = (*env)->GetObjectClass (env, packet);
+ if (cls == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error");
+ return;
+ }
+
+ mid = (*env)->GetMethodID (env, cls, "getData", "()[B");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: getData");
+ return;
+ }
+
+ arr = (*env)->CallObjectMethod (env, packet, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+ if (arr == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: call getData");
+ return;
+ }
+
+ /* Now get the offset from the packet */
+ mid = (*env)->GetMethodID (env, cls, "getOffset", "()I");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: getOffset");
+ return;
+ }
+
+ offset = (*env)->CallIntMethod (env, packet, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.receive(): Got the offset\n");
+
+ /* Now get the maximal available length from the packet */
+ fid = (*env)->GetFieldID (env, cls, "maxlen", "I");
+ if (fid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: maxlen");
+ return;
+ }
+
+ maxlen = (*env)->GetIntField (env, packet, fid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ /* Receive the packet */
+ /* should we try some sort of validation on the length? */
+ bytes_read =
+ _javanet_recvfrom (env, obj, arr, offset, maxlen, &addr, &port);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+ if (bytes_read == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: receive");
+ return;
+ }
+
+ DBG ("PlainDatagramSocketImpl.receive(): Received packet\n");
+
+ /* Store the address */
+ TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES (addr,
+ octets[0],
+ octets[1],
+ octets[2], octets[3]);
+ sprintf (ip_str, "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]);
+ ip_str_obj = (*env)->NewStringUTF (env, ip_str);
+ if (ip_str_obj == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: new string");
+ return;
+ }
+
+ addr_cls = (*env)->FindClass (env, "java/net/InetAddress");
+ if (addr_cls == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: InetAddress class");
+ return;
+ }
+ DBG ("PlainDatagramSocketImpl.receive(): Found InetAddress class\n");
+
+ mid = (*env)->GetStaticMethodID (env, addr_cls, "getByName",
+ "(Ljava/lang/String;)Ljava/net/InetAddress;");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal Error");
+ return;
+ }
+ DBG
+ ("PlainDatagramSocketImpl.receive(): Found InetAddress.getByName method\n");
+
+ addr_obj = (*env)->CallStaticObjectMethod (env, addr_cls, mid, ip_str_obj);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ mid = (*env)->GetMethodID (env, cls, "setAddress",
+ "(Ljava/net/InetAddress;)V");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: setAddress");
+ return;
+ }
+
+ (*env)->CallVoidMethod (env, packet, mid, addr_obj);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.receive(): Stored the address\n");
+
+ /* Store the port */
+ mid = (*env)->GetMethodID (env, cls, "setPort", "(I)V");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: setPort");
+ return;
+ }
+
+ (*env)->CallVoidMethod (env, packet, mid, port);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.receive(): Stored the port\n");
+
+ /* Store back the length */
+ fid = (*env)->GetFieldID (env, cls, "length", "I");
+ if (fid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: length");
+ return;
+ }
+
+ (*env)->SetIntField (env, packet, fid, bytes_read);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.receive(): Stored the length\n");
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Writes a buffer to the remote host
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_sendto (JNIEnv * env, jobject obj,
+ jobject addr, jint port,
+ jarray buf, jint offset,
+ jint len)
+{
+#ifndef WITHOUT_NETWORK
+ jint netAddress;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ netAddress = _javanet_get_netaddr (env, addr);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.sendto(): have addr\n");
+
+ _javanet_sendto (env, obj, buf, offset, len, netAddress, port);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.sendto(): finished\n");
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Joins a multicast group
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_join (JNIEnv * env, jobject obj,
+ jobject addr)
+{
+#ifndef WITHOUT_NETWORK
+ jint netAddress;
+ int fd;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ netAddress = _javanet_get_netaddr (env, addr);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ fd = _javanet_get_int_field (env, obj, "native_fd");
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.join(): have native fd\n");
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_ADD_MEMBERSHIP (fd, netAddress,
+ result);
+
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ DBG ("PlainDatagramSocketImpl.join(): finished\n");
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Leaves a multicast group
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_leave (JNIEnv * env, jobject obj,
+ jobject addr)
+{
+#ifndef WITHOUT_NETWORK
+ jint netAddress;
+ int fd;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ netAddress = _javanet_get_netaddr (env, addr);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ fd = _javanet_get_int_field (env, obj, "native_fd");
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.leave(): have native fd\n");
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_DROP_MEMBERSHIP (fd, netAddress,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ DBG ("PlainDatagramSocketImpl.leave(): finished\n");
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
diff --git a/libjava/classpath/native/jni/java-net/gnu_java_net_PlainSocketImpl.c b/libjava/classpath/native/jni/java-net/gnu_java_net_PlainSocketImpl.c
new file mode 100644
index 00000000000..a5261514dce
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/gnu_java_net_PlainSocketImpl.c
@@ -0,0 +1,320 @@
+/* PlainSocketImpl.c - Native methods for PlainSocketImpl class
+ Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "javanet.h"
+
+#include "target_native.h"
+#ifndef WITHOUT_NETWORK
+#include "target_native_network.h"
+#endif /* WITHOUT_NETWORK */
+
+#include "gnu_java_net_PlainSocketImpl.h"
+
+/*
+ * Note that the functions in this module simply redirect to another
+ * internal function. Why? Because many of these functions are shared
+ * with PlainDatagramSocketImpl. The unshared ones were done the same
+ * way for consistency.
+ */
+
+/*************************************************************************/
+
+/*
+ * Creates a new stream or datagram socket
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_create (JNIEnv * env, jobject this,
+ jboolean stream)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_create (env, this, stream);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Close the socket. Any underlying streams will be closed by this
+ * action as well.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_close (JNIEnv * env, jobject this)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_close (env, this, 1);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Connects to the specified destination.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_connect (JNIEnv * env, jobject this,
+ jobject addr, jint port)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_connect (env, this, addr, port);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method binds the specified address to the specified local port.
+ * Note that we have to set the local address and local port public instance
+ * variables.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_bind (JNIEnv * env, jobject this,
+ jobject addr, jint port)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_bind (env, this, addr, port, 1);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Starts listening on a socket with the specified number of pending
+ * connections allowed.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_listen (JNIEnv * env, jobject this,
+ jint queuelen)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_listen (env, this, queuelen);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Accepts a new connection and assigns it to the passed in SocketImpl
+ * object. Note that we assume this is a PlainSocketImpl just like us.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_accept (JNIEnv * env, jobject this,
+ jobject impl)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_accept (env, this, impl);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_net_PlainSocketImpl_available (JNIEnv * env, jobject this)
+{
+#ifndef WITHOUT_NETWORK
+ jclass cls;
+ jfieldID fid;
+ int fd;
+ int bytesAvailable;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ cls = (*env)->GetObjectClass (env, this);
+ if (cls == 0)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "internal error");
+ return 0;
+ }
+
+ fid = (*env)->GetFieldID (env, cls, "native_fd", "I");
+ if (fid == 0)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "internal error");
+ return 0;
+ }
+
+ fd = (*env)->GetIntField (env, this, fid);
+
+ TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_AVAILABLE (fd, bytesAvailable, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return 0;
+ }
+
+ return bytesAvailable;
+#else /* not WITHOUT_NETWORK */
+ return 0;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method sets the specified option for a socket
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_setOption (JNIEnv * env, jobject this,
+ jint option_id, jobject val)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_set_option (env, this, option_id, val);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method sets the specified option for a socket
+ */
+JNIEXPORT jobject JNICALL
+Java_gnu_java_net_PlainSocketImpl_getOption (JNIEnv * env, jobject this,
+ jint option_id)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ return (_javanet_get_option (env, this, option_id));
+#else /* not WITHOUT_NETWORK */
+ return NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Reads a buffer from a remote host
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_net_PlainSocketImpl_read (JNIEnv * env, jobject this,
+ jarray buf, jint offset, jint len)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ return (_javanet_recvfrom (env, this, buf, offset, len, 0, 0));
+#else /* not WITHOUT_NETWORK */
+ return 0;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Writes a buffer to the remote host
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_write (JNIEnv * env, jobject this,
+ jarray buf, jint offset, jint len)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_sendto (env, this, buf, offset, len, 0, 0);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_shutdownInput (JNIEnv * env, jobject this)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_shutdownInput (env, this);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_shutdownOutput (JNIEnv * env, jobject this)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_shutdownOutput (env, this);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/* end of file */
diff --git a/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c b/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c
new file mode 100644
index 00000000000..d33265cff7e
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c
@@ -0,0 +1,282 @@
+/* VMInetAddress.c - Native methods for InetAddress class
+ Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "javanet.h"
+
+#include "target_native.h"
+#ifndef WITHOUT_NETWORK
+#include "target_native_network.h"
+#endif /* WITHOUT_NETWORK */
+
+#include "java_net_VMInetAddress.h"
+
+/*************************************************************************/
+
+/*
+ * Function to return the local hostname
+ */
+JNIEXPORT jstring JNICALL
+Java_java_net_VMInetAddress_getLocalHostname (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)))
+{
+ char hostname[256];
+ int result;
+ jstring retval;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ TARGET_NATIVE_NETWORK_GET_HOSTNAME (hostname, sizeof (hostname), result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ strcpy (hostname, "localhost");
+ }
+#else /* not WITHOUT_NETWORK */
+ strcpy (hostname, "localhost");
+#endif /* not WITHOUT_NETWORK */
+
+ retval = (*env)->NewStringUTF (env, hostname);
+
+ return (retval);
+}
+
+/*************************************************************************/
+
+/*
+ * Returns the value of the special IP address INADDR_ANY
+ */
+JNIEXPORT jarray JNICALL
+Java_java_net_VMInetAddress_lookupInaddrAny (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)))
+{
+ jarray IParray;
+ jbyte *octets;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Allocate an array for the IP address */
+ IParray = (*env)->NewByteArray (env, 4);
+ if (IParray == NULL)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ return (jarray) NULL;
+ }
+
+ /* Copy in the values */
+ octets = (*env)->GetByteArrayElements (env, IParray, 0);
+
+#ifndef WITHOUT_NETWORK
+ TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES (INADDR_ANY,
+ octets[0],
+ octets[1],
+ octets[2], octets[3]);
+ (*env)->ReleaseByteArrayElements (env, IParray, octets, 0);
+#else /* not WITHOUT_NETWORK */
+ octets[0] = 0;
+ octets[1] = 0;
+ octets[2] = 0;
+ octets[3] = 0;
+#endif /* not WITHOUT_NETWORK */
+
+ return (IParray);
+}
+
+/*************************************************************************/
+
+/*
+ * Function to return the canonical hostname for a given IP address passed
+ * in as a byte array
+ */
+JNIEXPORT jstring JNICALL
+Java_java_net_VMInetAddress_getHostByAddr (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)),
+ jarray arr)
+{
+#ifndef WITHOUT_NETWORK
+ jbyte *octets;
+ jsize len;
+ int addr;
+ char hostname[255];
+ int result;
+ jstring retval;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Grab the byte[] array with the IP out of the input data */
+ len = (*env)->GetArrayLength (env, arr);
+ if (len != 4)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
+ return (jstring) NULL;
+ }
+
+ octets = (*env)->GetByteArrayElements (env, arr, 0);
+ if (!octets)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
+ return (jstring) NULL;
+ }
+
+ /* Convert it to a 32 bit address */
+ TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0],
+ octets[1],
+ octets[2], octets[3], addr);
+
+ /* Release some memory */
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+
+ /* Resolve the address and return the name */
+ TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_ADDRESS (addr, hostname,
+ sizeof (hostname), result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP address");
+ return (jstring) NULL;
+ }
+
+ retval = (*env)->NewStringUTF (env, hostname);
+
+ return (retval);
+#else /* not WITHOUT_NETWORK */
+ return (jstring) NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+JNIEXPORT jobjectArray JNICALL
+Java_java_net_VMInetAddress_getHostByName (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)),
+ jstring host)
+{
+#ifndef WITHOUT_NETWORK
+ const char *hostname;
+/* FIXME: limitation of max. 64 addresses - how to make it more flexibale? */
+ int addresses[64];
+ jsize addresses_count;
+ int result;
+ jclass arr_class;
+ jobjectArray addrs;
+ int i;
+ jbyte *octets;
+ jarray ret_octets;
+ int max_addresses;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Grab the hostname string */
+ hostname = (*env)->GetStringUTFChars (env, host, 0);
+ if (!hostname)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
+ return (jobjectArray) NULL;
+ }
+
+ max_addresses = sizeof (addresses) / sizeof (addresses[0]);
+ TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_NAME (hostname,
+ addresses,
+ max_addresses,
+ addresses_count, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, (char *) hostname);
+ return (jobjectArray) NULL;
+ }
+ (*env)->ReleaseStringUTFChars (env, host, hostname);
+
+ arr_class = (*env)->FindClass (env, "[B");
+ if (!arr_class)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ return (jobjectArray) NULL;
+ }
+
+ addrs = (*env)->NewObjectArray (env, addresses_count, arr_class, 0);
+ if (!addrs)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ return (jobjectArray) NULL;
+ }
+
+ /* Now loop and copy in each address */
+ for (i = 0; i < addresses_count; i++)
+ {
+ ret_octets = (*env)->NewByteArray (env, 4);
+ if (!ret_octets)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ return (jobjectArray) NULL;
+ }
+
+ octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
+
+ TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES (addresses[i],
+ octets[0],
+ octets[1],
+ octets[2], octets[3]);
+
+ (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
+
+ (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
+ }
+
+ return (addrs);
+#else /* not WITHOUT_NETWORK */
+ return (jobjectArray) NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/* end of file */
diff --git a/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c b/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c
new file mode 100644
index 00000000000..71f5e8927e5
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c
@@ -0,0 +1,66 @@
+/* VMNetworkInterface.c - Native methods for NetworkInterface class
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "java_net_VMNetworkInterface.h"
+
+#include "javanet.h"
+
+/*
+ * Returns all local network interfaces as vector
+ */
+JNIEXPORT jobject JNICALL
+Java_java_net_VMNetworkInterface_getInterfaces (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)))
+{
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "java.net.VMNetworkInterface.getInterfaces(): not implemented");
+ return 0;
+}
+
+/* end of file */
diff --git a/libjava/classpath/native/jni/java-net/javanet.c b/libjava/classpath/native/jni/java-net/javanet.c
new file mode 100644
index 00000000000..fdc1c22ecbf
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/javanet.c
@@ -0,0 +1,1577 @@
+/* javanet.c - Common internal functions for the java.net package
+ Copyright (C) 1998, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "javanet.h"
+
+#include "target_native.h"
+#ifndef WITHOUT_NETWORK
+#include "target_native_network.h"
+#endif /* WITHOUT_NETWORK */
+
+#ifndef WITHOUT_NETWORK
+/* Need to have some value for SO_TIMEOUT */
+#ifndef SO_TIMEOUT
+#ifndef SO_RCVTIMEO
+#warning Neither SO_TIMEOUT or SO_RCVTIMEO are defined!
+#warning This will cause all get/setOption calls with that value to throw an exception
+#else
+#define SO_TIMEOUT SO_RCVTIMEO
+#endif /* not SO_RCVTIMEO */
+#endif /* not SO_TIMEOUT */
+#endif /* WITHOUT_NETWORK */
+
+/*************************************************************************/
+
+/*
+ * Sets an integer field in the specified object.
+ */
+static void
+_javanet_set_int_field (JNIEnv * env, jobject obj,
+ const char *class, const char *field, int val)
+{
+ jclass cls;
+ jfieldID fid;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ cls = (*env)->FindClass (env, class);
+ if (cls == NULL)
+ return;
+
+ fid = (*env)->GetFieldID (env, cls, field, "I");
+ if (fid == NULL)
+ return;
+
+ (*env)->SetIntField (env, obj, fid, val);
+
+ return;
+}
+
+/*************************************************************************/
+
+/*
+ * Returns the value of the specified integer instance variable field or
+ * -1 if an error occurs.
+ */
+int
+_javanet_get_int_field (JNIEnv * env, jobject obj, const char *field)
+{
+ jclass cls = 0;
+ jfieldID fid;
+ int fd;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_get_int_field(): Entered _javanet_get_int_field\n");
+
+ cls = (*env)->GetObjectClass (env, obj);
+ if (cls == NULL)
+ return -1;
+
+ fid = (*env)->GetFieldID (env, cls, field, "I");
+ if (fid == NULL)
+ return -1;
+ DBG ("_javanet_get_int_field(): Found field id\n");
+
+ fd = (*env)->GetIntField (env, obj, fid);
+
+ return fd;
+}
+
+/*************************************************************************/
+
+/*
+ * Creates a FileDescriptor object in the parent class. It is not used
+ * by this implementation, but the docs list it as a variable, so we
+ * need to include it.
+ */
+static void
+_javanet_create_localfd (JNIEnv * env, jobject this)
+{
+ jclass this_cls, fd_cls;
+ jfieldID fid;
+ jmethodID mid;
+ jobject fd_obj;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_create_localfd(): Entered _javanet_create_localfd\n");
+
+ /* Look up the fd field */
+ this_cls = (*env)->FindClass (env, "java/net/SocketImpl");
+ if (this_cls == NULL)
+ return;
+
+ fid = (*env)->GetFieldID (env, this_cls, "fd", "Ljava/io/FileDescriptor;");
+ if (fid == NULL)
+ return;
+
+ DBG ("_javanet_create_localfd(): Found fd variable\n");
+
+ /* Create a FileDescriptor */
+ fd_cls = (*env)->FindClass (env, "java/io/FileDescriptor");
+ if (fd_cls == NULL)
+ return;
+
+ DBG ("_javanet_create_localfd(): Found FileDescriptor class\n");
+
+ mid = (*env)->GetMethodID (env, fd_cls, "<init>", "()V");
+ if (mid == NULL)
+ return;
+
+ DBG ("_javanet_create_localfd(): Found FileDescriptor constructor\n");
+
+ fd_obj = (*env)->NewObject (env, fd_cls, mid);
+ if (fd_obj == NULL)
+ return;
+
+ DBG ("_javanet_create_localfd(): Created FileDescriptor\n");
+
+ /* Now set the pointer to the new FileDescriptor */
+ (*env)->SetObjectField (env, this, fid, fd_obj);
+ DBG ("_javanet_create_localfd(): Set fd field\n");
+
+ return;
+}
+
+/*************************************************************************/
+
+/*
+ * Returns a Boolean object with the specfied value
+ */
+static jobject
+_javanet_create_boolean (JNIEnv * env, jboolean val)
+{
+ jclass cls;
+ jmethodID mid;
+ jobject obj;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ cls = (*env)->FindClass (env, "java/lang/Boolean");
+ if (cls == NULL)
+ return NULL;
+
+ mid = (*env)->GetMethodID (env, cls, "<init>", "(Z)V");
+ if (mid == NULL)
+ return NULL;
+
+ obj = (*env)->NewObject (env, cls, mid, val);
+ if (obj == NULL)
+ return NULL;
+
+ return obj;
+}
+
+/*************************************************************************/
+
+/*
+ * Returns an Integer object with the specfied value
+ */
+static jobject
+_javanet_create_integer (JNIEnv * env, jint val)
+{
+ jclass cls;
+ jmethodID mid;
+ jobject obj;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ cls = (*env)->FindClass (env, "java/lang/Integer");
+ if (cls == NULL)
+ return NULL;
+
+ mid = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
+ if (mid == NULL)
+ return NULL;
+
+ obj = (*env)->NewObject (env, cls, mid, val);
+ if (obj == NULL)
+ return NULL;
+
+ return obj;
+}
+
+/*************************************************************************/
+
+/*
+ * Builds an InetAddress object from a 32 bit address in host byte order
+ */
+static jobject
+_javanet_create_inetaddress (JNIEnv * env, int netaddr)
+{
+#ifndef WITHOUT_NETWORK
+ unsigned char octets[4];
+ char buf[16];
+ jclass ia_cls;
+ jmethodID mid;
+ jstring ip_str;
+ jobject ia;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Build a string IP address */
+ TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES (netaddr,
+ octets[0],
+ octets[1],
+ octets[2], octets[3]);
+ sprintf (buf, "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]);
+ DBG ("_javanet_create_inetaddress(): Created ip addr string\n");
+
+ /* Get an InetAddress object for this IP */
+ ia_cls = (*env)->FindClass (env, "java/net/InetAddress");
+ if (ia_cls == NULL)
+ {
+ return NULL;
+ }
+
+ DBG ("_javanet_create_inetaddress(): Found InetAddress class\n");
+
+ mid = (*env)->GetStaticMethodID (env, ia_cls, "getByName",
+ "(Ljava/lang/String;)Ljava/net/InetAddress;");
+ if (mid == NULL)
+ {
+ return NULL;
+ }
+
+ DBG ("_javanet_create_inetaddress(): Found getByName method\n");
+
+ ip_str = (*env)->NewStringUTF (env, buf);
+ if (ip_str == NULL)
+ {
+ return NULL;
+ }
+
+ ia = (*env)->CallStaticObjectMethod (env, ia_cls, mid, ip_str);
+ if (ia == NULL)
+ {
+ return NULL;
+ }
+
+ DBG ("_javanet_create_inetaddress(): Called getByName method\n");
+
+ return ia;
+#else /* not WITHOUT_NETWORK */
+ return NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+static void
+_javanet_set_remhost_addr (JNIEnv * env, jobject this, jobject ia)
+{
+ jclass this_cls;
+ jfieldID fid;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Set the variable in the object */
+ this_cls = (*env)->FindClass (env, "java/net/SocketImpl");
+ if (this_cls == NULL)
+ return;
+
+ fid =
+ (*env)->GetFieldID (env, this_cls, "address", "Ljava/net/InetAddress;");
+ if (fid == NULL)
+ return;
+
+ DBG ("_javanet_set_remhost_addr(): Found address field\n");
+
+ (*env)->SetObjectField (env, this, fid, ia);
+ DBG ("_javanet_set_remhost_addr(): Set field\n");
+}
+
+/*
+ * Set's the value of the "addr" field in PlainSocketImpl with a new
+ * InetAddress for the specified addr
+ */
+static void
+_javanet_set_remhost (JNIEnv * env, jobject this, int netaddr)
+{
+ jobject ia;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_set_remhost(): Entered _javanet_set_remhost\n");
+
+ /* Get an InetAddress object */
+ ia = _javanet_create_inetaddress (env, netaddr);
+ if (ia == NULL)
+ return;
+
+ _javanet_set_remhost_addr (env, this, ia);
+}
+
+
+/*************************************************************************/
+
+/*
+ * Returns a 32 bit Internet address for the passed in InetAddress object
+ */
+int
+_javanet_get_netaddr (JNIEnv * env, jobject addr)
+{
+#ifndef WITHOUT_NETWORK
+ jclass cls = 0;
+ jmethodID mid;
+ jarray arr = 0;
+ jbyte *octets;
+ int netaddr, len;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_get_netaddr(): Entered _javanet_get_netaddr\n");
+
+ if (addr == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/NullPointerException",
+ "Null address");
+ return 0;
+ }
+
+ /* Call the getAddress method on the object to retrieve the IP address */
+ cls = (*env)->GetObjectClass (env, addr);
+ if (cls == NULL)
+ return 0;
+
+ mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B");
+ if (mid == NULL)
+ return 0;
+
+ DBG ("_javanet_get_netaddr(): Got getAddress method\n");
+
+ arr = (*env)->CallObjectMethod (env, addr, mid);
+ if (arr == NULL)
+ return 0;
+
+ DBG ("_javanet_get_netaddr(): Got the address\n");
+
+ /* Turn the IP address into a 32 bit Internet address in network byte order */
+ len = (*env)->GetArrayLength (env, arr);
+ if (len != 4)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal Error");
+ return 0;
+ }
+ DBG ("_javanet_get_netaddr(): Length ok\n");
+
+ octets = (*env)->GetByteArrayElements (env, arr, 0);
+ if (octets == NULL)
+ return 0;
+
+ DBG ("_javanet_get_netaddr(): Grabbed bytes\n");
+
+ TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0],
+ octets[1],
+ octets[2],
+ octets[3], netaddr);
+
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+ DBG ("_javanet_get_netaddr(): Done getting addr\n");
+
+ return netaddr;
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Creates a new stream or datagram socket
+ */
+void
+_javanet_create (JNIEnv * env, jobject this, jboolean stream)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ if (stream)
+ {
+ /* create a stream socket */
+ TARGET_NATIVE_NETWORK_SOCKET_OPEN_STREAM (fd, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ }
+ else
+ {
+ /* create a datagram socket, set broadcast option */
+ TARGET_NATIVE_NETWORK_SOCKET_OPEN_DATAGRAM (fd, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_BROADCAST (fd, 1, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ }
+
+ if (stream)
+ _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl",
+ "native_fd", fd);
+ else
+ _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl",
+ "native_fd", fd);
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* Try to make sure we close the socket since close() won't work. */
+ do
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ if (result != TARGET_NATIVE_OK
+ && (TARGET_NATIVE_LAST_ERROR ()
+ != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ return;
+ }
+ while (result != TARGET_NATIVE_OK);
+ return;
+ }
+
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Close the socket. Any underlying streams will be closed by this
+ * action as well.
+ */
+void
+_javanet_close (JNIEnv * env, jobject this, int stream)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ int result;
+ int error = 0;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ return;
+
+ if (stream)
+ _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl",
+ "native_fd", -1);
+ else
+ _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl",
+ "native_fd", -1);
+ do
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ /* Only throw an error when a "real" error occurs. */
+ error = TARGET_NATIVE_LAST_ERROR ();
+ if (error != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL
+ && error != ENOTCONN && error != ECONNRESET && error != EBADF)
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ }
+ }
+ while (error == TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL);
+
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Connects to the specified destination.
+ */
+void
+_javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port)
+{
+#ifndef WITHOUT_NETWORK
+ int netaddr, fd;
+ int result;
+ int local_address, local_port;
+ int remote_address, remote_port;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_connect(): Entered _javanet_connect\n");
+
+ /* Pre-process input variables */
+ netaddr = _javanet_get_netaddr (env, addr);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ if (port == -1)
+ port = 0;
+ DBG ("_javanet_connect(): Got network address\n");
+
+ /* Grab the real socket file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_connect(): no native file descriptor");
+ return;
+ }
+ DBG ("_javanet_connect(): Got native fd\n");
+
+ /* Connect up */
+ do
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_CONNECT (fd, netaddr, port, result);
+ if (result != TARGET_NATIVE_OK
+ && (TARGET_NATIVE_LAST_ERROR ()
+ != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ }
+ while (result != TARGET_NATIVE_OK);
+
+ DBG ("_javanet_connect(): Connected successfully\n");
+
+ /* Populate instance variables */
+ TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (fd, local_address, local_port,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+
+ _javanet_create_localfd (env, this);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+ DBG ("_javanet_connect(): Created fd\n");
+
+ _javanet_set_int_field (env, this, "java/net/SocketImpl", "localport",
+ local_port);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+ DBG ("_javanet_connect(): Set the local port\n");
+
+ TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO (fd, remote_address,
+ remote_port, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+
+ if (remote_address == netaddr)
+ {
+ _javanet_set_remhost_addr (env, this, addr);
+ }
+ else
+ {
+ _javanet_set_remhost (env, this, remote_address);
+ }
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+ DBG ("_javanet_connect(): Set the remote host\n");
+
+ _javanet_set_int_field (env, this, "java/net/SocketImpl", "port",
+ remote_port);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+ DBG ("_javanet_connect(): Set the remote port\n");
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method binds the specified address to the specified local port.
+ * Note that we have to set the local address and local
+ * port public instance variables.
+ */
+void
+_javanet_bind (JNIEnv * env, jobject this, jobject addr, jint port,
+ int stream)
+{
+#ifndef WITHOUT_NETWORK
+ jclass cls;
+ jmethodID mid;
+ jbyteArray arr = 0;
+ jbyte *octets;
+ jint fd;
+ int tmpaddr;
+ int result;
+ int local_address, local_port;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_bind(): Entering native bind()\n");
+
+ /* Get the address to connect to */
+ cls = (*env)->GetObjectClass (env, addr);
+ if (cls == NULL)
+ return;
+
+ mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B");
+ if (mid == NULL)
+ return;
+
+ DBG ("_javanet_bind(): Past getAddress method id\n");
+
+ arr = (*env)->CallObjectMethod (env, addr, mid);
+ if ((arr == NULL) || (*env)->ExceptionOccurred (env))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_bind()");
+ return;
+ }
+
+ DBG ("_javanet_bind(): Past call object method\n");
+
+ octets = (*env)->GetByteArrayElements (env, arr, 0);
+ if (octets == NULL)
+ return;
+
+ DBG ("_javanet_bind(): Past grab array\n");
+
+ /* Get the native socket file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_bind(): no native file descriptor");
+ return;
+ }
+ DBG ("_javanet_bind(): Past native_fd lookup\n");
+
+ /* XXX NYI ??? */
+ _javanet_set_option (env, this, SOCKOPT_SO_REUSEADDR,
+ _javanet_create_boolean (env, JNI_TRUE));
+
+
+ /* Bind the socket */
+ TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0],
+ octets[1],
+ octets[2],
+ octets[3], tmpaddr);
+ TARGET_NATIVE_NETWORK_SOCKET_BIND (fd, tmpaddr, port, result);
+
+ if (result != TARGET_NATIVE_OK)
+ {
+ char *errorstr = TARGET_NATIVE_LAST_ERROR_STRING ();
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+
+ JCL_ThrowException (env, BIND_EXCEPTION,
+ errorstr);
+ return;
+ }
+ DBG ("_javanet_bind(): Past bind\n");
+
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+
+ /* Update instance variables, specifically the local port number */
+ TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (fd, local_address, local_port,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ if (stream)
+ _javanet_set_int_field (env, this, "java/net/SocketImpl",
+ "localport", local_port);
+ else
+ _javanet_set_int_field (env, this, "java/net/DatagramSocketImpl",
+ "localPort", local_port);
+ DBG ("_javanet_bind(): Past update port number\n");
+
+ return;
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Starts listening on a socket with the specified number of pending
+ * connections allowed.
+ */
+void
+_javanet_listen (JNIEnv * env, jobject this, jint queuelen)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_listen(): no native file descriptor");
+ return;
+ }
+
+ /* Start listening */
+ TARGET_NATIVE_NETWORK_SOCKET_LISTEN (fd, queuelen, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Accepts a new connection and assigns it to the passed in SocketImpl
+ * object. Note that we assume this is a PlainSocketImpl just like us
+ */
+void
+_javanet_accept (JNIEnv * env, jobject this, jobject impl)
+{
+#ifndef WITHOUT_NETWORK
+ int fd, newfd;
+ int result;
+ int local_address, local_port;
+ int remote_address, remote_port;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_accept(): no native file descriptor");
+ return;
+ }
+
+ /* Accept the connection */
+ do
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_ACCEPT (fd, newfd, result);
+ if (result != TARGET_NATIVE_OK
+ && (TARGET_NATIVE_LAST_ERROR ()
+ != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_accept(): ");
+ return;
+ }
+ }
+ while (result != TARGET_NATIVE_OK);
+
+ /* Populate instance variables */
+ _javanet_set_int_field (env, impl, "gnu/java/net/PlainSocketImpl",
+ "native_fd", newfd);
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* Try to make sure we close the socket since close() won't work. */
+ do
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ if (result != TARGET_NATIVE_OK
+ && (TARGET_NATIVE_LAST_ERROR ()
+ != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ return;
+ }
+ while (result != TARGET_NATIVE_OK);
+ return;
+ }
+
+ TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (newfd, local_address,
+ local_port, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ _javanet_create_localfd (env, impl);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ return;
+ }
+
+ _javanet_set_int_field (env, impl, "java/net/SocketImpl", "localport",
+ local_port);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ return;
+ }
+
+ TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO (newfd, remote_address,
+ remote_port, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ return;
+ }
+
+ _javanet_set_remhost (env, impl, remote_address);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ return;
+ }
+
+ _javanet_set_int_field (env, impl, "java/net/SocketImpl", "port",
+ remote_port);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ return;
+ }
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Receives a buffer from a remote host. The args are:
+ *
+ * buf - The byte array into which the data received will be written
+ * offset - Offset into the byte array to start writing
+ * len - The number of bytes to read.
+ * addr - Pointer to 32 bit net address of host to receive from. If null,
+ * this parm is ignored. If pointing to an address of 0, the
+ * actual address read is stored here
+ * port - Pointer to the port to receive from. If null, this parm is ignored.
+ * If it is 0, the actual remote port received from is stored here
+ *
+ * The actual number of bytes read is returned.
+ */
+int
+_javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset,
+ int len, int *addr, int *port)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ jbyte *p;
+ int from_address, from_port;
+ int received_bytes;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_recvfrom(): Entered _javanet_recvfrom\n");
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_recvfrom(): no native file descriptor");
+ return 0;
+ }
+ DBG ("_javanet_recvfrom(): Got native_fd\n");
+
+ /* Get a pointer to the buffer */
+ p = (*env)->GetByteArrayElements (env, buf, 0);
+ if (p == NULL)
+ return 0;
+
+ DBG ("_javanet_recvfrom(): Got buffer\n");
+
+ /* Read the data */
+ from_address = 0;
+ from_port = 0;
+ do
+ {
+ if (addr != NULL)
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_WITH_ADDRESS_PORT (fd,
+ p + offset,
+ len,
+ from_address,
+ from_port,
+ received_bytes);
+ }
+ else
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_RECEIVE (fd, p + offset, len,
+ received_bytes);
+ }
+ }
+ while ((received_bytes == -1) &&
+ (TARGET_NATIVE_LAST_ERROR () ==
+ TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL));
+
+ if (received_bytes == -1)
+ {
+ if (TARGET_NATIVE_LAST_ERROR () == EAGAIN)
+ JCL_ThrowException (env, "java/net/SocketTimeoutException", "Timeout");
+ else
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+
+ /* Cleanup and return. */
+ (*env)->ReleaseByteArrayElements (env, buf, p, 0);
+ return 0;
+ }
+
+ (*env)->ReleaseByteArrayElements (env, buf, p, 0);
+
+ /* Handle return addr case */
+ if (addr != NULL)
+ {
+ (*addr) = from_address;
+ if (port != NULL)
+ (*port) = from_port;
+ }
+
+ return (received_bytes);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Sends a buffer to a remote host. The args are:
+ *
+ * buf - A byte array
+ * offset - Index into the byte array to start sendign
+ * len - The number of bytes to write
+ * addr - The 32bit address to send to (may be 0)
+ * port - The port number to send to (may be 0)
+ */
+void
+_javanet_sendto (JNIEnv * env, jobject this, jarray buf, int offset, int len,
+ int addr, int port)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ jbyte *p;
+ int bytes_sent;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_sendto(): no native file descriptor");
+ return;
+ }
+
+ /* Get a pointer to the buffer */
+ p = (*env)->GetByteArrayElements (env, buf, 0);
+ if (p == NULL)
+ return;
+
+ /* We must send all the data, so repeat till done. */
+ while (len > 0)
+ {
+ /* Send the data */
+ if (addr == 0)
+ {
+ DBG ("_javanet_sendto(): Sending....\n");
+ TARGET_NATIVE_NETWORK_SOCKET_SEND (fd, p + offset, len, bytes_sent);
+ }
+ else
+ {
+ DBG ("_javanet_sendto(): Sending....\n");
+ TARGET_NATIVE_NETWORK_SOCKET_SEND_WITH_ADDRESS_PORT (fd, p + offset,
+ len, addr, port,
+ bytes_sent);
+ }
+
+ if (bytes_sent < 0)
+ {
+ if (TARGET_NATIVE_LAST_ERROR ()
+ != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ break;
+ }
+ }
+ else
+ {
+ len -= bytes_sent;
+ addr += bytes_sent;
+ }
+ }
+
+ (*env)->ReleaseByteArrayElements (env, buf, p, 0);
+
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Sets the specified option for a socket
+ */
+void
+_javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ int optval;
+ jclass cls;
+ jmethodID mid;
+ int address;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option(): no native file descriptor");
+ return;
+ }
+
+ /* We need a class object for all cases below */
+ cls = (*env)->GetObjectClass (env, val);
+ if (cls == NULL)
+ return;
+
+ /* Process the option request */
+ result = TARGET_NATIVE_ERROR;
+ switch (option_id)
+ {
+ /* TCP_NODELAY case. val is a Boolean that tells us what to do */
+ case SOCKOPT_TCP_NODELAY:
+ mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ /* Should be a 0 or a 1 */
+ optval = (*env)->CallBooleanMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_TCP_NODELAY (fd, optval,
+ result);
+ break;
+
+ /* SO_LINGER case. If val is a boolean, then it will always be set
+ to false indicating disable linger, otherwise it will be an
+ integer that contains the linger value */
+ case SOCKOPT_SO_LINGER:
+ mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
+ if (mid)
+ {
+ /* We are disabling linger */
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER (fd, 1, 0,
+ result);
+ }
+ else
+ {
+ /* Clear exception if thrown for failure to do method lookup
+ above */
+ if ((*env)->ExceptionOccurred (env))
+ (*env)->ExceptionClear (env);
+
+ mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ optval = (*env)->CallIntMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER (fd, 0, optval,
+ result);
+ }
+ break;
+
+ /* SO_TIMEOUT case. Val will be an integer with the new value */
+ /* Not writable on Linux */
+ case SOCKOPT_SO_TIMEOUT:
+#ifdef SO_TIMEOUT
+ mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ optval = (*env)->CallIntMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT (fd, optval, result);
+#else
+ result = TARGET_NATIVE_OK;
+#endif
+ break;
+
+ case SOCKOPT_SO_SNDBUF:
+ case SOCKOPT_SO_RCVBUF:
+ mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+
+ optval = (*env)->CallIntMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ if (option_id == SOCKOPT_SO_SNDBUF)
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_SNDBUF (fd, optval,
+ result);
+ else
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_RCDBUF (fd, optval,
+ result);
+ break;
+
+ /* TTL case. Val with be an Integer with the new time to live value */
+ case SOCKOPT_IP_TTL:
+ mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
+ if (!mid)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ optval = (*env)->CallIntMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_TTL (fd, optval, result);
+ break;
+
+ /* Multicast Interface case - val is InetAddress object */
+ case SOCKOPT_IP_MULTICAST_IF:
+ address = _javanet_get_netaddr (env, val);
+
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_MULTICAST_IF (fd, address,
+ result);
+ break;
+
+ case SOCKOPT_SO_REUSEADDR:
+ mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ /* Should be a 0 or a 1 */
+ optval = (*env)->CallBooleanMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_REUSE_ADDRESS (fd, optval,
+ result);
+ break;
+
+ case SOCKOPT_SO_KEEPALIVE:
+ mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ /* Should be a 0 or a 1 */
+ optval = (*env)->CallBooleanMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_KEEP_ALIVE (fd, optval, result);
+ break;
+
+ case SOCKOPT_SO_BINDADDR:
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "This option cannot be set");
+ break;
+
+ default:
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "Unrecognized option");
+ return;
+ }
+
+ /* Check to see if above operations succeeded */
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Retrieves the specified option values for a socket
+ */
+jobject
+_javanet_get_option (JNIEnv * env, jobject this, jint option_id)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ int flag, optval;
+ int address;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "Internal error: _javanet_get_option(): no native file descriptor");
+ return (0);
+ }
+
+ /* Process the option requested */
+ switch (option_id)
+ {
+ /* TCP_NODELAY case. Return a Boolean indicating on or off */
+ case SOCKOPT_TCP_NODELAY:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_TCP_NODELAY (fd, optval,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ if (optval)
+ return (_javanet_create_boolean (env, JNI_TRUE));
+ else
+ return (_javanet_create_boolean (env, JNI_FALSE));
+
+ break;
+
+ /* SO_LINGER case. If disabled, return a Boolean object that represents
+ false, else return an Integer that is the value of SO_LINGER */
+ case SOCKOPT_SO_LINGER:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_LINGER (fd, flag, optval,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ if (optval)
+ return (_javanet_create_integer (env, JNI_TRUE));
+ else
+ return (_javanet_create_boolean (env, JNI_FALSE));
+
+ break;
+
+ /* SO_TIMEOUT case. Return an Integer object with the timeout value */
+ case SOCKOPT_SO_TIMEOUT:
+#ifdef SO_TIMEOUT
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_TIMEOUT (fd, optval, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+ return (_javanet_create_integer (env, optval));
+#else
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "SO_TIMEOUT not supported on this platform");
+ return (0);
+#endif /* not SO_TIMEOUT */
+ break;
+
+ case SOCKOPT_SO_SNDBUF:
+ case SOCKOPT_SO_RCVBUF:
+ if (option_id == SOCKOPT_SO_SNDBUF)
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_SNDBUF (fd, optval,
+ result);
+ else
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_RCDBUF (fd, optval,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ return (_javanet_create_integer (env, optval));
+ break;
+
+ /* The TTL case. Return an Integer with the Time to Live value */
+ case SOCKOPT_IP_TTL:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_TTL (fd, optval, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ return (_javanet_create_integer (env, optval));
+ break;
+
+ /* Multicast interface case */
+ case SOCKOPT_IP_MULTICAST_IF:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_MULTICAST_IF (fd, address,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ return (_javanet_create_inetaddress (env, address));
+ break;
+
+ case SOCKOPT_SO_BINDADDR:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BIND_ADDRESS (fd, address,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ return (_javanet_create_inetaddress (env, address));
+ break;
+
+ case SOCKOPT_SO_REUSEADDR:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_REUSE_ADDRESS (fd, optval,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ if (optval)
+ return (_javanet_create_boolean (env, JNI_TRUE));
+ else
+ return (_javanet_create_boolean (env, JNI_FALSE));
+
+ break;
+
+ case SOCKOPT_SO_KEEPALIVE:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_KEEP_ALIVE (fd, optval, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ if (optval)
+ return (_javanet_create_boolean (env, JNI_TRUE));
+ else
+ return (_javanet_create_boolean (env, JNI_FALSE));
+
+ break;
+
+ default:
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "No such option");
+ return (0);
+ }
+
+ return (0);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+void
+_javanet_shutdownInput (JNIEnv * env, jobject this)
+{
+ int fd;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor. */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "Internal error: _javanet_get_option(): no native file descriptor");
+ return;
+ }
+
+ /* Shutdown input stream of socket. */
+ if (shutdown (fd, SHUT_RD) == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "Can't shutdown input of socket");
+ return;
+ }
+}
+
+void
+_javanet_shutdownOutput (JNIEnv * env, jobject this)
+{
+ int fd;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor. */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "Internal error: _javanet_get_option(): no native file descriptor");
+ return;
+ }
+
+ /* Shutdown output stream of socket. */
+ if (shutdown (fd, SHUT_WR) == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "Can't shutdown output of socket");
+ return;
+ }
+}
+
+/* end of file */
diff --git a/libjava/classpath/native/jni/java-net/javanet.h b/libjava/classpath/native/jni/java-net/javanet.h
new file mode 100644
index 00000000000..7c77ea77f84
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/javanet.h
@@ -0,0 +1,109 @@
+/* javanet.h - Declarations for common functions for the java.net package
+ Copyright (C) 1998, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#ifndef _JAVANET_LOADED
+#define _JAVANET_LOADED
+
+#include <jni.h>
+
+/*************************************************************************/
+
+/*
+ * Defined constants
+ */
+
+/* Exception Classes */
+#define BIND_EXCEPTION "java/net/BindException"
+#define IO_EXCEPTION "java/io/IOException"
+#define SOCKET_EXCEPTION "java/net/SocketException"
+#define UNKNOWN_HOST_EXCEPTION "java/net/UnknownHostException"
+
+/* Socket Option Identifiers - Don't change or binary compatibility with
+ the JDK will be broken! These also need to
+ be kept compatible with java.net.SocketOptions */
+#define SOCKOPT_TCP_NODELAY 1
+#define SOCKOPT_SO_BINDADDR 15
+#define SOCKOPT_SO_LINGER 128
+#define SOCKOPT_SO_TIMEOUT 4102
+#define SOCKOPT_SO_SNDBUF 4097
+#define SOCKOPT_SO_RCVBUF 4098
+#define SOCKOPT_SO_REUSEADDR 4
+#define SOCKOPT_IP_MULTICAST_IF 16
+#define SOCKOPT_SO_KEEPALIVE 8
+
+/* Internal option identifiers. Not needed for JDK compatibility */
+#define SOCKOPT_IP_TTL 7777
+
+/*************************************************************************/
+
+/*
+ * Macros
+ */
+
+/* Simple debug macro */
+#ifdef DEBUG
+#define DBG(x) fprintf(stderr, (x));
+#else
+#define DBG(x)
+#endif
+
+/*************************************************************************/
+
+/*
+ * Function Prototypes
+ */
+
+extern int _javanet_get_int_field(JNIEnv *, jobject, const char *);
+extern int _javanet_get_netaddr(JNIEnv *, jobject);
+extern void _javanet_create(JNIEnv *, jobject, jboolean);
+extern void _javanet_close(JNIEnv *, jobject, int);
+extern void _javanet_connect(JNIEnv *, jobject, jobject, jint);
+extern void _javanet_bind(JNIEnv *, jobject, jobject, jint, int);
+extern void _javanet_listen(JNIEnv *, jobject, jint);
+extern void _javanet_accept(JNIEnv *, jobject, jobject);
+extern int _javanet_recvfrom(JNIEnv *, jobject, jarray, int, int, int *, int *);
+extern void _javanet_sendto(JNIEnv *, jobject, jarray, int, int, int, int);
+extern jobject _javanet_get_option(JNIEnv *, jobject, jint);
+extern void _javanet_set_option(JNIEnv *, jobject, jint, jobject);
+extern void _javanet_shutdownInput (JNIEnv *, jobject);
+extern void _javanet_shutdownOutput (JNIEnv *, jobject);
+
+/*************************************************************************/
+
+#endif /* not _JAVANET_H_LOADED */
+
diff --git a/libjava/classpath/native/jni/java-nio/.cvsignore b/libjava/classpath/native/jni/java-nio/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/java-nio/Makefile.am b/libjava/classpath/native/jni/java-nio/Makefile.am
new file mode 100644
index 00000000000..9785fee6d9b
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/Makefile.am
@@ -0,0 +1,16 @@
+pkglib_LTLIBRARIES = libjavanio.la
+
+libjavanio_la_SOURCES = gnu_java_nio_VMPipe.c \
+ gnu_java_nio_VMSelector.c \
+ gnu_java_nio_channels_FileChannelImpl.c \
+ gnu_java_nio_charset_iconv_IconvDecoder.c \
+ gnu_java_nio_charset_iconv_IconvEncoder.c \
+ java_nio_MappedByteBufferImpl.c \
+ java_nio_VMDirectByteBuffer.c
+
+libjavanio_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo \
+ $(LTLIBICONV)
+
+AM_LDFLAGS = @CLASSPATH_MODULE@
+AM_CPPFLAGS = @CLASSPATH_INCLUDES@
+AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c
new file mode 100644
index 00000000000..369c5a3d650
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMPipe.c
@@ -0,0 +1,56 @@
+/* gnu_java_nio_VMPipe.c - Native methods for PipeImpl class
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <config.h>
+#include <errno.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "gnu_java_nio_VMPipe.h"
+
+#define IO_EXCEPTION "java/io/IOException"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_VMPipe_init (JNIEnv * env,
+ jclass cls __attribute__ ((__unused__)),
+ jobject self __attribute__ ((__unused__)),
+ jobject provider __attribute__ ((__unused__)))
+{
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "gnu.java.nio.VMPipe.init(): not implemented");
+}
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c
new file mode 100644
index 00000000000..f8a40aa7a15
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_VMSelector.c
@@ -0,0 +1,296 @@
+/* gnu_java_nio_VMSelector.c - Native methods for SelectorImpl class
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "config.h"
+
+/* <sys/types.h> needs to be included on OSX before <sys/select.h> */
+#if defined(HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+#include <sys/select.h>
+#include <sys/time.h>
+
+#include <string.h>
+
+#include <errno.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "gnu_java_nio_VMSelector.h"
+
+/* Amount of characters in the error message buffer for strerror_r. */
+#define BUF_SIZE 250
+
+void helper_put_filedescriptors (JNIEnv *, jintArray, fd_set *, int *);
+
+void helper_get_filedescriptors (JNIEnv *, jintArray *, fd_set *);
+
+void helper_reset (JNIEnv *, jintArray *);
+
+int
+helper_select (JNIEnv *, jclass, jmethodID,
+ int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+void
+helper_put_filedescriptors (JNIEnv * env, jintArray fdArray, fd_set * fds,
+ int *max_fd)
+{
+ jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0);
+ int size = (*env)->GetArrayLength (env, fdArray);
+ int index, fd;
+
+ for (index = 0; index < size; index++)
+ {
+ fd = tmpFDArray[index];
+
+ if (fd > 0)
+ {
+ FD_SET (tmpFDArray[index], fds);
+
+ if (tmpFDArray[index] > (*max_fd))
+ (*max_fd) = tmpFDArray[index];
+ }
+ }
+}
+
+void
+helper_get_filedescriptors (JNIEnv * env, jintArray * fdArray, fd_set * fds)
+{
+ jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0);
+ int size = (*env)->GetArrayLength (env, fdArray);
+ int index, fd;
+
+ for (index = 0; index < size; index++)
+ {
+ fd = tmpFDArray[index];
+ if (fd < 0 || !FD_ISSET (fd, fds))
+ tmpFDArray[index] = 0;
+ }
+}
+
+void
+helper_reset (JNIEnv * env, jintArray * fdArray)
+{
+ jint *tmpFDArray = (*env)->GetIntArrayElements (env, fdArray, 0);
+ int size = (*env)->GetArrayLength (env, fdArray);
+ int index;
+
+ for (index = 0; index < size; index++)
+ tmpFDArray[index] = 0;
+}
+
+/* A wrapper for select() which ignores EINTR.
+ * Taken from gclib's posix.cc
+ */
+int
+helper_select (JNIEnv * env, jclass thread_class,
+ jmethodID thread_interrupted, int n, fd_set * readfds,
+ fd_set * writefds, fd_set * exceptfds, struct timeval *timeout)
+{
+#ifdef HAVE_SYS_SELECT_H
+ /* If we have a timeout, compute the absolute ending time. */
+ struct timeval end, delay, after;
+ int r;
+
+ if (timeout)
+ {
+ gettimeofday (&end, NULL);
+
+ end.tv_usec += timeout->tv_usec;
+
+ if (end.tv_usec >= 1000000)
+ {
+ ++end.tv_sec;
+ end.tv_usec -= 1000000;
+ }
+
+ end.tv_sec += timeout->tv_sec;
+ delay = *timeout;
+ }
+ else
+ {
+ /* Placate compiler. */
+ delay.tv_sec = delay.tv_usec = 0;
+ }
+
+ while (1)
+ {
+ r = select (n, readfds, writefds, exceptfds, timeout ? &delay : NULL);
+
+ if (r < 0 && errno != EINTR)
+ return -errno;
+ else if (r >= 0)
+ return r;
+
+ /* Here we know we got EINTR. */
+ if ((*env)->
+ CallStaticBooleanMethod (env, thread_class, thread_interrupted))
+ {
+ return -EINTR;
+ }
+
+ if (timeout)
+ {
+ gettimeofday (&after, NULL);
+
+ /* Now compute new timeout argument. */
+ delay.tv_usec = end.tv_usec - after.tv_usec;
+ delay.tv_sec = end.tv_sec - after.tv_sec;
+
+ if (delay.tv_usec < 0)
+ {
+ --delay.tv_sec;
+ delay.tv_usec += 1000000;
+ }
+
+ if (delay.tv_sec < 0)
+ {
+ /* We assume that the user wants a valid select() call
+ * more than precise timing. So if we get a series of
+ * EINTR we just keep trying with delay 0 until we get a
+ * valid result.
+ */
+ delay.tv_sec = 0;
+ }
+ }
+ }
+#else /* HAVE_SYS_SELECT_H */
+ return 0;
+#endif
+
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_VMSelector_select (JNIEnv * env,
+ jclass obj __attribute__ ((__unused__)),
+ jintArray read,
+ jintArray write,
+ jintArray except, jlong timeout)
+{
+ jint result;
+ jclass thread_class = (*env)->FindClass (env, "java/lang/Thread");
+ jmethodID thread_current_thread =
+ (*env)->GetStaticMethodID (env, thread_class, "currentThread",
+ "()Ljava/lang/Thread;");
+ jmethodID thread_interrupt =
+ (*env)->GetMethodID (env, thread_class, "interrupt", "()V");
+ jmethodID thread_interrupted =
+ (*env)->GetStaticMethodID (env, thread_class, "interrupted", "()Z");
+ jobject current_thread;
+ int max_fd = 0;
+ fd_set read_fds;
+ fd_set write_fds;
+ fd_set except_fds;
+ struct timeval real_time_data;
+ struct timeval *time_data = NULL;
+ char message_buf[BUF_SIZE + 1];
+
+ /* If a legal timeout value isn't given, use NULL.
+ * This means an infinite timeout. The specification
+ * also says that a zero timeout should be treated
+ * as infinite. Otherwise (if the timeout value is legal),
+ * fill our timeval struct and use it for the select.
+ */
+ if (timeout > 0)
+ {
+ real_time_data.tv_sec = timeout / 1000;
+ real_time_data.tv_usec = (timeout % 1000) * 1000;
+ time_data = &real_time_data;
+ }
+
+ /* Reset all fd_set structures */
+ FD_ZERO (&read_fds);
+ FD_ZERO (&write_fds);
+ FD_ZERO (&except_fds);
+
+ /* Fill the fd_set data structures for the _Jv_select() call. */
+ helper_put_filedescriptors (env, read, &read_fds, &max_fd);
+ helper_put_filedescriptors (env, write, &write_fds, &max_fd);
+ helper_put_filedescriptors (env, except, &except_fds, &max_fd);
+
+ /* Actually do the select */
+ result =
+ helper_select (env, thread_class, thread_interrupted, max_fd + 1,
+ &read_fds, &write_fds, &except_fds, time_data);
+
+ if (result == -EINTR)
+ {
+ /* The behavior of JRE 1.4.1 is that no exception is thrown
+ * when the thread is interrupted, but the thread's interrupt
+ * status is set. Clear all of our select sets and return 0,
+ * indicating that nothing was selected.
+ */
+ current_thread =
+ (*env)->CallStaticObjectMethod (env, thread_class,
+ thread_current_thread);
+ (*env)->CallVoidMethod (env, current_thread, thread_interrupt);
+
+ helper_reset (env, read);
+ helper_reset (env, write);
+ helper_reset (env, except);
+
+ return 0;
+ }
+
+ if (result < 0)
+ {
+
+ int errorcode = -result;
+
+ if (strerror_r (errorcode, message_buf, BUF_SIZE))
+ {
+ /* This would mean that message_buf was to small
+ * to hold the error message.
+ */
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "Not enough space in message buffer.");
+ return 0;
+ }
+
+ JCL_ThrowException (env, "java/io/IOException", message_buf);
+ return 0;
+ }
+
+ /* Set the file descriptors according to the values returned from select(). */
+ helper_get_filedescriptors (env, read, &read_fds);
+ helper_get_filedescriptors (env, write, &write_fds);
+ helper_get_filedescriptors (env, except, &except_fds);
+
+ return result;
+}
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c
new file mode 100644
index 00000000000..743e12a8f30
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_channels_FileChannelImpl.c
@@ -0,0 +1,793 @@
+/* gnu_java_nio_channels_FileChannelImpl.c -
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "target_native.h"
+#ifndef WITHOUT_FILESYSTEM
+#include "target_native_file.h"
+#endif
+#include "target_native_math_int.h"
+
+#include "gnu_java_nio_channels_FileChannelImpl.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+/* These values must be kept in sync with FileChannelImpl.java. */
+#define FILECHANNELIMPL_READ 1
+#define FILECHANNELIMPL_WRITE 2
+#define FILECHANNELIMPL_APPEND 4
+
+/* These values must be kept in sync with FileChannelImpl.java. */
+/* #define FILECHANNELIMPL_FILESEEK_SET 0 */
+/* #define FILECHANNELIMPL_FILESEEK_CUR 1 */
+/* #define FILECHANNELIMPL_FILESEEK_END 2 */
+
+#define FILECHANNELIMPL_FILEOPEN_FLAG_READ 1
+#define FILECHANNELIMPL_FILEOPEN_FLAG_WRITE 2
+#define FILECHANNELIMPL_FILEOPEN_FLAG_APPEND 4
+#define FILECHANNELIMPL_FILEOPEN_FLAG_EXCL 8
+#define FILECHANNELIMPL_FILEOPEN_FLAG_SYNC 16
+#define FILECHANNELIMPL_FILEOPEN_FLAG_DSYNC 32
+
+#define IO_EXCEPTION "java/io/IOException"
+
+/* FIXME: This can't be right. Need converter macros. */
+#define CONVERT_JLONG_TO_INT(x) TARGET_NATIVE_MATH_INT_INT64_TO_INT32(x)
+#define CONVERT_INT_TO_JLONG(x) TARGET_NATIVE_MATH_INT_INT32_TO_INT64(x)
+
+/* FIXME: This can't be right. Need converter macros. */
+#define CONVERT_JLONG_TO_OFF_T(x) TARGET_NATIVE_MATH_INT_INT64_TO_INT32(x)
+#define CONVERT_OFF_T_TO_JLONG(x) TARGET_NATIVE_MATH_INT_INT32_TO_INT64(x)
+
+/* FIXME: This can't be right. Need converter macros */
+#define CONVERT_JINT_TO_INT(x) ((int)(x & 0xFFFFFFFF))
+#define CONVERT_INT_TO_JINT(x) ((int)(x & 0xFFFFFFFF))
+
+/* FIXME: This can't be right. Need converter macros. */
+#define CONVERT_SSIZE_T_TO_JINT(x) ((jint)(x & 0xFFFFFFFF))
+#define CONVERT_JINT_TO_SSIZE_T(x) (x)
+
+/* cached fieldID of gnu.java.nio.channels.FileChannelImpl.fd */
+static jfieldID native_fd_fieldID;
+
+static jint
+get_native_fd (JNIEnv * env, jobject obj)
+{
+ return (*env)->GetIntField (env, obj, native_fd_fieldID);
+}
+
+/*
+ * Library initialization routine. Called as part of java.io.FileDescriptor
+ * static initialization.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_init (JNIEnv * env, jclass clazz)
+{
+ jclass clazz_fc;
+ jfieldID field;
+ jmethodID constructor;
+ jobject obj;
+
+ /* Initialize native_fd_fieldID so we only compute it once! */
+ clazz_fc = (*env)->FindClass (env, "gnu/java/nio/channels/FileChannelImpl");
+ if (!clazz_fc)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error");
+ return;
+ }
+
+ field = (*env)->GetFieldID (env, clazz_fc, "fd", "I");
+ if (!field)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error");
+ return;
+ }
+
+ native_fd_fieldID = field;
+
+ constructor = (*env)->GetMethodID (env, clazz, "<init>", "(II)V");
+ if (!constructor)
+ return;
+
+#define INIT_FIELD(FIELDNAME, FDVALUE, MODE) \
+ field = (*env)->GetStaticFieldID (env, clazz, FIELDNAME, \
+ "Lgnu/java/nio/channels/FileChannelImpl;"); \
+ if (! field) \
+ return; \
+ obj = (*env)->NewObject (env, clazz, constructor, FDVALUE, MODE); \
+ if (! obj) \
+ return; \
+ (*env)->SetStaticObjectField (env, clazz, field, obj); \
+ if ((*env)->ExceptionOccurred (env)) \
+ return;
+
+ INIT_FIELD ("in", 0, FILECHANNELIMPL_READ);
+ INIT_FIELD ("out", 1, FILECHANNELIMPL_WRITE);
+ INIT_FIELD ("err", 2, FILECHANNELIMPL_WRITE);
+
+#undef INIT_FIELD
+}
+
+/*
+ * Open the specified file and return a native file descriptor
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_open (JNIEnv * env,
+ jobject obj
+ __attribute__ ((__unused__)),
+ jstring name, jint mode)
+{
+ const char *filename;
+ int flags;
+ int permissions;
+ int native_fd;
+ int result;
+
+ filename = JCL_jstring_to_cstring (env, name);
+ if (filename == NULL)
+ return (-1); /* Exception will already have been thrown */
+
+ /* get file/permission flags for open() */
+ if ((mode & FILECHANNELIMPL_FILEOPEN_FLAG_READ)
+ && (mode & FILECHANNELIMPL_FILEOPEN_FLAG_WRITE))
+ {
+ /* read/write */
+ flags =
+ TARGET_NATIVE_FILE_FILEFLAG_CREATE |
+ TARGET_NATIVE_FILE_FILEFLAG_READWRITE;
+ permissions = TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL;
+ }
+ else if ((mode & FILECHANNELIMPL_FILEOPEN_FLAG_READ))
+ {
+ /* read */
+ flags = TARGET_NATIVE_FILE_FILEFLAG_READ;
+ permissions = TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL;
+ }
+ else
+ {
+ /* write */
+ flags =
+ TARGET_NATIVE_FILE_FILEFLAG_CREATE |
+ TARGET_NATIVE_FILE_FILEFLAG_WRITE;
+ if ((mode & FILECHANNELIMPL_FILEOPEN_FLAG_APPEND))
+ {
+ flags |= TARGET_NATIVE_FILE_FILEFLAG_APPEND;
+ }
+ else
+ {
+ flags |= TARGET_NATIVE_FILE_FILEFLAG_TRUNCATE;
+ }
+ permissions = TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL;
+ }
+
+ if ((mode & FILECHANNELIMPL_FILEOPEN_FLAG_SYNC))
+ {
+ flags |= TARGET_NATIVE_FILE_FILEFLAG_SYNC;
+ }
+
+ if ((mode & FILECHANNELIMPL_FILEOPEN_FLAG_DSYNC))
+ {
+ flags |= TARGET_NATIVE_FILE_FILEFLAG_DSYNC;
+ }
+#ifdef O_BINARY
+ flags |= TARGET_NATIVE_FILE_FILEFLAG_BINARY;
+#endif
+
+ TARGET_NATIVE_FILE_OPEN (filename, native_fd, flags, permissions, result);
+ JCL_free_cstring (env, name, filename);
+
+ if (result != TARGET_NATIVE_OK)
+ {
+ /* We can only throw FileNotFoundException. */
+ JCL_ThrowException (env,
+ "java/io/FileNotFoundException",
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1;
+ }
+
+ return native_fd;
+}
+
+/*
+ * Closes the specified file descriptor and return status code.
+ * Exception on error
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_implCloseChannel (JNIEnv * env,
+ jobject obj)
+{
+ int native_fd;
+ int result;
+
+ native_fd = get_native_fd (env, obj);
+
+ TARGET_NATIVE_FILE_CLOSE (native_fd, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ }
+}
+
+/*
+ * Return number of bytes that can be read from the file w/o blocking.
+ * Exception on error
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_available (JNIEnv * env,
+ jobject obj)
+{
+ int native_fd;
+ jlong bytes_available;
+ int result;
+
+ native_fd = get_native_fd (env, obj);
+
+ TARGET_NATIVE_FILE_AVAILABLE (native_fd, bytes_available, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return 0;
+ }
+
+ /* FIXME NYI ??? why only jint and not jlong? */
+ return TARGET_NATIVE_MATH_INT_INT64_TO_INT32 (bytes_available);
+}
+
+JNIEXPORT jlong JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_size (JNIEnv * env, jobject obj)
+{
+ int native_fd;
+ jlong file_size;
+ int result;
+
+ native_fd = get_native_fd (env, obj);
+
+ TARGET_NATIVE_FILE_SIZE (native_fd, file_size, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1;
+ }
+
+ return file_size;
+}
+
+/*
+ * Return the current position of the file pointer
+ * Exception on error
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_implPosition (JNIEnv * env,
+ jobject obj)
+{
+ int native_fd;
+ jlong current_offset;
+ int result;
+
+ native_fd = get_native_fd (env, obj);
+
+ TARGET_NATIVE_FILE_TELL (native_fd, current_offset, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1;
+ }
+
+ return current_offset;
+}
+
+/*
+ * Wrapper around lseek call. Return new file position
+ * Exception on error
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_seek (JNIEnv * env, jobject obj,
+ jlong offset)
+{
+ int native_fd;
+ jlong new_offset;
+ int result;
+
+ native_fd = get_native_fd (env, obj);
+
+#if 0
+ /* Should there be such an exception? All native layer macros should
+ be accepting 64bit-values if needed. It some target is not able
+ to handle such values it should simply operate with 32bit-values
+ and convert 64bit-values appriopated. In this case I assume
+ problems should not occurre: if some specific target is not able
+ to handle 64bit-values the system is limited to 32bit at all, thus
+ the application can not do a seek() or something else beyond the
+ 32bit limit. It this true?
+ */
+
+ /* FIXME: What do we do if offset > the max value of off_t on this 32bit
+ * system? How do we detect that and what do we do? */
+ if (CONVERT_OFF_T_TO_JLONG (native_offset) != offset)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Cannot represent position correctly on this system");
+ }
+#endif /* 0 */
+
+ result = TARGET_NATIVE_ERROR;
+ new_offset = TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1;
+ TARGET_NATIVE_FILE_SEEK_BEGIN (native_fd, offset, new_offset, result);
+
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ }
+}
+
+/*
+ * Set the length of the file
+ * Exception on error
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_implTruncate (JNIEnv * env,
+ jobject obj,
+ jlong len)
+{
+ int native_fd;
+ jlong file_size;
+ int bytes_written;
+ jlong save_offset, new_offset;
+ char data;
+ int result;
+
+ native_fd = get_native_fd (env, obj);
+
+#if 0
+ /* Should there be such an exception? All native layer macros should
+ be accepting 64bit-values if needed. It some target is not able
+ to handle such values it should simply operate with 32bit-values
+ and convert 64bit-values appriopated. In this case I assume
+ problems should not occurre: if some specific target is not able
+ to handle 64bit-values the system is limited to 32bit at all, thus
+ the application can not do a seek() or something else beyond the
+ 32bit limit. It this true?
+ */
+
+ /* FIXME: What do we do if len > the max value of off_t on this 32bit
+ * system? How do we detect that and what do we do? */
+ if (CONVERT_OFF_T_TO_JLONG (native_len) != len)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Cannot represent position correctly on this system");
+ return;
+ }
+#endif /* 0 */
+
+ /* get file size */
+ TARGET_NATIVE_FILE_SIZE (native_fd, file_size, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ /* Save off current position */
+ TARGET_NATIVE_FILE_TELL (native_fd, save_offset, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ if (TARGET_NATIVE_MATH_INT_INT64_LT (file_size, len))
+ {
+ /* File is too short -- seek to one byte short of where we want,
+ * then write a byte */
+
+ /* move to position n-1 */
+ TARGET_NATIVE_FILE_SEEK_BEGIN (native_fd,
+ TARGET_NATIVE_MATH_INT_INT64_SUB (len,
+ 1),
+ new_offset, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ /* write a byte
+ Note: This will fail if we somehow get here in read only mode
+ * That shouldn't happen */
+ data = '\0';
+ TARGET_NATIVE_FILE_WRITE (native_fd, &data, 1, bytes_written, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ /* Reposition file pointer to where we started if not beyond new len. */
+ if (TARGET_NATIVE_MATH_INT_INT64_LT (save_offset, len))
+ {
+ TARGET_NATIVE_FILE_SEEK_BEGIN (native_fd, save_offset,
+ new_offset, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ }
+ }
+ else if (TARGET_NATIVE_MATH_INT_INT64_GT (file_size, len))
+ {
+ /* File is too long - use ftruncate if available */
+#ifdef HAVE_FTRUNCATE
+ TARGET_NATIVE_FILE_TRUNCATE (native_fd, len, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+#else /* HAVE_FTRUNCATE */
+ /* FIXME: Probably operation isn't supported, but this exception
+ * is too harsh as it will probably crash the program without need
+ JCL_ThrowException(env, "java/lang/UnsupportedOperationException",
+ "not implemented - can't shorten files on this platform");
+ */
+ JCL_ThrowException (env, IO_EXCEPTION, "Unable to shorten file length");
+#endif /* HAVE_FTRUNCATE */
+
+ /* Reposition file pointer when it now is beyond the end of file. */
+ if (TARGET_NATIVE_MATH_INT_INT64_GT (save_offset, len))
+ {
+ TARGET_NATIVE_FILE_SEEK_BEGIN (native_fd, len, new_offset, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ }
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_mapImpl (JNIEnv * env,
+ jobject obj
+ __attribute__ ((__unused__)), jchar mode __attribute__ ((__unused__)), jlong position __attribute__ ((__unused__)), jint size __attribute__ ((__unused__)))
+{
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "java.nio.FileChannelImpl.nio_mmap_file(): not implemented");
+ return 0;
+}
+
+/*
+ * Read a single byte from the file descriptor
+ * Return byte read or -1 on eof, exception on error
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_read__ (JNIEnv * env, jobject obj)
+{
+ int native_fd;
+ char data;
+ ssize_t bytes_read;
+ int result;
+
+ native_fd = get_native_fd (env, obj);
+
+ bytes_read = 0;
+ do
+ {
+ TARGET_NATIVE_FILE_READ (native_fd, &data, 1, bytes_read, result);
+ if ((result == TARGET_NATIVE_OK) && (bytes_read == 0))
+ {
+ return (-1);
+ }
+ if ((result != TARGET_NATIVE_OK)
+ && (TARGET_NATIVE_LAST_ERROR () !=
+ TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (-1);
+ }
+ }
+ while (result != TARGET_NATIVE_OK);
+
+ return ((jint) (data & 0xFF));
+}
+
+/*
+ * Reads to a byte buffer from the specified file descriptor
+ * Return number of bytes read or -1 on eof, exception on error
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_read___3BII (JNIEnv * env,
+ jobject obj,
+ jbyteArray buffer,
+ jint offset,
+ jint length)
+{
+ int native_fd;
+ jbyte *bufptr;
+ ssize_t bytes_read;
+ ssize_t n;
+ int result;
+
+ native_fd = get_native_fd (env, obj);
+
+ /* Must return 0 if an attempt is made to read 0 bytes. */
+ if (length == 0)
+ return 0;
+
+ if (offset < 0)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "negative offset");
+ return -1;
+ }
+
+ bufptr = (*env)->GetByteArrayElements (env, buffer, 0);
+ if (!bufptr)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Unexpected JNI error");
+ return (-1);
+ }
+
+ if (length + offset > (*env)->GetArrayLength (env, buffer))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "length + offset > buffer.length");
+ return -1;
+ }
+
+ bytes_read = 0;
+ do
+ {
+ TARGET_NATIVE_FILE_READ (native_fd, (bufptr + offset + bytes_read),
+ (length - bytes_read), n, result);
+ if ((result == TARGET_NATIVE_OK) && (n == 0))
+ {
+ (*env)->ReleaseByteArrayElements (env, buffer, bufptr, 0);
+ if (bytes_read == 0)
+ return -1; /* Signal end of file to Java */
+ else
+ return CONVERT_SSIZE_T_TO_JINT (bytes_read);
+ }
+ if ((result != TARGET_NATIVE_OK)
+ && (TARGET_NATIVE_LAST_ERROR () !=
+ TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ (*env)->ReleaseByteArrayElements (env, buffer, bufptr, 0);
+ return -1;
+ }
+ if (result == TARGET_NATIVE_OK)
+ bytes_read += n;
+ }
+ while (bytes_read < 1);
+
+ (*env)->ReleaseByteArrayElements (env, buffer, bufptr, 0);
+ return CONVERT_SSIZE_T_TO_JINT (bytes_read);
+}
+
+/*
+ * Writes a single byte to the specified file descriptor
+ * Return status code, exception on error
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_write__I (JNIEnv * env,
+ jobject obj, jint b)
+{
+ int native_fd;
+ char native_data;
+ ssize_t bytes_written;
+ int result;
+
+ native_fd = get_native_fd (env, obj);
+ native_data = (char) (CONVERT_JINT_TO_INT (b) & 0xFF);
+
+ do
+ {
+ TARGET_NATIVE_FILE_WRITE (native_fd, &native_data, 1, bytes_written,
+ result);
+ if ((result != TARGET_NATIVE_OK)
+ && (TARGET_NATIVE_LAST_ERROR () !=
+ TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ }
+ while (result != TARGET_NATIVE_OK);
+}
+
+/*
+ * Copies all parts of a file to disk.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_force (JNIEnv * env,
+ jobject obj)
+{
+ int native_fd;
+ int result;
+ native_fd = get_native_fd (env, obj);
+ TARGET_NATIVE_FILE_FSYNC (native_fd, result);
+ if (result != TARGET_NATIVE_OK)
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+}
+
+/*
+ * Writes a byte buffer to the specified file descriptor
+ * Return status code, exception on error
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_write___3BII (JNIEnv * env,
+ jobject obj,
+ jbyteArray buffer,
+ jint offset,
+ jint length)
+{
+ int native_fd;
+ jbyte *bufptr;
+ ssize_t bytes_written;
+ ssize_t n;
+ int result;
+
+ native_fd = get_native_fd (env, obj);
+
+ /* Just return if an attempt is made to write 0 bytes. */
+ if (length == 0)
+ return;
+
+ bufptr = (*env)->GetByteArrayElements (env, buffer, 0);
+ if (!bufptr)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Unexpected JNI error");
+ return;
+ }
+
+ bytes_written = 0;
+ while (bytes_written < CONVERT_JINT_TO_SSIZE_T (length))
+ {
+ TARGET_NATIVE_FILE_WRITE (native_fd, (bufptr + offset + bytes_written),
+ (length - bytes_written), n, result);
+ if ((result != TARGET_NATIVE_OK)
+ && (TARGET_NATIVE_LAST_ERROR () !=
+ TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ (*env)->ReleaseByteArrayElements (env, buffer, bufptr, 0);
+ return;
+ }
+ if (result == TARGET_NATIVE_OK)
+ bytes_written += n;
+ }
+
+ (*env)->ReleaseByteArrayElements (env, buffer, bufptr, 0);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_lock (JNIEnv *env, jobject obj,
+ jlong position, jlong size,
+ jboolean shared, jboolean wait)
+{
+#ifdef HAVE_FCNTL
+ int fd = get_native_fd (env, obj);
+ int cmd = wait ? F_SETLKW : F_SETLK;
+ struct flock flock;
+ int ret;
+
+ flock.l_type = shared ? F_RDLCK : F_WRLCK;
+ flock.l_whence = SEEK_SET;
+ flock.l_start = (off_t) position;
+ flock.l_len = (off_t) size;
+
+ ret = fcntl (fd, cmd, &flock);
+ if (ret)
+ {
+ /* Linux man pages for fcntl state that errno might be either
+ EACCES or EAGAIN if we try F_SETLK, and another process has
+ an overlapping lock. */
+ if (errno != EACCES && errno != EAGAIN)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+#else
+ (void) obj;
+ (void) position;
+ (void) size;
+ (void) shared;
+ (void) wait;
+ JCL_ThrowException (env, "java/lang/UnsupportedOperationException",
+ "file locks not implemented on this platform");
+ return JNI_FALSE;
+#endif /* HAVE_FCNTL */
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_channels_FileChannelImpl_unlock (JNIEnv *env,
+ jobject obj,
+ jlong position,
+ jlong length)
+{
+#ifdef HAVE_FCNTL
+ int fd = get_native_fd (env, obj);
+ struct flock flock;
+ int ret;
+
+ flock.l_type = F_UNLCK;
+ flock.l_whence = SEEK_SET;
+ flock.l_start = (off_t) position;
+ flock.l_len = (off_t) length;
+
+ ret = fcntl (fd, F_SETLK, &flock);
+ if (ret)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+ }
+#else
+ (void) obj;
+ (void) position;
+ (void) length;
+ JCL_ThrowException (env, "java/lang/UnsupportedOperationException",
+ "file locks not implemented on this platform");
+#endif /* HAVE_FCNTL */
+}
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c
new file mode 100644
index 00000000000..8c3f83accff
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvDecoder.c
@@ -0,0 +1,219 @@
+/* gnu_java_nio_charset_iconv_IconvDecoder.c --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <config.h>
+#include <jcl.h>
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+
+#if defined(HAVE_ICONV)
+#include <iconv.h>
+#endif
+
+#include "gnu_java_nio_charset_iconv_IconvDecoder.h"
+
+static void createRawData (JNIEnv * env, jobject obj, void *ptr);
+static void *getData (JNIEnv * env, jobject obj);
+
+static jfieldID infid = NULL;
+static jfieldID outfid = NULL;
+
+/* Union used for type punning. */
+union char_union
+{
+ jbyte **jb;
+ jchar **jc;
+ char **c;
+};
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_charset_iconv_IconvDecoder_openIconv (JNIEnv * env,
+ jobject obj,
+ jstring jname)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object;
+ jclass cls;
+
+ const char *name = JCL_jstring_to_cstring (env, jname);
+ if (name == NULL)
+ return;
+
+ /* Cache fieldIDs for use in decode function. */
+ if (infid == NULL || outfid == NULL)
+ {
+ cls = (*env)->GetObjectClass (env, obj);
+ infid = (*env)->GetFieldID (env, cls, "inremaining", "I");
+ assert (infid != 0);
+ outfid = (*env)->GetFieldID (env, cls, "outremaining", "I");
+ assert (outfid != 0);
+ }
+
+ /* to java from "name", native java format depends on endianness */
+#ifdef WORDS_BIGENDIAN
+ iconv_object = iconv_open ("UTF-16BE", name);
+#else
+ iconv_object = iconv_open ("UTF-16LE", name);
+#endif
+
+ JCL_free_cstring (env, jname, name);
+ if ((long) iconv_object == -1L)
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Charset not available");
+ return;
+ }
+ createRawData (env, obj, (void *) iconv_object);
+#else
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "iconv not available");
+#endif
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_charset_iconv_IconvDecoder_decode (JNIEnv * env,
+ jobject obj,
+ jbyteArray inArr,
+ jcharArray outArr,
+ jint posIn, jint remIn,
+ jint posOut, jint remOut)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object = getData (env, obj);
+ size_t retval;
+ union char_union in, out;
+ jbyte *input, *inputcopy;
+ jchar *output, *outputcopy;
+ size_t lenIn = (size_t) remIn;
+ size_t lenOut = (size_t) remOut * 2;
+
+ inputcopy = input = (*env)->GetByteArrayElements (env, inArr, 0);
+ outputcopy = output = (*env)->GetCharArrayElements (env, outArr, 0);
+
+ input += posIn;
+ output += posOut;
+
+ in.jb = &input;
+ out.jc = &output;
+ retval = iconv (iconv_object, (ICONV_CONST char **) in.c, &lenIn,
+ out.c, &lenOut);
+
+ /* XXX: Do we need to relase the input array? It's not modified. */
+ (*env)->ReleaseByteArrayElements (env, inArr, inputcopy, 0);
+ (*env)->ReleaseCharArrayElements (env, outArr, outputcopy, 0);
+
+ if (retval == (size_t) (-1))
+ {
+ if (errno == EILSEQ || errno == EINVAL)
+ retval = 1;
+ else
+ retval = 0;
+ }
+ else
+ retval = 0;
+
+ (*env)->SetIntField (env, obj, infid, (jint) lenIn);
+ (*env)->SetIntField (env, obj, outfid, (jint) (lenOut >> 1));
+
+ return (jint) retval;
+#else
+ return -1;
+#endif
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_charset_iconv_IconvDecoder_closeIconv (JNIEnv * env,
+ jobject obj)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object;
+ iconv_object = getData (env, obj);
+ iconv_close (iconv_object);
+#endif
+}
+
+
+static void
+createRawData (JNIEnv * env, jobject obj, void *ptr)
+{
+ jclass cls;
+ jmethodID method;
+ jobject data;
+ jfieldID data_fid;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/RawData;");
+ assert (data_fid != 0);
+
+#ifdef POINTERS_ARE_64BIT
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(J)V");
+ data = (*env)->NewObject (env, cls, method, (jlong) ptr);
+#else
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
+ data = (*env)->NewObject (env, cls, method, (jint) ptr);
+#endif
+
+ (*env)->SetObjectField (env, obj, data_fid, data);
+}
+
+static void *
+getData (JNIEnv * env, jobject obj)
+{
+ jclass cls;
+ jfieldID field;
+ jfieldID data_fid;
+ jobject data;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/RawData;");
+ assert (data_fid != 0);
+ data = (*env)->GetObjectField (env, obj, data_fid);
+
+#if SIZEOF_VOID_P == 8
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ field = (*env)->GetFieldID (env, cls, "data", "J");
+ return (void *) (*env)->GetLongField (env, data, field);
+#else
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ field = (*env)->GetFieldID (env, cls, "data", "I");
+ return (void *) (*env)->GetIntField (env, data, field);
+#endif
+}
diff --git a/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c
new file mode 100644
index 00000000000..cd5d48656f7
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/gnu_java_nio_charset_iconv_IconvEncoder.c
@@ -0,0 +1,219 @@
+/* gnu_java_nio_charset_iconv_IconvEncoder.c --
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <config.h>
+#include <jcl.h>
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+
+#if defined(HAVE_ICONV)
+#include <iconv.h>
+#endif
+
+#include "gnu_java_nio_charset_iconv_IconvEncoder.h"
+
+static void createRawData (JNIEnv * env, jobject obj, void *ptr);
+static void *getData (JNIEnv * env, jobject obj);
+
+static jfieldID infid = NULL;
+static jfieldID outfid = NULL;
+
+/* Union used for type punning. */
+union char_union
+{
+ jbyte **jb;
+ jchar **jc;
+ char **c;
+};
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_charset_iconv_IconvEncoder_openIconv (JNIEnv * env,
+ jobject obj,
+ jstring jname)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object;
+ jclass cls;
+
+ const char *name = JCL_jstring_to_cstring (env, jname);
+ if (name == NULL)
+ return;
+
+ /* Cache fieldIDs for use in encode function. */
+ if (infid == NULL || outfid == NULL)
+ {
+ cls = (*env)->GetObjectClass (env, obj);
+ infid = (*env)->GetFieldID (env, cls, "inremaining", "I");
+ assert (infid != 0);
+ outfid = (*env)->GetFieldID (env, cls, "outremaining", "I");
+ assert (outfid != 0);
+ }
+
+ /* to "name" from java, native java format depends on endianness */
+#ifdef WORDS_BIGENDIAN
+ iconv_object = iconv_open (name, "UTF-16BE");
+#else
+ iconv_object = iconv_open (name, "UTF-16LE");
+#endif
+
+ JCL_free_cstring (env, jname, name);
+ if ((long) iconv_object == -1L)
+ {
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "Charset not available");
+ return;
+ }
+ createRawData (env, obj, (void *) iconv_object);
+#else
+ JCL_ThrowException (env, "java/lang/IllegalArgumentException",
+ "iconv not available");
+#endif
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_nio_charset_iconv_IconvEncoder_encode (JNIEnv * env,
+ jobject obj,
+ jcharArray inArr,
+ jbyteArray outArr,
+ jint posIn, jint remIn,
+ jint posOut, jint remOut)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object = getData (env, obj);
+ size_t retval;
+ union char_union in, out;
+ jchar *input, *inputcopy;
+ jbyte *output, *outputcopy;
+ size_t lenIn = (size_t) remIn * 2;
+ size_t lenOut = (size_t) remOut;
+
+ inputcopy = input = (*env)->GetCharArrayElements (env, inArr, 0);
+ outputcopy = output = (*env)->GetByteArrayElements (env, outArr, 0);
+
+ input += posIn;
+ output += posOut;
+
+ in.jc = &input;
+ out.jb = &output;
+ retval = iconv (iconv_object, (ICONV_CONST char **) in.c, &lenIn,
+ out.c, &lenOut);
+
+ /* XXX: Do we need to relase the input array? It's not modified. */
+ (*env)->ReleaseCharArrayElements (env, inArr, inputcopy, 0);
+ (*env)->ReleaseByteArrayElements (env, outArr, outputcopy, 0);
+
+ if (retval == (size_t) (-1))
+ {
+ if (errno == EILSEQ || errno == EINVAL)
+ retval = 1;
+ else
+ retval = 0;
+ }
+ else
+ retval = 0;
+
+ (*env)->SetIntField (env, obj, infid, (jint) (lenIn >> 1));
+ (*env)->SetIntField (env, obj, outfid, (jint) lenOut);
+
+ return (jint) retval;
+#else
+ return -1;
+#endif
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_nio_charset_iconv_IconvEncoder_closeIconv (JNIEnv * env,
+ jobject obj)
+{
+#if defined(HAVE_ICONV)
+ iconv_t iconv_object;
+ iconv_object = getData (env, obj);
+ iconv_close (iconv_object);
+#endif
+}
+
+
+static void
+createRawData (JNIEnv * env, jobject obj, void *ptr)
+{
+ jclass cls;
+ jmethodID method;
+ jobject data;
+ jfieldID data_fid;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/RawData;");
+ assert (data_fid != 0);
+
+#ifdef POINTERS_ARE_64BIT
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(J)V");
+ data = (*env)->NewObject (env, cls, method, (jlong) ptr);
+#else
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
+ data = (*env)->NewObject (env, cls, method, (jint) ptr);
+#endif
+
+ (*env)->SetObjectField (env, obj, data_fid, data);
+}
+
+static void *
+getData (JNIEnv * env, jobject obj)
+{
+ jclass cls;
+ jfieldID field;
+ jfieldID data_fid;
+ jobject data;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ data_fid = (*env)->GetFieldID (env, cls, "data", "Lgnu/classpath/RawData;");
+ assert (data_fid != 0);
+ data = (*env)->GetObjectField (env, obj, data_fid);
+
+#if SIZEOF_VOID_P == 8
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ field = (*env)->GetFieldID (env, cls, "data", "J");
+ return (void *) (*env)->GetLongField (env, data, field);
+#else
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ field = (*env)->GetFieldID (env, cls, "data", "I");
+ return (void *) (*env)->GetIntField (env, data, field);
+#endif
+}
diff --git a/libjava/classpath/native/jni/java-nio/java_nio.c b/libjava/classpath/native/jni/java-nio/java_nio.c
new file mode 100644
index 00000000000..a25f38a6d2a
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/java_nio.c
@@ -0,0 +1,328 @@
+/* java_nio.c - Native methods for gnu.java.nio.FileChannelImpl class
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "target_native.h"
+#ifndef WITHOUT_NETWORK
+#include "target_native_network.h"
+#endif /* WITHOUT_NETWORK */
+
+#include "java_nio_channels_FileChannelImpl.h"
+
+#include "javaio.h"
+
+#define NIO_DEBUG(X) /* no debug */
+//#define NIO_DEBUG(X) X
+
+/***************************************
+ *
+ * File Channel implementation
+ *
+ *************/
+
+
+static char *
+compare (int i, int lim, char *buffer)
+{
+ sprintf (buffer, "(%d >= %d)", i, lim);
+ return buffer;
+}
+
+static inline int
+convert_Int (int X)
+{
+ unsigned char *a = (unsigned char *) &X;
+ int res =
+ (((int) a[0]) << 24) +
+ (((int) a[1]) << 16) + (((int) a[2]) << 8) + (((int) a[3]) << 0);
+ return res;
+}
+
+static inline jlong
+convert_Long (jlong X)
+{
+ unsigned char *a = (unsigned char *) &X;
+ int res1 =
+ (((int) a[0]) << 24) +
+ (((int) a[1]) << 16) + (((int) a[2]) << 8) + (((int) a[3]) << 0);
+ int res2;
+ a += 4;
+ res2 =
+ (((int) a[0]) << 24) +
+ (((int) a[1]) << 16) + (((int) a[2]) << 8) + (((int) a[3]) << 0);
+ return ((jlong) res1) | ((jlong) res2) << 32LL;
+}
+
+static inline short
+convert_Short (short X)
+{
+ unsigned char *a = (unsigned char *) &X;
+ int res = (((int) a[2]) << 8) + (((int) a[3]) << 0);
+ return res;
+}
+static inline short
+convert_Char (short X)
+{
+ unsigned char *a = (unsigned char *) &X;
+ int res = (((int) a[2]) << 8) + (((int) a[3]) << 0);
+ return res;
+}
+
+static inline unsigned char
+convert_Byte (unsigned char X)
+{
+ return X;
+}
+
+static inline float
+convert_Float (float X)
+{
+ return X;
+}
+
+static inline double
+convert_Double (double X)
+{
+ return X;
+}
+
+
+// Note: do to many get()'s on a buffer and you should throw a BufferUnderflowException
+// Alas, I only found this out during testing....
+
+#define READ_WRITE_MMAPED_FILE(TYPE,ELT) \
+ \
+ELT Java_gnu_java_nio_MappedByteFileBuffer_nio_1read_1 ## TYPE ## _1file_1channel(JNIEnv *env, \
+ jclass c, jobject b, \
+ int index, int limit, jlong jaddress) \
+{ \
+ char *address = *(void **) &jaddress; char buffer[128]; \
+ if (index >= limit) JCL_ThrowException(env, "java/nio/BufferUnderflowException", compare(index,limit, buffer)); \
+ NIO_DEBUG( fprintf(stderr, "READ:index = %d [0]=%c [1]=%c\n", index, address[0],address[1]); ) \
+ address += index; \
+ return convert_ ## TYPE (*(ELT *) address); \
+} \
+ \
+void Java_gnu_java_nio_MappedByteFileBuffer_nio_1write_1 ## TYPE ## _1file_1channel(JNIEnv *env, \
+ jclass c, jobject b, \
+ int index, int limit, ELT value, jlong jaddress) \
+{ \
+ \
+ char *address = *(void **) &jaddress; char buffer[128]; \
+ if (index >= limit) JCL_ThrowException(env, "java/nio/BufferUnderflowException", compare(index,limit, buffer)); \
+NIO_DEBUG( fprintf(stderr, "WRITE:index = %d [0]=%c [1]=%c\n", index, address[0],address[1]); ) \
+ address += index; \
+ *(ELT *) address = value; \
+} \
+ \
+ELT Java_gnu_java_nio_MappedByteFileBuffer_nio_1get_1 ## TYPE(JNIEnv *env, jclass c, jobject b, \
+ int index, int limit, jlong jaddress) \
+{ \
+ fprintf(stderr, "unimplemented\n"); return 0; \
+} \
+ \
+void Java_gnu_java_nio_MappedByteFileBuffer_nio_1put_1 ## TYPE(JNIEnv *env, jclass c, jobject b, \
+ int index, int limit, \
+ ELT value, jlong jaddress) \
+{ \
+ fprintf(stderr, "unimplemented\n"); \
+}
+
+READ_WRITE_MMAPED_FILE (Byte, u_int8_t);
+READ_WRITE_MMAPED_FILE (Char, u_int16_t);
+READ_WRITE_MMAPED_FILE (Short, u_int16_t);
+READ_WRITE_MMAPED_FILE (Int, u_int32_t);
+READ_WRITE_MMAPED_FILE (Long, u_int64_t);
+READ_WRITE_MMAPED_FILE (Float, float);
+READ_WRITE_MMAPED_FILE (Double, double);
+
+u_int64_t
+nio_mmap_file (jint fd, jlong pos, jint size, jint jflags)
+{
+#ifdef HAVE_MMAP
+ u_int64_t ret = 0;
+ void *address;
+
+ int flags = (jflags != 2) ? MAP_SHARED : MAP_PRIVATE;
+ int prot = PROT_READ;
+
+ if (jflags == 1)
+ prot |= PROT_WRITE;
+
+ // fprintf(stderr, "mapping file: %d\n", fd);
+
+ address = mmap (0, size, prot, flags, fd, pos);
+
+ if (address == (void *) -1)
+ {
+ perror ("mapping file failed");
+ return 0;
+ }
+
+ // fprintf(stderr, "address = %p, fd = %d, pos=%lld, size=%d\n", address, fd, pos, size);
+
+ *(void **) &ret = address;
+
+ return ret;
+#else /* not HAVE_MMAP */
+ return (TARGET_NATIVE_MATH_INT_INT64_CONST_0);
+#endif /* not HAVE_MMAP */
+}
+
+
+void
+nio_msync (int fd, jlong jaddress, int size)
+{
+#ifdef HAVE_MMAP
+ int res;
+ char *address = *(void **) &jaddress;
+
+ // fprintf(stderr, "synchronizing with file (%p -> %d bytes (%s))\n", address, size, address);
+
+ res = msync (address, size, MS_SYNC | MS_INVALIDATE);
+
+ if (res == -1)
+ {
+ perror ("synchronize with file failed");
+ }
+#else /* not HAVE_MMAP */
+#endif /* not HAVE_MMAP */
+}
+
+void
+nio_unmmap_file (int fd, jlong jaddress, int size)
+{
+#ifdef HAVE_MMAP
+ int res = 0;
+ char *address = *(void **) &jaddress;
+
+ // nio_msync(fd, jaddress, size);
+
+ // fprintf(stderr, "unmapping (%p -> %d bytes)\n", address, size);
+
+ res = munmap (address, size);
+ if (res == -1)
+ {
+ perror ("un-mapping file failed");
+ }
+#else /* not HAVE_MMAP */
+#endif /* not HAVE_MMAP */
+}
+
+
+/***************************************
+ *
+ * Socket Channel implementation
+ *
+ *************/
+
+/*************************************************************************/
+
+/*
+ * Returns a 32 bit Internet address for the passed in InetAddress object
+ * Ronald: This is a verbatim copy from javanet.c.
+ * It's a copy to avoid a link error in orp.
+ */
+
+static int
+socket_channel_get_net_addr (JNIEnv * env, jobject addr)
+{
+#ifndef WITHOUT_NETWORK
+ jclass cls = 0;
+ jmethodID mid;
+ jarray arr = 0;
+ jbyte *octets;
+ int netaddr, len;
+
+ DBG
+ ("socket_channel_get_net_addr(): Entered socket_channel_get_net_addr\n");
+
+ /* Call the getAddress method on the object to retrieve the IP address */
+ cls = (*env)->GetObjectClass (env, addr);
+ if (cls == NULL)
+ return (0);
+
+ mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B");
+ if (mid == NULL)
+ return (0);
+
+ DBG ("socket_channel_get_net_addr(): Got getAddress method\n");
+
+ arr = (*env)->CallObjectMethod (env, addr, mid);
+ if (arr == NULL)
+ return (0);
+
+ DBG ("socket_channel_get_net_addr(): Got the address\n");
+
+ /* Turn the IP address into a 32 bit Internet address in network byte order */
+ len = (*env)->GetArrayLength (env, arr);
+ if (len != 4)
+ {
+ JCL_ThrowException (env, "java/io/IOException",
+ "Internal Error: invalid byte array length");
+ return (0);
+ }
+ DBG ("socket_channel_get_net_addr(): Length ok\n");
+
+ octets = (*env)->GetByteArrayElements (env, arr, 0);
+ if (octets == NULL)
+ return (0);
+
+ DBG ("socket_channel_get_net_addr(): Grabbed bytes\n");
+
+ TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0],
+ octets[1],
+ octets[2],
+ octets[3], netaddr);
+
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+ DBG ("socket_channel_get_net_addr(): Done getting addr\n");
+
+ return netaddr;
+#else /* not WITHOUT_NETWORK */
+ return (0);
+#endif /* not WITHOUT_NETWORK */
+}
diff --git a/libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c b/libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c
new file mode 100644
index 00000000000..e1ba1e454f0
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/java_nio_MappedByteBufferImpl.c
@@ -0,0 +1,83 @@
+/* java_nio_MappedByteBufferImpl.c - Native methods for MappedByteBufferImpl
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <config.h>
+#include <errno.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "java_nio_MappedByteBufferImpl.h"
+
+#define IO_EXCEPTION "java/io/IOException"
+
+JNIEXPORT void JNICALL
+Java_java_nio_MappedByteBufferImpl_unmapImpl (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)))
+{
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "java.nio.MappedByteBufferImpl.unmapImpl(): not implemented");
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_nio_MappedByteBufferImpl_isLoadedImpl (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)))
+{
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "java.nio.MappedByteBufferImpl.isLoadedImpl(): not implemented");
+ return 0;
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_MappedByteBufferImpl_loadImpl (JNIEnv * env,
+ jclass clazz
+ __attribute__ ((__unused__)))
+{
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "java.nio.MappedByteBufferImpl.loadImpl(): not implemented");
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_MappedByteBufferImpl_forceImpl (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)))
+{
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "java.nio.MappedByteBufferImpl.forceImpl(): not implemented");
+}
diff --git a/libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c b/libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c
new file mode 100644
index 00000000000..3eb5677e646
--- /dev/null
+++ b/libjava/classpath/native/jni/java-nio/java_nio_VMDirectByteBuffer.c
@@ -0,0 +1,216 @@
+/* java_nio_VMDirectByteBuffer.c - Native methods for VMDirectByteBuffer
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <config.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "java_nio_VMDirectByteBuffer.h"
+
+static jclass classRawData;
+static jmethodID methodRawDataInit;
+static jfieldID fieldNativePointer;
+
+static void *NIOGetPointer (JNIEnv *, jobject);
+static jobject NIOGetRawData (JNIEnv *, void *pointer);
+
+static void *
+NIOGetPointer (JNIEnv * env, jobject rawdata)
+{
+#if SIZEOF_VOID_P == 4
+ return (void *) (*env)->GetIntField (env, rawdata, fieldNativePointer);
+#elif SIZEOF_VOID_P == 8
+ return (void *) (*env)->GetLongField (env, rawdata, fieldNativePointer);
+#else
+#error unsupported pointer size
+#endif
+}
+
+static jobject
+NIOGetRawData (JNIEnv * env, void *pointer)
+{
+#if SIZEOF_VOID_P == 4
+ return (*env)->NewObject (env, classRawData, methodRawDataInit,
+ (jint) pointer);
+#elif SIZEOF_VOID_P == 8
+ return (*env)->NewObject (env, classRawData, methodRawDataInit,
+ (jlong) pointer);
+#else
+#error unsupported pointer size
+#endif
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_init
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)))
+{
+#if SIZEOF_VOID_P == 4
+ classRawData = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ if (classRawData == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "unable to find internal class");
+ return;
+ }
+
+ methodRawDataInit = (*env)->GetMethodID (env, classRawData,
+ "<init>", "(I)V");
+ if (methodRawDataInit == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "unable to find internal constructor");
+ return;
+ }
+
+ fieldNativePointer = (*env)->GetFieldID (env, classRawData, "data", "I");
+ if (fieldNativePointer == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "unable to find internal field");
+ return;
+ }
+#elif SIZEOF_VOID_P == 8
+ classRawData = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ if (classRawData == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "unable to find internal class");
+ return;
+ }
+
+ methodRawDataInit = (*env)->GetMethodID (env, classRawData,
+ "<init>", "(J)V");
+ if (methodRawDataInit == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "unable to find internal constructor");
+ return;
+ }
+
+ fieldNativePointer = (*env)->GetFieldID (env, classRawData, "data", "J");
+ if (fieldNativePointer == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "unable to find internal field");
+ return;
+ }
+#else
+#error unsupported pointer size
+#endif
+
+ /* We need to wrap the jclass in global reference to make it persistent */
+ if ((classRawData = (*env)->NewGlobalRef (env, classRawData)) == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "failed to create global reference");
+ return;
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_java_nio_VMDirectByteBuffer_allocate
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), jint capacity)
+{
+ void *buffer;
+
+ buffer = malloc (capacity);
+
+ if (buffer == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/OutOfMemoryError",
+ "unable to allocate memory for direct byte buffer");
+ return 0;
+ }
+
+ return NIOGetRawData (env, buffer);
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_free
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)), jobject address)
+{
+ free (NIOGetPointer (env, address));
+}
+
+JNIEXPORT jbyte JNICALL
+Java_java_nio_VMDirectByteBuffer_get__Lgnu_classpath_RawData_2I
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint index)
+{
+ return ((jbyte *) NIOGetPointer (env, address))[index];
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_put
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint index, jbyte value)
+{
+ jbyte *pointer = (jbyte *) NIOGetPointer (env, address) + index;
+ *pointer = value;
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_get__Lgnu_classpath_RawData_2I_3BII
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint index, jbyteArray dst, jint dst_offset, jint dst_len)
+{
+ jbyte *src = (jbyte *) NIOGetPointer (env, address) + index;
+ memcpy ((*env)->GetByteArrayElements (env, dst, NULL) + dst_offset, src,
+ dst_len);
+}
+
+JNIEXPORT void JNICALL
+Java_java_nio_VMDirectByteBuffer_shiftDown
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint dst_offset, jint src_offset, jint count)
+{
+ jbyte *dst = (jbyte *) NIOGetPointer (env, address) + dst_offset;
+ jbyte *src = (jbyte *) NIOGetPointer (env, address) + src_offset;
+ memmove (dst, src, count);
+}
+
+JNIEXPORT jobject JNICALL
+Java_java_nio_VMDirectByteBuffer_adjustAddress
+ (JNIEnv * env, jclass clazz __attribute__ ((__unused__)),
+ jobject address, jint offset)
+{
+ return NIOGetRawData (env, (jbyte *) NIOGetPointer (env, address) + offset);
+}
diff --git a/libjava/classpath/native/jni/java-util/.cvsignore b/libjava/classpath/native/jni/java-util/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/jni/java-util/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/java-util/Makefile.am b/libjava/classpath/native/jni/java-util/Makefile.am
new file mode 100644
index 00000000000..da617f6a2b8
--- /dev/null
+++ b/libjava/classpath/native/jni/java-util/Makefile.am
@@ -0,0 +1,7 @@
+pkglib_LTLIBRARIES = libjavautil.la
+
+libjavautil_la_SOURCES = java_util_VMTimeZone.c
+
+AM_LDFLAGS = @CLASSPATH_MODULE@
+AM_CPPFLAGS = @CLASSPATH_INCLUDES@
+AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
diff --git a/libjava/classpath/native/jni/java-util/java_util_VMTimeZone.c b/libjava/classpath/native/jni/java-util/java_util_VMTimeZone.c
new file mode 100644
index 00000000000..a3a986d36bc
--- /dev/null
+++ b/libjava/classpath/native/jni/java-util/java_util_VMTimeZone.c
@@ -0,0 +1,223 @@
+/* VMTimeZone.c - Native method for java.util.VMTimeZone
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "config.h"
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <jni.h>
+
+#include "java_util_VMTimeZone.h"
+
+static size_t jint_to_charbuf (char *bufend, jint num);
+
+/**
+ * This method returns a time zone id string which is in the form
+ * (standard zone name) or (standard zone name)(GMT offset) or
+ * (standard zone name)(GMT offset)(daylight time zone name). The
+ * GMT offset can be in seconds, or where it is evenly divisible by
+ * 3600, then it can be in hours. The offset must be the time to
+ * add to the local time to get GMT. If a offset is given and the
+ * time zone observes daylight saving then the (daylight time zone
+ * name) must also be given (otherwise it is assumed the time zone
+ * does not observe any daylight savings).
+ * <p>
+ * The result of this method is given to getDefaultTimeZone(String)
+ * which tries to map the time zone id to a known TimeZone. See
+ * that method on how the returned String is mapped to a real
+ * TimeZone object.
+ */
+JNIEXPORT jstring JNICALL
+Java_java_util_VMTimeZone_getSystemTimeZoneId (JNIEnv * env,
+ jclass clazz
+ __attribute__ ((__unused__)))
+{
+ struct tm tim;
+#ifndef HAVE_LOCALTIME_R
+ struct tm *lt_tim;
+#endif
+#ifdef HAVE_TM_ZONE
+ int month;
+#endif
+ time_t current_time;
+ long tzoffset;
+ const char *tz1, *tz2;
+ char tzoff[11];
+ size_t tz1_len, tz2_len, tzoff_len;
+ char *tzid;
+ jstring retval;
+
+ time (&current_time);
+#ifdef HAVE_LOCALTIME_R
+ localtime_r (&current_time, &tim);
+#else
+ /* Fall back on non-thread safe localtime. */
+ lt_tim = localtime (&current_time);
+ memcpy (&tim, lt_tim, sizeof (struct tm));
+#endif
+ mktime (&tim);
+
+#ifdef HAVE_STRUCT_TM_TM_ZONE
+ /* We will cycle through the months to make sure we hit dst. */
+ month = tim.tm_mon;
+ tz1 = tz2 = NULL;
+ while (tz1 == NULL || tz2 == NULL)
+ {
+ if (tim.tm_isdst > 0)
+ tz2 = tim.tm_zone;
+ else if (tz1 == NULL)
+ {
+ tz1 = tim.tm_zone;
+ month = tim.tm_mon;
+ }
+
+ if (tz1 == NULL || tz2 == NULL)
+ {
+ tim.tm_mon++;
+ tim.tm_mon %= 12;
+ }
+
+ if (tim.tm_mon == month && tz2 == NULL)
+ tz2 = "";
+ else
+ mktime (&tim);
+ }
+ /* We want to make sure the tm struct we use later on is not dst. */
+ tim.tm_mon = month;
+ mktime (&tim);
+#elif defined (HAVE_TZNAME)
+ /* If dst is never used, tzname[1] is the empty string. */
+ tzset ();
+ tz1 = tzname[0];
+ tz2 = tzname[1];
+#else
+ /* Some targets have no concept of timezones. Assume GMT without dst. */
+ tz1 = "GMT";
+ tz2 = "";
+#endif
+
+#ifdef STRUCT_TM_HAS_GMTOFF
+ /* tm_gmtoff is the number of seconds that you must add to GMT to get
+ local time, we need the number of seconds to add to the local time
+ to get GMT. */
+ tzoffset = -1L * tim.tm_gmtoff;
+#elif HAVE_UNDERSCORE_TIMEZONE
+ /* On some systems _timezone is actually defined as time_t. */
+ tzoffset = (long) _timezone;
+#elif HAVE_TIMEZONE
+ /* timezone is secs WEST of UTC. */
+ tzoffset = timezone;
+#else
+ /* FIXME: there must be another global if neither tm_gmtoff nor timezone
+ is available, esp. if tzname is valid.
+ Richard Earnshaw <rearnsha@arm.com> has suggested using difftime to
+ calculate between gmtime and localtime (and accounting for possible
+ daylight savings time) as an alternative. */
+ tzoffset = 0L;
+#endif
+
+ if ((tzoffset % 3600) == 0)
+ tzoffset = tzoffset / 3600;
+
+ tz1_len = strlen (tz1);
+ tz2_len = strlen (tz2);
+ tzoff_len = jint_to_charbuf (tzoff + 11, tzoffset);
+ tzid = (char *) malloc (tz1_len + tz2_len + tzoff_len + 1); /* FIXME alloc */
+ memcpy (tzid, tz1, tz1_len);
+ memcpy (tzid + tz1_len, tzoff + 11 - tzoff_len, tzoff_len);
+ memcpy (tzid + tz1_len + tzoff_len, tz2, tz2_len);
+ tzid[tz1_len + tzoff_len + tz2_len] = '\0';
+
+ retval = (*env)->NewStringUTF (env, tzid);
+ free (tzid);
+
+ return retval;
+}
+
+/* Put printed (decimal) representation of NUM in a buffer.
+ BUFEND marks the end of the buffer, which must be at least 11 chars long.
+ Returns the COUNT of chars written. The result is in
+ (BUFEND - COUNT) (inclusive) upto (BUFEND) (exclusive).
+
+ Note that libgcj has a slightly different version called _Jv_FormatInt
+ that works on jchar buffers.
+*/
+
+static size_t
+jint_to_charbuf (char *bufend, jint num)
+{
+ register char *ptr = bufend;
+ jboolean isNeg;
+ if (num < 0)
+ {
+ isNeg = JNI_TRUE;
+ num = -(num);
+ if (num < 0)
+ {
+ /* Must be MIN_VALUE, so handle this special case.
+ FIXME use 'unsigned jint' for num. */
+ *--ptr = '8';
+ num = 214748364;
+ }
+ }
+ else
+ isNeg = JNI_FALSE;
+
+ do
+ {
+ *--ptr = (char) ((int) '0' + (num % 10));
+ num /= 10;
+ }
+ while (num > 0);
+
+ if (isNeg)
+ *--ptr = '-';
+ return bufend - ptr;
+}
diff --git a/libjava/classpath/native/jni/xmlj/.cvsignore b/libjava/classpath/native/jni/xmlj/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/xmlj/BUGS b/libjava/classpath/native/jni/xmlj/BUGS
new file mode 100644
index 00000000000..801700cf1b0
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/BUGS
@@ -0,0 +1,35 @@
+GNU Jaxp
+------------------------------------------------------------------------
+
+These bugs are for the gnu.xml.libxmlj package.
+
+CAVEAT: LibxmlJ's current incarnation is incomplete and partly
+incorrect. Highly experimental.
+
+- Thread-safe, but effectively runs single-threaded.
+
+- Native code passes incorrect URIs to URIResolver.resolve.
+
+- Default output properties accessible through JAXP always assume XML
+ output (in violation of the XSLT 1.0 specification, section 16)
+ Correction: LibxmlJ always assumes XML output.
+
+- OutputProperties are not properly implemented, compare code and API
+ documentation.
+
+- TransformerFactory.getAttribute() and
+ TransformerFactory.setAttribute() not implemented, i.e. low-level
+ libxslt settings can currently not be accessed from Java.
+
+- TransformerFactory.getFeature() not implemented, i.e. currently no
+ low-level features of libxslt are advertised.
+
+FIXME:
+
+- Make LRU caching configurable.
+
+- Check whether <?xml encoding="..."?> headers are honored.
+
+- DefaultURIResolver uses naive approach.
+
+- TransformerFactory.getAssociatedStyleSheet() unfinished.
diff --git a/libjava/classpath/native/jni/xmlj/Makefile.am b/libjava/classpath/native/jni/xmlj/Makefile.am
new file mode 100644
index 00000000000..b0f1f9104de
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/Makefile.am
@@ -0,0 +1,25 @@
+pkglib_LTLIBRARIES = libxmlj.la
+
+libxmlj_la_SOURCES = \
+xmlj_dom.c \
+xmlj_dom.h \
+xmlj_error.c \
+xmlj_error.h \
+xmlj_io.c \
+xmlj_io.h \
+xmlj_node.c \
+xmlj_node.h \
+xmlj_sax.c \
+xmlj_sax.h \
+xmlj_transform.c \
+xmlj_util.c \
+xmlj_util.h \
+xmlj_xpath.c
+
+AM_LDFLAGS = @CLASSPATH_MODULE@ @XML_LIBS@ @XSLT_LIBS@
+AM_CPPFLAGS = @CLASSPATH_INCLUDES@
+
+# Don't enable ERROR flags. Code isn't warning free yet.
+AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @XML_CFLAGS@ @XSLT_CFLAGS@
+
+EXTRA_DIST = BUGS
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_dom.c b/libjava/classpath/native/jni/xmlj/xmlj_dom.c
new file mode 100644
index 00000000000..b9bd372b17b
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_dom.c
@@ -0,0 +1,2617 @@
+/* xmlj_dom.c -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_dom.h"
+#include "xmlj_error.h"
+#include "xmlj_io.h"
+#include "xmlj_node.h"
+#include "xmlj_sax.h"
+#include "xmlj_util.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+JNIEnv *dom_cb_env;
+jobject dom_cb_obj;
+
+typedef struct
+{
+ int index;
+ int count;
+ xmlNodePtr node;
+}
+xmljHashScanData;
+
+/* Prototypes for local functions */
+
+void
+xmljAddAttribute (xmlNodePtr node, xmlAttrPtr attr);
+
+void
+xmljHashScanner (void *payload, void *vdata, xmlChar *name);
+
+xmlChar *
+xmljGetNodeValue (xmlNodePtr node);
+
+/*
+ * Determines whether a child node is suitable for insertion in the list of
+ * children for a given parent node.
+ * Returns 0 on success, a DOMException code otherwise.
+ */
+void
+xmljValidateChildNode (JNIEnv *env, xmlNodePtr parent, xmlNodePtr child)
+{
+ xmlNodePtr cur;
+
+ if (child == NULL || parent == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return;
+ }
+ if (child->doc != parent->doc)
+ {
+ xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
+ return;
+ }
+ /* Check that new parent is of an allowed type */
+ switch (parent->type)
+ {
+ case XML_CDATA_SECTION_NODE:
+ case XML_COMMENT_NODE:
+ case XML_TEXT_NODE:
+ case XML_ENTITY_NODE:
+ case XML_ENTITY_REF_NODE:
+ case XML_NOTATION_NODE:
+ case XML_PI_NODE:
+ /* these can't have any children */
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "parent type does not allow children");
+ return;
+ case XML_ATTRIBUTE_NODE:
+ if (child->type != XML_TEXT_NODE &&
+ child->type != XML_ENTITY_REF_NODE)
+ {
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "attributes may only contain text or entity reference nodes");
+ return;
+ }
+ break;
+ case XML_DOCUMENT_FRAG_NODE:
+ case XML_ELEMENT_NODE:
+ if (child->type == XML_DTD_NODE ||
+ child->type == XML_DOCUMENT_TYPE_NODE ||
+ child->type == XML_ENTITY_NODE ||
+ child->type == XML_NOTATION_NODE ||
+ child->type == XML_PI_NODE)
+ {
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "parent type does not allow child of this type");
+ return;
+ }
+ /* fall through */
+ default:
+ if (child->type == XML_ATTRIBUTE_NODE ||
+ child->type == XML_DOCUMENT_NODE ||
+ child->type == XML_DOCUMENT_FRAG_NODE)
+ {
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "node type may not be a child");
+ return;
+ }
+ /* TODO others? */
+ }
+ /* Check that new parent is not self or an ancestor */
+ for (cur = parent; cur != NULL; cur = cur->parent)
+ {
+ if (cur == child)
+ {
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "child cannot be an ancestor of itself");
+ return;
+ }
+ }
+ /* Check that new parent does not add a second doctype or root element
+ * to a document parent */
+ if (parent->type == XML_DOCUMENT_NODE)
+ {
+ cur = parent->children;
+ while (cur != NULL)
+ {
+ if (cur->type == XML_DTD_NODE ||
+ cur->type == XML_DOCUMENT_TYPE_NODE ||
+ (cur->type == XML_ELEMENT_NODE &&
+ parent->type == XML_DOCUMENT_NODE))
+ {
+ if (child->type == cur->type && child != cur)
+ {
+ /* HIERARCHY_REQUEST_ERR */
+ xmljThrowDOMException (env, 3, "cannot add a second doctype or root element");
+ return;
+ }
+ }
+ cur = cur->next;
+ }
+ }
+}
+
+/*
+ * Adds the specified attribute node to the list of attributes for the given
+ * element.
+ */
+void
+xmljAddAttribute (xmlNodePtr node, xmlAttrPtr attr)
+{
+ xmlAttrPtr cur = node->properties;
+
+ if (cur == NULL)
+ {
+ node->properties = attr;
+ attr->prev = NULL;
+ attr->next = NULL;
+ attr->parent = node;
+ attr->doc = node->doc;
+ }
+ else
+ {
+ while (cur->next != NULL)
+ {
+ cur = cur->next;
+ }
+ cur->next = attr;
+ attr->prev = cur;
+ attr->next = NULL;
+ attr->parent = node;
+ attr->doc = node->doc;
+ }
+}
+
+/* -- GnomeAttr -- */
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeAttr_getSpecified (JNIEnv * env, jobject self)
+{
+ xmlAttrPtr attr;
+
+ attr = (xmlAttrPtr) xmljGetNodeID (env, self);
+ return (attr->atype != 0);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeAttr_getValue (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+ xmlChar *text;
+ jstring ret;
+
+ node = xmljGetNodeID (env, self);
+ text = xmlNodeGetContent (node);
+ ret = xmljNewString (env, (const xmlChar *) text);
+ if (text != NULL)
+ {
+ xmlFree (text);
+ }
+ return ret;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeAttr_setValue (JNIEnv * env,
+ jobject self, jstring value)
+{
+ xmlNodePtr node;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_value = xmljGetStringChars (env, value);
+ xmlNodeSetContent (node, s_value);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeAttr_xmljIsId (JNIEnv * env, jobject self)
+{
+ xmlAttrPtr attr;
+
+ attr = (xmlAttrPtr) xmljGetNodeID (env, self);
+ return (attr->atype == XML_ATTRIBUTE_ID);
+}
+
+/* -- GnomeDocument -- */
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_free (JNIEnv * env,
+ jobject self
+ __attribute__ ((__unused__)),
+ jobject id)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljAsPointer (env, id);
+ xmljFreeDoc (env, doc);
+ xmlFree (doc);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getDoctype (JNIEnv * env, jobject self)
+{
+ xmlDocPtr doc;
+ xmlDtdPtr dtd;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ dtd = doc->extSubset;
+ if (dtd == NULL)
+ {
+ dtd = doc->intSubset;
+ }
+ return xmljGetNodeInstance (env, (xmlNodePtr) dtd);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getDocumentElement (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, xmlDocGetRootElement (doc));
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createDocumentType (JNIEnv * env,
+ jobject self,
+ jstring name,
+ jstring publicId,
+ jstring systemId)
+{
+ xmlDocPtr doc;
+ xmlDtdPtr dtd;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ dtd = xmlNewDtd (doc,
+ xmljGetStringChars (env, name),
+ xmljGetStringChars (env, publicId),
+ xmljGetStringChars (env, systemId));
+ return xmljGetNodeInstance (env, (xmlNodePtr) dtd);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createDocumentFragment (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, xmlNewDocFragment (doc));
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createTextNode (JNIEnv * env,
+ jobject self,
+ jstring data)
+{
+ xmlDocPtr doc;
+ xmlNodePtr text;
+ const xmlChar *s_data;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_data = xmljGetStringChars (env, data);
+ text = xmlNewDocText (doc, s_data);
+ return xmljGetNodeInstance (env, text);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createComment (JNIEnv * env,
+ jobject self,
+ jstring data)
+{
+ xmlDocPtr doc;
+ xmlNodePtr comment;
+ const xmlChar *s_data;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_data = xmljGetStringChars (env, data);
+ comment = xmlNewDocComment (doc, s_data);
+ return xmljGetNodeInstance (env, comment);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createCDATASection (JNIEnv * env,
+ jobject self,
+ jstring data)
+{
+ xmlDocPtr doc;
+ xmlNodePtr cdata;
+ const xmlChar *s_data;
+ int len;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_data = xmljGetStringChars (env, data);
+ len = xmlStrlen (s_data);
+ cdata = xmlNewCDataBlock (doc, s_data, len);
+ return xmljGetNodeInstance (env, cdata);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createProcessingInstruction (JNIEnv *
+ env,
+ jobject
+ self,
+ jstring
+ target,
+ jstring
+ data)
+{
+ xmlDocPtr doc;
+ xmlNodePtr pi;
+ const xmlChar *s_target;
+ const xmlChar *s_data;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_target = xmljGetStringChars (env, target);
+ s_data = xmljGetStringChars (env, data);
+ pi = xmlNewPI (s_target, s_data);
+ pi->doc = doc;
+ return xmljGetNodeInstance (env, pi);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createEntityReference (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ xmlDocPtr doc;
+ xmlNodePtr ref;
+ const xmlChar *s_name;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_name = xmljGetStringChars (env, name);
+ ref = xmlNewReference (doc, s_name);
+ return xmljGetNodeInstance (env, ref);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_xmljImportNode (JNIEnv * env,
+ jobject self,
+ jobject importedNode,
+ jboolean deep)
+{
+ xmlDocPtr doc;
+ xmlNodePtr node;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ node = xmljGetNodeID (env, importedNode);
+ if (node == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ if (node->type == XML_DOCUMENT_NODE ||
+ node->type == XML_DOCUMENT_TYPE_NODE)
+ {
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return NULL;
+ }
+ node = xmlDocCopyNode (node, doc, deep);
+ return xmljGetNodeInstance (env, node);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createElementNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring qName)
+{
+ xmlDocPtr doc;
+ xmlNodePtr element;
+ xmlNsPtr ns = NULL;
+ const xmlChar *s_uri;
+ const xmlChar *s_qName;
+ const xmlChar *s_prefix;
+ const xmlChar *s_localName;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_qName = xmljGetStringChars (env, qName);
+ if (xmlValidateQName (s_qName, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ return NULL;
+ }
+ if (uri != NULL)
+ {
+ s_uri = xmljGetStringChars (env, uri);
+ s_prefix = xmljGetPrefix (s_qName);
+ s_localName = xmljGetLocalName (s_qName);
+ ns = xmlNewNs ((xmlNodePtr) doc, s_uri, s_prefix);
+ }
+ element = xmlNewDocNode (doc, ns, s_qName, NULL);
+ return xmljGetNodeInstance (env, element);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_createAttributeNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring qName)
+{
+ xmlDocPtr doc;
+ xmlNodePtr attr;
+ xmlNsPtr ns = NULL;
+ const xmlChar *s_uri;
+ const xmlChar *s_qName;
+ const xmlChar *s_prefix;
+ const xmlChar *s_localName;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ s_qName = xmljGetStringChars (env, qName);
+ if (xmlValidateQName (s_qName, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ return NULL;
+ }
+ if (uri != NULL)
+ {
+ s_uri = xmljGetStringChars (env, uri);
+ s_prefix = xmljGetPrefix (s_qName);
+ s_localName = xmljGetLocalName (s_qName);
+ ns = xmlNewNs ((xmlNodePtr) doc, s_uri, s_prefix);
+ }
+ attr = (xmlNodePtr) xmlNewNsProp ((xmlNodePtr) doc, ns, s_qName, NULL);
+ attr->parent = NULL;
+ return xmljGetNodeInstance (env, attr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_xmljGetElementById (JNIEnv * env,
+ jobject self,
+ jstring elementId)
+{
+ xmlDocPtr doc;
+ xmlNodePtr ctx, tmp;
+ xmlAttrPtr attr;
+ const xmlChar *id;
+ const xmlChar *val;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ id = xmljGetStringChars (env, elementId);
+
+ ctx = xmlDocGetRootElement (doc);
+ while (ctx && ctx != (xmlNodePtr) doc)
+ {
+ if (ctx->type == XML_ELEMENT_NODE)
+ {
+ for (attr = ctx->properties; attr;
+ attr = (xmlAttrPtr) attr->next)
+ {
+ if (xmlIsID (doc, ctx, attr))
+ {
+ val = xmlGetProp (ctx, attr->name);
+ if (val && xmlStrEqual (id, val))
+ {
+ return xmljGetNodeInstance (env, ctx);
+ }
+ }
+ }
+ }
+ if (ctx->children)
+ {
+ ctx = ctx->children;
+ }
+ else
+ {
+ tmp = ctx->next;
+ if (tmp)
+ {
+ ctx = tmp;
+ }
+ else
+ {
+ do
+ {
+ tmp = ctx->parent;
+ if (!tmp)
+ {
+ return NULL;
+ }
+ ctx = tmp;
+ tmp = ctx->next;
+ }
+ while (!tmp);
+ ctx = tmp;
+ }
+ }
+ }
+ return NULL;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getInputEncoding (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ if (doc->encoding)
+ {
+ return xmljNewString (env, doc->encoding);
+ }
+ switch (doc->charset)
+ {
+ case XML_CHAR_ENCODING_ASCII:
+ return xmljNewString (env, BAD_CAST "US-ASCII");
+ case XML_CHAR_ENCODING_UTF16LE:
+ return xmljNewString (env, BAD_CAST "UTF-16LE");
+ case XML_CHAR_ENCODING_UTF16BE:
+ return xmljNewString (env, BAD_CAST "UTF-16BE");
+ case XML_CHAR_ENCODING_8859_1:
+ return xmljNewString (env, BAD_CAST "ISO-8859-1");
+ /* TODO others */
+ default:
+ return xmljNewString (env, BAD_CAST "UTF-8");
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getXmlEncoding (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return (doc->encoding == NULL) ?
+ xmljNewString (env, BAD_CAST "UTF-8") :
+ xmljNewString (env, doc->encoding);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getXmlStandalone (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return doc->standalone;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_setXmlStandalone (JNIEnv * env,
+ jobject self,
+ jboolean xmlStandalone)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ doc->standalone = xmlStandalone;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getXmlVersion (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return (doc->version == NULL) ?
+ xmljNewString (env, BAD_CAST "1.0") :
+ xmljNewString (env, doc->version);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_setXmlVersion (JNIEnv * env,
+ jobject self,
+ jstring xmlVersion)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ if (xmlVersion == NULL)
+ {
+ doc->version = NULL;
+ }
+ else
+ {
+ const xmlChar *version = xmljGetStringChars (env, xmlVersion);
+ if (!xmlStrEqual (version, BAD_CAST "1.0") &&
+ !xmlStrEqual (version, BAD_CAST "1.1"))
+ {
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return;
+ }
+ doc->version = version;
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getDocumentURI (JNIEnv * env,
+ jobject self)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ return (doc->name == NULL) ? NULL :
+ xmljNewString (env, (const xmlChar *) doc->URL);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_setDocumentURI (JNIEnv * env,
+ jobject self,
+ jstring documentURI)
+{
+ xmlDocPtr doc;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ if (documentURI == NULL)
+ {
+ doc->URL = NULL;
+ }
+ else
+ {
+ doc->URL = xmljGetStringChars (env, documentURI);
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_xmljAdoptNode (JNIEnv *env,
+ jobject self,
+ jobject jnode)
+{
+ xmlDocPtr doc;
+ xmlNodePtr node;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, self);
+ node = xmljGetNodeID (env, jnode);
+
+ if (node == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ if (node->type == XML_DOCUMENT_NODE ||
+ node->type == XML_DOCUMENT_TYPE_NODE ||
+ node->type == XML_ENTITY_NODE ||
+ node->type == XML_NOTATION_NODE)
+ {
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return NULL;
+ }
+ xmlUnlinkNode (node);
+ node = xmlDocCopyNode (node, doc, 1);
+ return xmljGetNodeInstance (env, node);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_renameNode (JNIEnv * env,
+ jobject self
+ __attribute__ ((__unused__)),
+ jobject n
+ __attribute__ ((__unused__)),
+ jstring namespaceURI
+ __attribute__ ((__unused__)),
+ jstring qName
+ __attribute__ ((__unused__)))
+{
+ xmlNodePtr node;
+ xmlNsPtr ns;
+ const xmlChar *s_qName;
+ const xmlChar *href;
+ const xmlChar *prefix;
+ int *len;
+
+ node = xmljGetNodeID (env, n);
+ if (node == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ s_qName = xmljGetStringChars (env, qName);
+ if (xmlValidateQName (s_qName, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ return NULL;
+ }
+ xmlNodeSetName (node, s_qName);
+
+ href = xmljGetStringChars (env, namespaceURI);
+ len = (int *) malloc (sizeof (int));
+ prefix = xmlSplitQName3 (s_qName, len);
+ ns = node->ns;
+ if (ns == NULL)
+ {
+ if (href != NULL)
+ {
+ ns = xmlNewNs (node, href, prefix);
+ xmlSetNs (node, ns);
+ }
+ }
+ else
+ {
+ node->ns = NULL;
+ /*xmlFreeNs (ns); FIXME this can segfault (?) */
+ if (href != NULL)
+ {
+ ns = xmlNewNs (node, href, prefix);
+ xmlSetNs (node, ns);
+ }
+ }
+ free (len);
+ return n;
+}
+
+/* -- GnomeDocumentBuilder -- */
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocumentBuilder_parseStream (JNIEnv * env,
+ jobject self,
+ jobject in,
+ jbyteArray
+ detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean coalesce,
+ jboolean
+ expandEntities,
+ jboolean
+ entityResolver,
+ jboolean
+ errorHandler)
+{
+ xmlDocPtr doc;
+
+ doc = xmljParseDocument(env,
+ self,
+ in,
+ detectBuffer,
+ publicId,
+ systemId,
+ base,
+ validate,
+ coalesce,
+ expandEntities,
+ 0,
+ 0,
+ entityResolver,
+ errorHandler,
+ 0,
+ 0,
+ 1);
+ return xmljCreateDocument (env, self, doc);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocumentBuilder_createDocument
+(JNIEnv * env,
+ jobject self,
+ jstring namespaceURI,
+ jstring qualifiedName,
+ jobject doctype)
+{
+ xmlDocPtr doc;
+ xmlNodePtr root;
+ xmlNsPtr ns;
+ const xmlChar *href;
+ const xmlChar *prefix;
+ const xmlChar *qName;
+
+ qName = xmljGetStringChars (env, qualifiedName);
+ href = xmljGetStringChars (env, namespaceURI);
+ if (qName == NULL)
+ {
+ prefix = NULL;
+ }
+ else
+ {
+ int *len;
+
+ len = (int *) malloc (sizeof (int));
+ prefix = xmlSplitQName3 (qName, len);
+ free (len);
+ }
+
+ /* Create the document node */
+ doc = xmlNewDoc (BAD_CAST "1.0");
+
+ /* doctype */
+ if (doctype != NULL)
+ {
+ jclass cls;
+ jmethodID method;
+ jstring ret;
+ const xmlChar *name;
+ const xmlChar *publicId;
+ const xmlChar *systemId;
+ const xmlChar *internalSubset;
+ xmlDtdPtr dtd;
+
+ cls = (*env)->FindClass (env, "org/w3c/dom/DocumentType");
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ /* name */
+ method = (*env)->GetMethodID (env, cls, "getName",
+ "()Ljava/lang/String;");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
+ name = xmljGetStringChars (env, ret);
+
+ /* publicId */
+ method = (*env)->GetMethodID (env, cls, "getPublicId",
+ "()Ljava/lang/String;");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
+ publicId = xmljGetStringChars (env, ret);
+
+ /* systemId */
+ method = (*env)->GetMethodID (env, cls, "getSystemId",
+ "()Ljava/lang/String;");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
+ systemId = xmljGetStringChars (env, ret);
+
+ /* internalSubset */
+ method = (*env)->GetMethodID (env, cls, "getInternalSubset",
+ "()Ljava/lang/String;");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
+ internalSubset = xmljGetStringChars (env, ret);
+
+ /* TODO notations */
+ /* TODO entities */
+ if (internalSubset == NULL)
+ {
+ dtd = xmlNewDtd (doc, name, publicId, systemId);
+ }
+ else
+ {
+ dtd = xmlCreateIntSubset (doc, name, publicId, systemId);
+ /* TODO parse internal subset? */
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return NULL;
+ }
+ }
+
+ /* Create the root element */
+ root = xmlNewNode (NULL, qName);
+ xmlDocSetRootElement (doc, root);
+ ns = xmlNewNs (root, href, prefix);
+ xmlSetNs (root, ns);
+
+ return xmljCreateDocument (env, self, doc);
+}
+
+/* -- GnomeDocumentType -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocumentType_getPublicId (JNIEnv * env,
+ jobject self)
+{
+ xmlDtdPtr dtd;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ return xmljNewString (env, dtd->ExternalID);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocumentType_getSystemId (JNIEnv * env,
+ jobject self)
+{
+ xmlDtdPtr dtd;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ return xmljNewString (env, dtd->SystemID);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocumentType_getInternalSubset (JNIEnv * env,
+ jobject self
+ __attribute__ ((__unused__)))
+{
+ /* TODO */
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return NULL;
+}
+
+/* -- GnomeElement -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getAttribute (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ xmlNodePtr node;
+ const xmlChar *s_name;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_name = xmljGetStringChars (env, name);
+ s_value = xmlGetProp (node, s_name);
+ xmlFree ((xmlChar *) s_name);
+ return (s_value == NULL) ?
+ xmljNewString (env, BAD_CAST "") :
+ xmljNewString (env, s_value);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_setAttribute (JNIEnv * env,
+ jobject self,
+ jstring name,
+ jstring value)
+{
+ xmlNodePtr node;
+ const xmlChar *s_name;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_name = xmljGetStringChars (env, name);
+ if (xmlValidateName (s_name, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ return;
+ }
+ s_value = xmljGetStringChars (env, value);
+ xmlSetProp (node, s_name, s_value);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getAttributeNode (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ xmlNodePtr node;
+ const xmlChar *s_name;
+ xmlAttrPtr attr;
+
+ node = xmljGetNodeID (env, self);
+ s_name = xmljGetStringChars (env, name);
+ attr = xmlHasProp (node, s_name);
+ if (attr == NULL)
+ {
+ return NULL;
+ }
+ xmlFree ((xmlChar *) s_name);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_setAttributeNode (JNIEnv * env,
+ jobject self,
+ jobject newAttr)
+{
+ xmlNodePtr node;
+ xmlAttrPtr new_attr;
+ xmlAttrPtr old_attr;
+
+ node = xmljGetNodeID (env, self);
+ new_attr = (xmlAttrPtr) xmljGetNodeID (env, newAttr);
+ if (new_attr->parent != NULL)
+ {
+ xmljThrowDOMException (env, 10, NULL); /* INUSE_ATTRIBUTE_ERR */
+ return NULL;
+ }
+ if (new_attr->doc != node->doc)
+ {
+ xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
+ return NULL;
+ }
+ old_attr = xmlHasProp (node, new_attr->name);
+ if (old_attr)
+ {
+ xmlUnlinkNode ((xmlNodePtr) old_attr);
+ }
+ xmljAddAttribute (node, new_attr);
+ return xmljGetNodeInstance (env, (xmlNodePtr) old_attr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_removeAttributeNode (JNIEnv * env,
+ jobject self
+ __attribute__ ((__unused__)),
+ jobject oldAttr)
+{
+ xmlNodePtr attr;
+
+ attr = xmljGetNodeID (env, oldAttr);
+ xmlUnlinkNode (attr);
+ return oldAttr;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getAttributeNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ xmlNodePtr node;
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_localName = xmljGetStringChars (env, localName);
+ if (uri == NULL)
+ {
+ s_value = xmlGetNoNsProp (node, s_localName);
+ }
+ else
+ {
+ s_uri = xmljGetStringChars (env, uri);
+ s_value = xmlGetNsProp (node, s_localName, s_uri);
+ xmlFree ((xmlChar *) s_uri);
+ }
+ xmlFree ((xmlChar *) s_localName);
+ return (s_value == NULL) ?
+ xmljNewString (env, BAD_CAST "") :
+ xmljNewString (env, s_value);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_setAttributeNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring qName,
+ jstring value)
+{
+ xmlNodePtr node;
+ xmlNsPtr ns;
+ const xmlChar *s_uri;
+ const xmlChar *s_qName;
+ const xmlChar *s_prefix;
+ const xmlChar *s_localName;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_qName = xmljGetStringChars (env, qName);
+ if (xmlValidateQName (s_qName, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ return;
+ }
+ s_value = xmljGetStringChars (env, value);
+ if (uri == NULL)
+ {
+ xmlSetProp (node, s_qName, s_value);
+ }
+ else
+ {
+ s_prefix = xmljGetPrefix (s_qName);
+ s_localName = xmljGetLocalName (s_qName);
+ s_uri = xmljGetStringChars (env, uri);
+ ns = xmlNewNs (node, s_uri, s_prefix);
+ xmlSetNsProp (node, ns, s_localName, s_value);
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getAttributeNodeNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+
+ node = xmljGetNodeID (env, self);
+ attr = node->properties;
+ s_uri = xmljGetStringChars (env, uri);
+ s_localName = xmljGetStringChars (env, localName);
+ while (attr != NULL)
+ {
+ if (uri == NULL)
+ {
+ if (xmljMatch (s_localName, (xmlNodePtr) attr))
+ break;
+ }
+ else
+ {
+ if (xmljMatchNS (s_uri, s_localName, (xmlNodePtr) attr))
+ break;
+ }
+ attr = attr->next;
+ }
+ xmlFree ((xmlChar *) s_uri);
+ xmlFree ((xmlChar *) s_localName);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_setAttributeNodeNS (JNIEnv * env,
+ jobject self,
+ jobject newAttr)
+{
+ xmlNodePtr node;
+ xmlAttrPtr new_attr;
+ xmlAttrPtr old_attr;
+ const xmlChar *uri;
+
+ node = xmljGetNodeID (env, self);
+ new_attr = (xmlAttrPtr) xmljGetNodeID (env, newAttr);
+ if (new_attr->parent != NULL)
+ {
+ xmljThrowDOMException (env, 10, NULL); /* INUSE_ATTRIBUTE_ERR */
+ return NULL;
+ }
+ if (new_attr->doc != node->doc)
+ {
+ xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
+ return NULL;
+ }
+ uri = (new_attr->ns != NULL) ? new_attr->ns->href : NULL;
+ old_attr = xmlHasNsProp (node, new_attr->name, uri);
+ if (old_attr)
+ {
+ xmlUnlinkNode ((xmlNodePtr) old_attr);
+ }
+ xmljAddAttribute (node, new_attr);
+ return xmljGetNodeInstance (env, (xmlNodePtr) old_attr);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_hasAttribute (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ xmlNodePtr node;
+ const xmlChar *s_name;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_name = xmljGetStringChars (env, name);
+ s_value = xmlGetProp (node, s_name);
+ xmlFree ((xmlChar *) s_name);
+ return (s_value != NULL);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_hasAttributeNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ xmlNodePtr node;
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+ const xmlChar *s_value;
+
+ node = xmljGetNodeID (env, self);
+ s_localName = xmljGetStringChars (env, localName);
+ if (uri == NULL)
+ {
+ s_value = xmlGetNoNsProp (node, s_localName);
+ }
+ else
+ {
+ s_uri = xmljGetStringChars (env, uri);
+ s_value = xmlGetNsProp (node, s_localName, s_uri);
+ xmlFree ((xmlChar *) s_uri);
+ }
+ xmlFree ((xmlChar *) s_localName);
+ return (s_value != NULL);
+}
+
+/* -- GnomeEntity -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeEntity_getPublicId (JNIEnv * env, jobject self)
+{
+ xmlEntityPtr entity;
+
+ entity = (xmlEntityPtr) xmljGetNodeID (env, self);
+ return xmljNewString (env, entity->ExternalID);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeEntity_getSystemId (JNIEnv * env, jobject self)
+{
+ xmlEntityPtr entity;
+
+ entity = (xmlEntityPtr) xmljGetNodeID (env, self);
+ return xmljNewString (env, entity->SystemID);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeEntity_getNotationName (JNIEnv * env,
+ jobject self
+ __attribute__ ((__unused__)))
+{
+ /* TODO */
+ xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
+ return NULL;
+}
+
+/* -- GnomeNamedNodeMap -- */
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_getNamedItem (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlAttrPtr attr;
+
+ attr = xmljGetNamedItem (env, self, name);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+ }
+ else
+ {
+ xmlDtdPtr dtd;
+ xmlHashTablePtr hash;
+ const xmlChar *s_name;
+ xmlNodePtr ret;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
+ if (hash == NULL)
+ {
+ return NULL;
+ }
+ s_name = xmljGetStringChars (env, name);
+ ret = (xmlNodePtr) xmlHashLookup (hash, s_name);
+ xmlFree ((xmlChar *) s_name);
+ return xmljGetNodeInstance (env, ret);
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_setNamedItem (JNIEnv * env,
+ jobject self,
+ jobject arg)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+ xmlNodePtr node;
+ xmlNodePtr argNode;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ node = xmljGetNodeID (env, self);
+ argNode = xmljGetNodeID (env, arg);
+
+ if (argNode->doc != node->doc)
+ {
+ xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
+ }
+ xmljValidateChildNode (env, node, argNode);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+ if (type == 0)
+ {
+ if (argNode->parent != NULL)
+ {
+ xmljThrowDOMException (env, 10, NULL); /* INUSE_ATTRIBUTE_ERR */
+ return NULL;
+ }
+ xmlAddChild (node, argNode);
+ }
+ else
+ {
+ xmlDtdPtr dtd;
+ xmlHashTablePtr hash;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
+ if (hash == NULL)
+ {
+ hash = xmlHashCreate (10);
+ if (type == 1)
+ {
+ dtd->entities = hash;
+ }
+ else
+ {
+ dtd->notations = hash;
+ }
+ }
+ xmlHashAddEntry (hash, argNode->name, argNode);
+ }
+ return arg;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_removeNamedItem (JNIEnv * env,
+ jobject self,
+ jstring name)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlAttrPtr attr;
+
+ attr = xmljGetNamedItem (env, self, name);
+ if (attr == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ xmlUnlinkNode ((xmlNodePtr) attr);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+ }
+ else
+ {
+ xmlDtdPtr dtd;
+ xmlHashTablePtr hash;
+ const xmlChar *s_name;
+ xmlNodePtr ret;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
+ if (hash == NULL)
+ {
+ return NULL;
+ }
+ s_name = xmljGetStringChars (env, name);
+ ret = (xmlNodePtr) xmlHashLookup (hash, s_name);
+ if (ret != NULL)
+ {
+ xmlHashRemoveEntry (hash, s_name, NULL);
+ }
+ xmlFree ((xmlChar *) s_name);
+ return xmljGetNodeInstance (env, ret);
+ }
+}
+
+void
+xmljHashScanner (void *payload, void *vdata, xmlChar *name)
+{
+ xmljHashScanData *data;
+
+ data = (xmljHashScanData *) vdata;
+ if (data->count <= data->index)
+ {
+ data->node = (xmlNodePtr) payload;
+ }
+ data->count++;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_item (JNIEnv * env,
+ jobject self, jint index)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ jint count;
+
+ node = xmljGetNodeID (env, self);
+ switch (node->type)
+ {
+ case XML_ELEMENT_NODE:
+ attr = node->properties;
+ for (count = 0; attr != NULL && count < index; count++)
+ {
+ attr = attr->next;
+ }
+ if (attr == NULL)
+ {
+ char msg[1024];
+ sprintf (msg, "No attribute at index %d\n", (int) index);
+ xmljThrowException (env, "java/lang/NullPointerException", msg);
+ return NULL;
+ }
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+ default:
+ return NULL;
+ }
+ }
+ else
+ {
+ xmlDtdPtr dtd;
+ xmlHashTablePtr hash;
+ xmljHashScanData *data;
+ xmlNodePtr ret;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
+ if (hash == NULL)
+ {
+ return NULL;
+ }
+ data = (xmljHashScanData *) malloc (sizeof (xmljHashScanData));
+ if (data == NULL)
+ {
+ return NULL;
+ }
+ data->index = index;
+ data->count = 0;
+ data->node = NULL;
+ xmlHashScan (hash, xmljHashScanner, data);
+ ret = data->node;
+ free (data);
+ return xmljGetNodeInstance (env, ret);
+ }
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_getLength (JNIEnv * env,
+ jobject self)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ jint count;
+
+ node = xmljGetNodeID (env, self);
+ switch (node->type)
+ {
+ case XML_ELEMENT_NODE:
+ count = 0;
+ attr = node->properties;
+ while (attr != NULL)
+ {
+ count++;
+ attr = attr->next;
+ }
+ return count;
+ default:
+ return -1;
+ }
+ }
+ else
+ {
+ xmlDtdPtr dtd;
+ xmlHashTablePtr hash;
+ xmljHashScanData *data;
+ jint ret;
+
+ dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
+ hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
+ if (hash == NULL)
+ {
+ return 0;
+ }
+ data = (xmljHashScanData *) malloc (sizeof (xmljHashScanData));
+ if (data == NULL)
+ {
+ return 0;
+ }
+ data->index = -1;
+ data->count = 0;
+ data->node = NULL;
+ xmlHashScan (hash, xmljHashScanner, data);
+ ret = data->count;
+ free (data);
+ return ret;
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_getNamedItemNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlAttrPtr attr;
+
+ attr = xmljGetNamedItemNS (env, self, uri, localName);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_setNamedItemNS (JNIEnv * env,
+ jobject self,
+ jobject arg)
+{
+ return Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_setNamedItem (env, self,
+ arg);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_removeNamedItemNS (JNIEnv * env,
+ jobject self,
+ jstring uri,
+ jstring
+ localName)
+{
+ jclass cls;
+ jfieldID field;
+ jint type;
+
+ cls = (*env)->GetObjectClass (env, self);
+ field = (*env)->GetFieldID (env, cls, "type", "I");
+ type = (*env)->GetIntField (env, self, field);
+
+ if (type == 0)
+ {
+ xmlAttrPtr attr;
+
+ attr = xmljGetNamedItemNS (env, self, uri, localName);
+ if (attr == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ else
+ {
+ xmlUnlinkNode ((xmlNodePtr) attr);
+ return xmljGetNodeInstance (env, (xmlNodePtr) attr);
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/* -- GnomeNode -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getNodeName (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, node->name);
+}
+
+xmlChar *
+xmljGetNodeValue (xmlNodePtr node)
+{
+ /* If not character data, return null */
+ switch (node->type)
+ {
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_COMMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ return xmlNodeGetContent (node);
+ default:
+ return NULL;
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getNodeValue (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+ xmlChar *text;
+ jstring ret;
+
+ node = xmljGetNodeID (env, self);
+ text = xmljGetNodeValue (node);
+ ret = xmljNewString (env, (const xmlChar *) text);
+ if (text != NULL)
+ {
+ xmlFree (text);
+ }
+ return ret;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_setNodeValue (JNIEnv * env,
+ jobject self,
+ jstring nodeValue)
+{
+ xmlNodePtr node;
+ const xmlChar *s_nodeValue;
+
+ node = xmljGetNodeID (env, self);
+
+ /* If not character data, return */
+ if (node->type != XML_TEXT_NODE &&
+ node->type != XML_CDATA_SECTION_NODE && node->type != XML_COMMENT_NODE)
+ return;
+
+ s_nodeValue = xmljGetStringChars (env, nodeValue);
+ xmlNodeSetContent (node, s_nodeValue);
+}
+
+JNIEXPORT jshort JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getNodeType (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ switch (node->type)
+ {
+ case XML_DTD_NODE:
+ return XML_DOCUMENT_TYPE_NODE;
+ case XML_ATTRIBUTE_DECL:
+ return XML_ATTRIBUTE_NODE;
+ case XML_ENTITY_DECL:
+ return XML_ENTITY_NODE;
+ default:
+ return node->type;
+ }
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getParentNode (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, node->parent);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getFirstChild (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, node->children);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getLastChild (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, node->last);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getPreviousSibling (JNIEnv * env,
+ jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, node->prev);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getNextSibling (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, node->next);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getOwnerDocument (JNIEnv * env,
+ jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return xmljGetNodeInstance (env, (xmlNodePtr) node->doc);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljInsertBefore (JNIEnv * env,
+ jobject self,
+ jobject newChild,
+ jobject refChild)
+{
+ xmlNodePtr node;
+ xmlNodePtr newChildNode;
+ xmlNodePtr refChildNode;
+
+ node = xmljGetNodeID (env, self);
+ newChildNode = xmljGetNodeID (env, newChild);
+ refChildNode = xmljGetNodeID (env, refChild);
+
+ /* Is refChildNode a child of this node? */
+ if (refChildNode == NULL ||
+ refChildNode->parent == NULL ||
+ refChildNode->parent != node)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ /* Check new child */
+ xmljValidateChildNode (env, node, newChildNode);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+
+ newChildNode = xmlAddPrevSibling (refChildNode, newChildNode);
+ return xmljGetNodeInstance (env, newChildNode);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljReplaceChild (JNIEnv * env,
+ jobject self,
+ jobject newChild,
+ jobject oldChild)
+{
+ xmlNodePtr node;
+ xmlNodePtr newChildNode;
+ xmlNodePtr oldChildNode;
+
+ node = xmljGetNodeID (env, self);
+ newChildNode = xmljGetNodeID (env, newChild);
+ oldChildNode = xmljGetNodeID (env, oldChild);
+
+ /* Is oldChildNode a child of this node? */
+ if (oldChildNode == NULL ||
+ oldChildNode->parent == NULL ||
+ oldChildNode->parent != node)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ /* Check new child */
+ xmljValidateChildNode (env, node, newChildNode);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+
+ newChildNode = xmlReplaceNode (oldChildNode, newChildNode);
+ return xmljGetNodeInstance (env, newChildNode);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljRemoveChild (JNIEnv * env,
+ jobject self,
+ jobject oldChild)
+{
+ xmlNodePtr node;
+ xmlNodePtr oldChildNode;
+
+ node = xmljGetNodeID (env, self);
+ oldChildNode = xmljGetNodeID (env, oldChild);
+
+ if (oldChildNode == NULL ||
+ oldChildNode->parent == NULL ||
+ oldChildNode->parent != node)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ xmlUnlinkNode (oldChildNode);
+ return oldChild;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljAppendChild (JNIEnv * env,
+ jobject self,
+ jobject newChild)
+{
+ xmlNodePtr node;
+ xmlNodePtr newChildNode;
+
+ node = xmljGetNodeID (env, self);
+ newChildNode = xmljGetNodeID (env, newChild);
+
+ /* Check new child */
+ xmljValidateChildNode (env, node, newChildNode);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+
+ newChildNode = xmlAddChild (node, newChildNode);
+ return xmljGetNodeInstance (env, newChildNode);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_hasChildNodes (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return (node->children != NULL);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljCloneNode (JNIEnv * env,
+ jobject self, jboolean deep)
+{
+ xmlNodePtr node;
+ xmlNodePtr clone;
+
+ node = xmljGetNodeID (env, self);
+ clone = xmlCopyNode (node, deep);
+ clone->parent = NULL;
+ clone->doc = node->doc;
+ return xmljGetNodeInstance (env, clone);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_normalize (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ xmljNormalizeNode (node);
+}
+
+void
+xmljNormalizeNode (xmlNodePtr node)
+{
+ xmlNodePtr cur;
+ xmlNodePtr last = NULL;
+
+ cur = node->children;
+ while (cur != NULL)
+ {
+ switch (cur->type)
+ {
+ case XML_CDATA_SECTION_NODE:
+ case XML_TEXT_NODE:
+ if (xmlIsBlankNode (cur))
+ {
+ xmlNodePtr next = cur->next;
+ xmlUnlinkNode (cur);
+ xmlFreeNode (cur);
+ cur = next;
+ continue;
+ }
+ if (last != NULL)
+ {
+ last = xmlTextMerge (last, cur);
+ xmlUnlinkNode (cur);
+ xmlFreeNode (cur);
+ cur = last;
+ }
+ else
+ {
+ last = cur;
+ }
+ break;
+ default:
+ last = NULL;
+ xmljNormalizeNode (cur);
+ }
+ cur = cur->next;
+ }
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getNamespaceURI (JNIEnv * env,
+ jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ if (node->type != XML_ELEMENT_NODE &&
+ node->type != XML_ATTRIBUTE_NODE)
+ {
+ return NULL;
+ }
+ if (node->ns == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, node->ns->href);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getPrefix (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ if (node->type != XML_ELEMENT_NODE &&
+ node->type != XML_ATTRIBUTE_NODE)
+ {
+ return NULL;
+ }
+ if (node->ns == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, node->ns->prefix);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_setPrefix (JNIEnv * env,
+ jobject self, jstring prefix)
+{
+ xmlNodePtr node;
+ const xmlChar *s_prefix;
+
+ s_prefix = xmljGetStringChars (env, prefix);
+ if (xmlValidateName (s_prefix, 0))
+ {
+ xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
+ }
+ node = xmljGetNodeID (env, self);
+ if (node->type != XML_ELEMENT_NODE &&
+ node->type != XML_ATTRIBUTE_NODE)
+ {
+ xmljThrowDOMException (env, 3, NULL); /* HIERARCHY_REQUEST_ERR */
+ return;
+ }
+ if (node->ns == NULL)
+ {
+ xmljThrowDOMException (env, 14, NULL); /* NAMESPACE_ERR */
+ return;
+ }
+ node->ns->prefix = s_prefix;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getLocalName (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+ int *len;
+ jstring ret;
+
+ node = xmljGetNodeID (env, self);
+ if (node->name == NULL)
+ {
+ return NULL;
+ }
+ len = (int *) malloc (sizeof (int));
+ if (xmlSplitQName3 (node->name, len) != NULL)
+ {
+ ret = xmljNewString (env, node->name + (*len));
+ }
+ else
+ {
+ ret = xmljNewString (env, node->name);
+ }
+ free (len);
+ return ret;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_hasAttributes (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+
+ node = xmljGetNodeID (env, self);
+ return (node->properties != NULL);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_getBaseURI (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+ xmlChar *baseURI;
+ jstring ret;
+
+ node = xmljGetNodeID (env, self);
+ baseURI = xmlNodeGetBase (node->doc, node);
+ ret = xmljNewString (env, (const xmlChar *) baseURI);
+ if (baseURI != NULL)
+ {
+ xmlFree (baseURI);
+ }
+ return ret;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_lookupPrefix (JNIEnv * env, jobject self,
+ jstring namespaceURI)
+{
+ xmlNodePtr node;
+ xmlNsPtr ns;
+ xmlDocPtr doc;
+ const xmlChar *s_uri;
+
+ node = xmljGetNodeID (env, self);
+ doc = node->doc;
+ /* If this is a document node, search from the root element */
+ if (node->type == XML_DOCUMENT_NODE)
+ {
+ doc = (xmlDocPtr) node;
+ node = xmlDocGetRootElement (doc);
+ }
+ s_uri = xmljGetStringChars (env, namespaceURI);
+ ns = xmlSearchNsByHref (doc, node, s_uri);
+ xmlFree ((xmlChar *) s_uri);
+ if (ns == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, ns->prefix);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_isDefaultNamespace (JNIEnv * env,
+ jobject self,
+ jstring namespaceURI)
+{
+ xmlNodePtr node;
+ xmlNsPtr ns;
+ const xmlChar *s_uri;
+
+ node = xmljGetNodeID (env, self);
+ s_uri = xmljGetStringChars (env, namespaceURI);
+ ns = xmlSearchNsByHref (node->doc, node, s_uri);
+ xmlFree ((xmlChar *) s_uri);
+ if (ns == NULL)
+ {
+ return 0;
+ }
+ return (ns->prefix == NULL || xmlStrlen (ns->prefix) == 0);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_lookupNamespaceURI (JNIEnv * env,
+ jobject self,
+ jstring prefix)
+{
+ xmlNodePtr node;
+ xmlDocPtr doc;
+ xmlNsPtr ns;
+ const xmlChar *s_prefix;
+
+ node = xmljGetNodeID (env, self);
+ doc = node->doc;
+ /* If this is a document node, search from the root element */
+ if (node->type == XML_DOCUMENT_NODE)
+ {
+ doc = (xmlDocPtr) node;
+ node = xmlDocGetRootElement (doc);
+ }
+ s_prefix = xmljGetStringChars (env, prefix);
+ ns = xmlSearchNs (doc, node, s_prefix);
+ xmlFree ((xmlChar *) s_prefix);
+ if (ns == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, ns->href);
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_xmljCompareTo (JNIEnv * env,
+ jobject self,
+ jobject other)
+{
+ xmlNodePtr n1, n2, x;
+ int d1, d2, delta, c;
+
+ n1 = xmljGetNodeID (env, self);
+ n2 = xmljGetNodeID (env, other);
+ if (n1->doc != n2->doc)
+ {
+ return 0;
+ }
+ if (n1->type == XML_ATTRIBUTE_NODE || n2->type == XML_ATTRIBUTE_NODE)
+ {
+ return 0;
+ }
+ d1 = 0;
+ for (x = n1->parent; x && x->type != XML_DOCUMENT_NODE; x = x->parent)
+ {
+ d1++;
+ }
+ d2 = 0;
+ for (x = n2->parent; x && x->type != XML_DOCUMENT_NODE; x = x->parent)
+ {
+ d2++;
+ }
+ delta = d1 - d2;
+ while (d1 > d2)
+ {
+ n1 = n1->parent;
+ d1--;
+ }
+ while (d2 > d1)
+ {
+ n2 = n2->parent;
+ d2--;
+ }
+ c = xmljCompare (n1, n2);
+ return (c != 0) ? c : delta;
+}
+
+/* Compare at same level */
+int
+xmljCompare (xmlNodePtr n1, xmlNodePtr n2)
+{
+ int c, i1, i2;
+
+ if (n1->parent == NULL || n1->type == XML_DOCUMENT_NODE ||
+ n2->parent == NULL || n2->type == XML_DOCUMENT_NODE ||
+ n1 == n2)
+ {
+ return 0;
+ }
+ c = xmljCompare (n1->parent, n2->parent);
+ if (c != 0)
+ {
+ return c;
+ }
+ i1 = 0;
+ for (n1 = n1->prev; n1; n1 = n1->prev)
+ {
+ i1++;
+ }
+ i2 = 0;
+ for (n2 = n2->prev; n2; n2 = n2->prev)
+ {
+ i2++;
+ }
+ return i1 - i2;
+}
+
+int
+xmljIsEqualNodeList (xmlNodePtr node1, xmlNodePtr node2)
+{
+ while (node1 != NULL)
+ {
+ if (!xmljIsEqualNode (node1, node2))
+ {
+ return 0;
+ }
+ node1 = node1->next;
+ node2 = node2->next;
+ }
+ return 1;
+}
+
+int
+xmljIsEqualNode (xmlNodePtr node1, xmlNodePtr node2)
+{
+ const xmlChar *val1;
+ const xmlChar *val2;
+
+ if (node1 == node2)
+ {
+ return 1;
+ }
+ if (node1 == NULL || node2 == NULL)
+ {
+ return 0;
+ }
+ /* Check node type */
+ if (node1->type != node2->type)
+ {
+ return 0;
+ }
+ /* Check node name */
+ if (!xmlStrEqual (node1->name, node2->name))
+ {
+ return 0;
+ }
+ /* Check node namespace */
+ if (node1->type == XML_ELEMENT_NODE ||
+ node1->type == XML_ATTRIBUTE_NODE)
+ {
+ xmlNsPtr ns1, ns2;
+
+ ns1 = node1->ns;
+ if (ns1 != NULL)
+ {
+ ns2 = node2->ns;
+ if (ns2 == NULL)
+ {
+ return 0;
+ }
+ val1 = ns1->href;
+ val2 = ns2->href;
+ if (!xmlStrEqual (val1, val2))
+ {
+ return 0;
+ }
+ }
+ }
+ /* Check node value */
+ val1 = xmljGetNodeValue (node1);
+ val2 = xmljGetNodeValue (node2);
+ if (!xmlStrEqual (val1, val2))
+ {
+ return 0;
+ }
+ /* Check attributes */
+ if (node1->type == XML_ELEMENT_NODE &&
+ !xmljIsEqualNodeList ((xmlNodePtr) node1->properties,
+ (xmlNodePtr) node2->properties))
+ {
+ return 0;
+ }
+ /* Check doctype */
+ if (node1->type == XML_DOCUMENT_NODE)
+ {
+ xmlDocPtr doc1 = (xmlDocPtr) node1;
+ xmlDocPtr doc2 = (xmlDocPtr) node2;
+
+ if (!xmljIsEqualNode ((xmlNodePtr) doc1->intSubset,
+ (xmlNodePtr) doc2->intSubset) ||
+ !xmljIsEqualNode ((xmlNodePtr) doc1->extSubset,
+ (xmlNodePtr) doc2->extSubset))
+ {
+ return 0;
+ }
+ }
+ /* Check child nodes */
+ if (!xmljIsEqualNodeList (node1->children, node2->children))
+ {
+ return 0;
+ }
+ return 1;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNode_isEqualNode (JNIEnv * env,
+ jobject self,
+ jobject arg)
+{
+ xmlNodePtr node1;
+ xmlNodePtr node2;
+
+ node1 = xmljGetNodeID (env, self);
+ node2 = xmljGetNodeID (env, arg);
+ return xmljIsEqualNode (node1, node2);
+}
+
+/* -- GnomeNodeList -- */
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNodeList_item (JNIEnv * env,
+ jobject self, jint index)
+{
+ xmlNodePtr node;
+ jint count;
+
+ node = xmljGetNodeID (env, self);
+ node = node->children;
+ count = 0;
+ for (count = 0; node != NULL && count < index; count++)
+ {
+ node = node->next;
+ }
+ return xmljGetNodeInstance (env, node);
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNodeList_getLength (JNIEnv * env, jobject self)
+{
+ xmlNodePtr node;
+ jint count;
+
+ node = xmljGetNodeID (env, self);
+ count = 0;
+ node = node->children;
+ while (node != NULL)
+ {
+ count++;
+ node = node->next;
+ }
+ return count;
+}
+
+/* -- GnomeNotation -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNotation_getPublicId (JNIEnv * env,
+ jobject self)
+{
+ xmlNotationPtr notation;
+
+ notation = (xmlNotationPtr) xmljGetNodeID (env, self);
+ if (notation->PublicID == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, notation->PublicID);
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeNotation_getSystemId (JNIEnv * env,
+ jobject self)
+{
+ xmlNotationPtr notation;
+
+ notation = (xmlNotationPtr) xmljGetNodeID (env, self);
+ if (notation->SystemID == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, notation->SystemID);
+}
+
+/* -- GnomeProcessingInstruction -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeProcessingInstruction_getData (JNIEnv * env,
+ jobject self)
+{
+ xmlNodePtr node;
+ xmlChar *text;
+ jstring ret;
+
+ node = xmljGetNodeID (env, self);
+ text = xmlNodeGetContent (node);
+ ret = xmljNewString (env, (const xmlChar *) text);
+ if (text != NULL)
+ {
+ xmlFree (text);
+ }
+ return ret;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeProcessingInstruction_setData (JNIEnv * env,
+ jobject self,
+ jstring data)
+{
+ xmlNodePtr node;
+ const xmlChar *s_data;
+
+ node = xmljGetNodeID (env, self);
+ s_data = xmljGetStringChars (env, data);
+ xmlNodeSetContent (node, s_data);
+}
+
+/* -- GnomeTypeInfo -- */
+
+xmlDtdPtr xmljGetDtd (xmlDocPtr doc)
+{
+ xmlNodePtr ctx;
+
+ for (ctx = doc->children; ctx; ctx = ctx->next)
+ {
+ if (ctx->type == XML_DOCUMENT_TYPE_NODE)
+ {
+ return (xmlDtdPtr) ctx;
+ }
+ }
+ return NULL;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeTypeInfo_getTypeName (JNIEnv *env, jobject self)
+{
+ xmlNodePtr node;
+ xmlDtdPtr dtd;
+ xmlAttributePtr attribute;
+
+ node = xmljGetNodeID (env, self);
+ dtd = xmljGetDtd (node->doc);
+ if (dtd)
+ {
+ switch (node->type)
+ {
+ case XML_ATTRIBUTE_NODE:
+ attribute = xmlGetDtdAttrDesc (dtd, node->parent->name, node->name);
+ if (attribute)
+ {
+ switch (attribute->type)
+ {
+ case XML_ATTRIBUTE_CDATA:
+ return xmljNewString (env, BAD_CAST "CDATA");
+ case XML_ATTRIBUTE_ID:
+ return xmljNewString (env, BAD_CAST "ID");
+ case XML_ATTRIBUTE_IDREF:
+ return xmljNewString (env, BAD_CAST "IDREF");
+ case XML_ATTRIBUTE_IDREFS:
+ return xmljNewString (env, BAD_CAST "IDREFS");
+ case XML_ATTRIBUTE_ENTITY:
+ return xmljNewString (env, BAD_CAST "ENTITY");
+ case XML_ATTRIBUTE_ENTITIES:
+ return xmljNewString (env, BAD_CAST "ENTITIES");
+ case XML_ATTRIBUTE_NMTOKEN:
+ return xmljNewString (env, BAD_CAST "NMTOKEN");
+ case XML_ATTRIBUTE_NMTOKENS:
+ return xmljNewString (env, BAD_CAST "NMTOKENS");
+ default:
+ return NULL;
+ }
+ }
+ return NULL;
+ default:
+ return NULL;
+ }
+ }
+ /* TODO when XML Schema support is available */
+ return NULL;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeTypeInfo_getTypeNamespace (JNIEnv *env,
+ jobject self)
+{
+ xmlNodePtr node;
+ xmlDtdPtr dtd;
+ xmlAttributePtr attribute;
+
+ node = xmljGetNodeID (env, self);
+ dtd = xmljGetDtd (node->doc);
+ if (dtd)
+ {
+ switch (node->type)
+ {
+ case XML_ATTRIBUTE_NODE:
+ attribute = xmlGetDtdAttrDesc (dtd, node->parent->name, node->name);
+ if (attribute)
+ {
+ return xmljNewString (env,
+ BAD_CAST "http://www.w3.org/TR/REC-xml");
+ }
+ return NULL;
+ default:
+ return NULL;
+ }
+ }
+ /* TODO when XML Schema support is available */
+ return NULL;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeTypeInfo_isDerivedFrom (JNIEnv *env
+ __attribute__ ((__unused__)),
+ jobject self
+ __attribute__ ((__unused__)),
+ jstring typeNS
+ __attribute__ ((__unused__)),
+ jstring typeName
+ __attribute__ ((__unused__)),
+ jint method
+ __attribute__ ((__unused__)))
+{
+ /* TODO when XML Schema support is available */
+ return 0;
+}
+
+/* -- Utility -- */
+
+/*
+ * Create GnomeDocument object from the given xmlDocPtr
+ */
+jobject
+xmljCreateDocument (JNIEnv * env, jobject self, xmlDocPtr doc)
+{
+ jclass cls;
+ jfieldID field;
+ jobject ret;
+
+ if (!doc)
+ {
+ return NULL;
+ }
+
+ /* Get document object */
+ ret = xmljGetNodeInstance (env, (xmlNodePtr) doc);
+
+ /* Set DOM implementation field */
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeDocument");
+ field = (*env)->GetFieldID (env, cls, "dom",
+ "Lorg/w3c/dom/DOMImplementation;");
+ (*env)->SetObjectField (env, ret, field, self);
+ return ret;
+}
+
+xmlAttrPtr
+xmljGetNamedItem (JNIEnv * env, jobject self, jstring name)
+{
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ const xmlChar *s_name;
+
+ s_name = xmljGetStringChars (env, name);
+
+ node = xmljGetNodeID (env, self);
+ attr = node->properties;
+ while (attr != NULL)
+ {
+ if (xmljMatch (s_name, (xmlNodePtr) attr))
+ break;
+ attr = attr->next;
+ }
+ xmlFree ((xmlChar *) s_name);
+
+ return attr;
+}
+
+xmlAttrPtr
+xmljGetNamedItemNS (JNIEnv * env, jobject self, jstring uri, jstring localName)
+{
+ xmlNodePtr node;
+ xmlAttrPtr attr;
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+
+ s_uri = xmljGetStringChars (env, uri);
+ s_localName = xmljGetStringChars (env, localName);
+
+ node = xmljGetNodeID (env, self);
+ attr = node->properties;
+ while (attr != NULL)
+ {
+ if (xmljMatchNS (s_uri, s_localName, (xmlNodePtr) attr))
+ break;
+ attr = attr->next;
+ }
+ xmlFree ((xmlChar *) s_uri);
+ xmlFree ((xmlChar *) s_localName);
+
+ return attr;
+}
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_dom.h b/libjava/classpath/native/jni/xmlj/xmlj_dom.h
new file mode 100644
index 00000000000..d4a1dff420c
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_dom.h
@@ -0,0 +1,70 @@
+/* xmlj_dom.h -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_DOM_H
+#define XMLJ_DOM_H
+
+#include "gnu_xml_libxmlj_dom_GnomeAttr.h"
+#include "gnu_xml_libxmlj_dom_GnomeDocument.h"
+#include "gnu_xml_libxmlj_dom_GnomeDocumentBuilder.h"
+#include "gnu_xml_libxmlj_dom_GnomeDocumentType.h"
+#include "gnu_xml_libxmlj_dom_GnomeElement.h"
+#include "gnu_xml_libxmlj_dom_GnomeEntity.h"
+#include "gnu_xml_libxmlj_dom_GnomeNamedNodeMap.h"
+#include "gnu_xml_libxmlj_dom_GnomeNode.h"
+#include "gnu_xml_libxmlj_dom_GnomeNodeList.h"
+#include "gnu_xml_libxmlj_dom_GnomeNotation.h"
+#include "gnu_xml_libxmlj_dom_GnomeProcessingInstruction.h"
+#include "gnu_xml_libxmlj_dom_GnomeTypeInfo.h"
+
+#include <libxml/parser.h>
+#include <libxml/valid.h>
+
+void xmljValidateChildNode (JNIEnv *env, xmlNodePtr parent, xmlNodePtr child);
+int xmljIsEqualNode (xmlNodePtr node1, xmlNodePtr node2);
+int xmljIsEqualNodeList (xmlNodePtr node1, xmlNodePtr node2);
+void xmljNormalizeNode (xmlNodePtr node);
+xmlDtdPtr xmljGetDtd (xmlDocPtr doc);
+int xmljCompare (xmlNodePtr n1, xmlNodePtr n2);
+
+/* Utility */
+jobject xmljCreateDocument (JNIEnv * env, jobject self, xmlDocPtr doc);
+xmlAttrPtr xmljGetNamedItem (JNIEnv * env, jobject self, jstring name);
+xmlAttrPtr xmljGetNamedItemNS (JNIEnv * env, jobject self, jstring uri,
+ jstring localName);
+
+#endif /* !defined XMLJ_DOM_H */
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_error.c b/libjava/classpath/native/jni/xmlj/xmlj_error.c
new file mode 100644
index 00000000000..5dd90552c35
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_error.c
@@ -0,0 +1,169 @@
+/* xmlj_error.c -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_error.h"
+#include "xmlj_io.h"
+#include "xmlj_util.h"
+
+void
+xmljXsltErrorFunc (void *ctx, const char *msg, ...)
+{
+ if (NULL != ctx)
+ {
+ SAXParseContext *sax = ((SAXParseContext *) ctx);
+
+ if (NULL != sax)
+ {
+ JNIEnv *env = sax->env;
+
+ if (!(*env)->ExceptionOccurred (env))
+ {
+ jobject target = sax->obj;
+ xmlChar *x_msg;
+ jstring j_msg;
+ va_list args;
+
+ if (sax->error == NULL)
+ {
+ sax->error =
+ xmljGetMethodID (env,
+ target,
+ "error",
+ "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
+ if (sax->error == NULL)
+ {
+ return;
+ }
+ }
+
+ va_start (args, msg);
+ x_msg = (msg == NULL) ? NULL : xmlCharStrdup (msg);
+ va_end (args);
+ j_msg = xmljNewString (env, x_msg);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->error,
+ j_msg,
+ -1,
+ -1,
+ NULL,
+ NULL);
+ }
+ }
+ }
+ else
+ {
+ va_list va;
+ va_start (va, msg);
+ fprintf (stderr, "libxslt error: ");
+ vfprintf (stderr, msg, va);
+ fflush (stderr);
+ va_end (va);
+ }
+}
+
+void
+xmljThrowException (JNIEnv *env,
+ const char *classname,
+ const char *message)
+{
+ jclass cls;
+ jmethodID method;
+ jthrowable ex;
+ jstring jmsg;
+
+ /*fprintf(stderr, "Throwing exception %s %s\n", classname, message);*/
+ cls = (*env)->FindClass (env, classname);
+ if (cls == NULL)
+ {
+ fprintf (stderr, "Can't find class %s\n", classname);
+ fflush (stderr);
+ return;
+ }
+ method = (*env)->GetMethodID (env, cls, "<init>", "(Ljava/lang/String;)V");
+ if (method == NULL)
+ {
+ fprintf (stderr, "Can't find method %s.<init>\n", classname);
+ fflush (stderr);
+ return;
+ }
+ jmsg = (message == NULL) ? NULL : (*env)->NewStringUTF (env, message);
+ ex = (jthrowable) (*env)->NewObject (env, cls, method, jmsg);
+ if (ex == NULL)
+ {
+ fprintf (stderr, "Can't instantiate new %s\n", classname);
+ fflush (stderr);
+ return;
+ }
+ (*env)->Throw (env, ex);
+}
+
+void
+xmljThrowDOMException (JNIEnv *env,
+ int code,
+ const char *message)
+{
+ jclass cls;
+ jmethodID method;
+ jthrowable ex;
+ jstring jmsg;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeDOMException");
+ if (cls == NULL)
+ {
+ fprintf (stderr, "Can't find DOMException class!\n");
+ fflush (stderr);
+ return;
+ }
+ method = (*env)->GetMethodID (env, cls, "<init>", "(SLjava/lang/String;)V");
+ if (method == NULL)
+ {
+ fprintf (stderr, "Can't find DOMException constructor!\n");
+ fflush (stderr);
+ return;
+ }
+ jmsg = (message == NULL) ? NULL : (*env)->NewStringUTF (env, message);
+ ex = (jthrowable) (*env)->NewObject (env, cls, method, code, jmsg);
+ (*env)->Throw (env, ex);
+}
+
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_error.h b/libjava/classpath/native/jni/xmlj/xmlj_error.h
new file mode 100644
index 00000000000..a0c9fcc8042
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_error.h
@@ -0,0 +1,85 @@
+/* xmlj_error.h -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_ERROR_H
+#define XMLJ_ERROR_H
+
+#include <jni.h>
+#include <libxml/xmlIO.h>
+
+/*
+typedef struct SaxErrorContext_
+{
+ JNIEnv * env;
+ jobject saxErrorAdapter;
+ jmethodID saxCommentMethodID;
+ jmethodID saxWarningMethodID;
+ jmethodID saxErrorMethodID;
+ jmethodID saxFatalErrorMethodID;
+ jclass sourceLocatorClass;
+ jmethodID sourceLocatorConstructor;
+ xmlSAXLocatorPtr locator;
+ jstring publicId;
+ jstring systemId;
+ const char *publicIdCstr;
+ const char *systemIdCstr;
+ jmethodID resolveURIMethodID;
+ jmethodID resolveURIAndOpenMethodID;
+ jmethodID getInputStreamMethodID;
+ jmethodID xsltGenericErrorMethodID;
+ jobject theTransformerException;
+ jmethodID getNativeHandleMethodID;
+} SaxErrorContext;
+
+SaxErrorContext * xmljCreateSaxErrorContext (JNIEnv * env,
+ jobject errorContext,
+ jstring systemId,
+ jstring publicId);
+
+void xmljFreeSaxErrorContext (SaxErrorContext * errorContext);
+
+void xmljInitErrorHandling (xmlSAXHandler * saxHandler);
+*/
+
+void xmljXsltErrorFunc (void *ctx, const char *msg, ...);
+
+void xmljThrowException (JNIEnv *, const char *classname, const char *message);
+
+void xmljThrowDOMException (JNIEnv *, int code, const char *message);
+
+#endif /* !defined XMLJ_ERROR_H */
+
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_io.c b/libjava/classpath/native/jni/xmlj/xmlj_io.c
new file mode 100644
index 00000000000..aa2964dc312
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_io.c
@@ -0,0 +1,799 @@
+/* xmlj_io.c -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_io.h"
+#include "xmlj_error.h"
+#include "xmlj_node.h"
+#include "xmlj_sax.h"
+#include "xmlj_util.h"
+
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <libxml/xmlIO.h>
+#include <libxml/parserInternals.h>
+
+#include <pthread.h>
+
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define UNSIGN(a) (((a) < 0) ? ((a) + 0x100) : (a))
+
+#define DETECT_BUFFER_SIZE 50
+
+typedef struct _OutputStreamContext
+{
+
+ JNIEnv *env;
+ jobject outputStream;
+ jmethodID outputStreamWriteFunc;
+ jmethodID outputStreamCloseFunc;
+
+}
+OutputStreamContext;
+
+typedef struct _InputStreamContext
+{
+
+ JNIEnv *env;
+ jobject inputStream;
+ jmethodID inputStreamReadFunc;
+ jmethodID inputStreamCloseFunc;
+ jobject bufferByteArray;
+ jint bufferLength;
+
+}
+InputStreamContext;
+
+InputStreamContext *xmljNewInputStreamContext (JNIEnv * env,
+ jobject inputStream);
+
+void xmljFreeInputStreamContext (InputStreamContext * inContext);
+
+int xmljInputReadCallback (void *context, char *buffer, int len);
+
+int xmljInputCloseCallback (void *context);
+
+int xmljOutputWriteCallback (void *context, const char *buffer, int len);
+
+int xmljOutputCloseCallback (void *context);
+
+OutputStreamContext *xmljNewOutputStreamContext (JNIEnv * env,
+ jobject outputStream);
+
+void
+xmljFreeOutputStreamContext (OutputStreamContext * outContext);
+
+xmlCharEncoding
+xmljDetectCharEncoding (JNIEnv * env, jbyteArray buffer);
+
+int
+xmljOutputWriteCallback (void *context, const char *buffer, int len)
+{
+ OutputStreamContext *outContext;
+ JNIEnv *env;
+ jbyteArray byteArray;
+
+ outContext = (OutputStreamContext *) context;
+ env = outContext->env;
+ byteArray = (*env)->NewByteArray (env, len);
+
+ if (0 != byteArray)
+ {
+ (*env)->SetByteArrayRegion (env, byteArray, 0, len, (jbyte *) buffer);
+
+ (*env)->CallVoidMethod (env,
+ outContext->outputStream,
+ outContext->outputStreamWriteFunc, byteArray);
+
+ (*env)->DeleteLocalRef (env, byteArray);
+
+ return (*env)->ExceptionOccurred (env) ? -1 : len;
+ }
+ else
+ {
+ /* Out of memory, signal error */
+ return -1;
+ }
+}
+
+int
+xmljOutputCloseCallback (void *context)
+{
+ OutputStreamContext *outContext;
+ JNIEnv *env;
+
+ outContext = (OutputStreamContext *) context;
+ env = outContext->env;
+ (*env)->CallVoidMethod (env,
+ outContext->outputStream,
+ outContext->outputStreamCloseFunc);
+
+ return (*env)->ExceptionOccurred (env) ? -1 : 0;
+}
+
+int
+xmljInputReadCallback (void *context, char *buffer, int len)
+{
+ InputStreamContext *inContext;
+ JNIEnv *env;
+ jint nread;
+ int offset;
+
+ inContext = (InputStreamContext *) context;
+ env = inContext->env;
+ nread = 0;
+
+ for (offset = 0; offset < len && nread >= 0;)
+ {
+ nread = (*env)->CallIntMethod (env,
+ inContext->inputStream,
+ inContext->inputStreamReadFunc,
+ inContext->bufferByteArray,
+ 0, MIN (len - offset,
+ inContext->bufferLength));
+
+ if (nread > 0)
+ {
+ (*env)->GetByteArrayRegion (env,
+ inContext->bufferByteArray,
+ 0, nread, ((jbyte *) buffer) + offset);
+
+ offset += nread;
+ }
+ }
+
+ return (*env)->ExceptionOccurred (env) ? -1 : offset;
+}
+
+int
+xmljInputCloseCallback (void *context)
+{
+ InputStreamContext *inContext;
+ JNIEnv *env;
+
+ inContext = (InputStreamContext *) context;
+ env = inContext->env;
+ (*env)->CallVoidMethod (env, inContext->inputStream,
+ inContext->inputStreamCloseFunc);
+
+ return (*env)->ExceptionOccurred (env) ? -1 : 0;
+}
+
+InputStreamContext *
+xmljNewInputStreamContext (JNIEnv * env, jobject inputStream)
+{
+ jclass inputStreamClass;
+ InputStreamContext *result;
+
+ inputStreamClass = (*env)->FindClass (env, "java/io/InputStream");
+ if (inputStreamClass == NULL)
+ {
+ return NULL;
+ }
+ result = (InputStreamContext *) malloc (sizeof (InputStreamContext));
+ if (result == NULL)
+ {
+ return NULL;
+ }
+
+ result->env = env;
+ result->inputStream = inputStream;
+ result->inputStreamReadFunc =
+ (*env)->GetMethodID (env, inputStreamClass, "read", "([BII)I");
+ result->inputStreamCloseFunc =
+ (*env)->GetMethodID (env, inputStreamClass, "close", "()V");
+ result->bufferLength = 4096;
+ result->bufferByteArray = (*env)->NewByteArray (env, result->bufferLength);
+ return result;
+}
+
+void
+xmljFreeInputStreamContext (InputStreamContext * inContext)
+{
+ JNIEnv *env;
+
+ env = inContext->env;
+ (*env)->DeleteLocalRef (env, inContext->bufferByteArray);
+ free (inContext);
+}
+
+OutputStreamContext *
+xmljNewOutputStreamContext (JNIEnv * env, jobject outputStream)
+{
+ jclass outputStreamClass;
+ OutputStreamContext *result;
+
+ outputStreamClass = (*env)->FindClass (env, "java/io/OutputStream");
+ if (outputStreamClass == NULL)
+ {
+ return NULL;
+ }
+ result = (OutputStreamContext *) malloc (sizeof (OutputStreamContext));
+ if (result == NULL)
+ {
+ return NULL;
+ }
+
+ result->env = env;
+ result->outputStream = outputStream;
+ result->outputStreamWriteFunc =
+ (*env)->GetMethodID (env, outputStreamClass, "write", "([B)V");
+ result->outputStreamCloseFunc =
+ (*env)->GetMethodID (env, outputStreamClass, "close", "()V");
+ return result;
+}
+
+
+void
+xmljFreeOutputStreamContext (OutputStreamContext * outContext)
+{
+ free (outContext);
+}
+
+SAXParseContext *
+xmljNewSAXParseContext (JNIEnv * env, jobject obj, xmlParserCtxtPtr ctx,
+ jstring publicId, jstring systemId)
+{
+ SAXParseContext *ret;
+
+ ret = (SAXParseContext *) malloc (sizeof (SAXParseContext));
+ ret->env = env;
+ ret->obj = obj;
+ ret->ctx = ctx;
+ ret->sax = ctx->sax;
+ ret->loc = NULL;
+ ret->publicId = publicId;
+ ret->systemId = systemId;
+
+ ret->startDTD = NULL;
+ ret->externalEntityDecl = NULL;
+ ret->internalEntityDecl = NULL;
+ ret->resolveEntity = NULL;
+ ret->notationDecl = NULL;
+ ret->attributeDecl = NULL;
+ ret->elementDecl = NULL;
+ ret->unparsedEntityDecl = NULL;
+ ret->setDocumentLocator = NULL;
+ ret->startDocument = NULL;
+ ret->endDocument = NULL;
+ ret->startElement = NULL;
+ ret->endElement = NULL;
+ ret->characters = NULL;
+ ret->ignorableWhitespace = NULL;
+ ret->processingInstruction = NULL;
+ ret->comment = NULL;
+ ret->cdataBlock = NULL;
+ ret->warning = NULL;
+ ret->error = NULL;
+ ret->fatalError = NULL;
+
+ ret->resolveURIAndOpen = NULL;
+ ret->stringClass = NULL;
+ return ret;
+}
+
+void
+xmljFreeSAXParseContext (SAXParseContext * saxCtx)
+{
+ free (saxCtx);
+}
+
+xmlCharEncoding
+xmljDetectCharEncoding (JNIEnv * env, jbyteArray buffer)
+{
+ xmlCharEncoding ret;
+ jint nread;
+
+ if (buffer == NULL)
+ {
+ return XML_CHAR_ENCODING_ERROR;
+ }
+ nread = (*env)->GetArrayLength (env, buffer);
+ if (nread >= 5)
+ {
+ jbyte nativeBuffer[DETECT_BUFFER_SIZE + 1];
+ unsigned char converted[DETECT_BUFFER_SIZE + 1];
+ int i;
+
+ memset (nativeBuffer, 0, DETECT_BUFFER_SIZE + 1);
+ (*env)->GetByteArrayRegion (env, buffer, 0, nread, nativeBuffer);
+ /* Convert from signed to unsigned */
+ for (i = 0; i < DETECT_BUFFER_SIZE + 1; i++)
+ {
+ converted[i] = UNSIGN (nativeBuffer[i]);
+ }
+ ret = xmlDetectCharEncoding (converted, nread);
+ }
+ else
+ {
+ ret = XML_CHAR_ENCODING_NONE;
+ }
+ return ret;
+}
+
+xmlParserCtxtPtr
+xmljNewParserContext (JNIEnv * env,
+ jobject inputStream,
+ jbyteArray detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean coalesce,
+ jboolean expandEntities,
+ jboolean loadEntities)
+{
+ InputStreamContext *inputContext;
+ xmlCharEncoding encoding;
+ xmlParserCtxtPtr ctx;
+ int options;
+
+ encoding = xmljDetectCharEncoding (env, detectBuffer);
+ if (encoding != XML_CHAR_ENCODING_ERROR)
+ {
+ inputContext = xmljNewInputStreamContext (env, inputStream);
+ if (NULL != inputContext)
+ {
+ /* NOTE: userdata must be NULL for DOM to work */
+ ctx = xmlCreateIOParserCtxt (NULL,
+ NULL,
+ xmljInputReadCallback,
+ xmljInputCloseCallback,
+ inputContext,
+ encoding);
+ if (NULL != ctx)
+ {
+ ctx->userData = ctx;
+
+ /* Set parsing options */
+ options = 0;
+ if (validate)
+ {
+ options |= XML_PARSE_DTDVALID;
+ }
+ if (coalesce)
+ {
+ options |= XML_PARSE_NOCDATA;
+ }
+ if (expandEntities)
+ {
+ options |= XML_PARSE_NOENT;
+ }
+ if (loadEntities)
+ {
+ options |= XML_PARSE_DTDLOAD;
+ }
+ if (xmlCtxtUseOptions (ctx, options))
+ {
+ xmljThrowException (env,
+ "java/lang/RuntimeException",
+ "Unable to set xmlParserCtxtPtr options");
+ }
+ if (base != NULL)
+ {
+ ctx->input->directory =
+ (*env)->GetStringUTFChars (env, base, 0);
+ }
+ return ctx;
+ }
+ xmljFreeInputStreamContext (inputContext);
+ }
+ }
+ return NULL;
+}
+
+void
+xmljFreeParserContext (xmlParserCtxtPtr ctx)
+{
+ InputStreamContext *inputStreamContext = NULL;
+
+ if (ctx->input != NULL && ctx->input->buf != NULL)
+ {
+ inputStreamContext
+ = (InputStreamContext *) ctx->input->buf->context;
+
+ }
+ xmlFreeParserCtxt (ctx);
+ if (inputStreamContext != NULL)
+ {
+ xmljFreeInputStreamContext (inputStreamContext);
+ }
+}
+
+xmlDocPtr
+xmljParseDocument (JNIEnv * env,
+ jobject self,
+ jobject in,
+ jbyteArray detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean coalesce,
+ jboolean expandEntities,
+ jboolean contentHandler,
+ jboolean dtdHandler,
+ jboolean entityResolver,
+ jboolean errorHandler,
+ jboolean declarationHandler,
+ jboolean lexicalHandler,
+ int mode)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *saxCtx;
+ xmlSAXHandlerPtr sax;
+
+ ctx = xmljNewParserContext (env, in, detectBuffer, publicId, systemId, base,
+ validate, coalesce, expandEntities,
+ entityResolver);
+ if (ctx != NULL)
+ {
+ saxCtx = xmljNewSAXParseContext (env, self, ctx, publicId, systemId);
+ if (saxCtx != NULL)
+ {
+ sax = xmljNewSAXHandler (contentHandler,
+ dtdHandler,
+ entityResolver,
+ errorHandler,
+ declarationHandler,
+ lexicalHandler);
+ if (sax != NULL)
+ {
+ return xmljParseDocument2 (env,
+ ctx,
+ saxCtx,
+ sax,
+ mode);
+ }
+ xmljFreeSAXParseContext (saxCtx);
+ }
+ xmljFreeParserContext (ctx);
+ }
+ if (!(*env)->ExceptionOccurred (env))
+ {
+ xmljThrowException (env, "java/io/IOException",
+ "Unable to create parser context");
+ }
+ return NULL;
+}
+
+xmlDocPtr
+xmljParseDocument2 (JNIEnv * env,
+ xmlParserCtxtPtr ctx,
+ SAXParseContext *saxCtx,
+ xmlSAXHandlerPtr sax,
+ int mode)
+{
+ xmlSAXHandlerPtr orig;
+ xmlDocPtr doc;
+ int ret;
+
+ ctx->_private = saxCtx;
+ ctx->userData = ctx;
+ orig = ctx->sax;
+ ctx->sax = sax;
+
+ xmljSetThreadContext (saxCtx);
+
+ ret = xmlParseDocument (ctx);
+ doc = ctx->myDoc;
+ if (ret || !doc)
+ {
+ const char *msg = ctx->lastError.message;
+ switch (mode)
+ {
+ case 0:
+ xmljSAXFatalError (ctx, msg);
+ break;
+ case 1:
+ xmljThrowDOMException (env, ret, msg);
+ break;
+ case 2:
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerException",
+ msg);
+ }
+ }
+
+ xmljClearThreadContext ();
+
+ ctx->sax = orig;
+ free(sax);
+ xmljFreeSAXParseContext (saxCtx);
+ xmljFreeParserContext (ctx);
+ xmljClearStringCache ();
+ return doc;
+}
+
+xmlParserInputPtr
+xmljNewParserInput (JNIEnv * env,
+ jobject inputStream,
+ jbyteArray detectBuffer,
+ xmlParserCtxtPtr parserContext)
+{
+ xmlParserInputPtr ret;
+ xmlParserInputBufferPtr input;
+ xmlCharEncoding encoding;
+
+ encoding = xmljDetectCharEncoding (env, detectBuffer);
+ if (encoding != XML_CHAR_ENCODING_ERROR)
+ {
+ input = xmljNewParserInputBuffer (env, inputStream, encoding);
+ if (input != NULL)
+ {
+ ret = xmlNewIOInputStream (parserContext, input, encoding);
+ return ret;
+ }
+ xmlFreeParserInputBuffer (input);
+ }
+ return NULL;
+}
+
+xmlParserInputBufferPtr
+xmljNewParserInputBuffer (JNIEnv * env,
+ jobject inputStream, xmlCharEncoding encoding)
+{
+ xmlParserInputBufferPtr ret;
+ InputStreamContext *inputContext;
+
+ inputContext = xmljNewInputStreamContext (env, inputStream);
+ if (NULL != inputContext)
+ {
+ ret = xmlParserInputBufferCreateIO (&xmljInputReadCallback,
+ &xmljInputCloseCallback,
+ inputContext, encoding);
+ if (ret != NULL)
+ return ret;
+ xmljFreeInputStreamContext (inputContext);
+ }
+ return NULL;
+}
+
+void
+xmljSaveFileToJavaOutputStream (JNIEnv * env, jobject outputStream,
+ xmlDocPtr tree,
+ const char *outputEncodingName)
+{
+ OutputStreamContext *outputContext =
+ xmljNewOutputStreamContext (env, outputStream);
+
+ xmlCharEncoding outputEncoding = xmlParseCharEncoding (outputEncodingName);
+
+ xmlOutputBufferPtr outputBuffer =
+ xmlOutputBufferCreateIO (xmljOutputWriteCallback,
+ xmljOutputCloseCallback,
+ outputContext,
+ xmlGetCharEncodingHandler (outputEncoding));
+
+ /* Write result to output stream */
+
+ xmlSaveFileTo (outputBuffer, tree, outputEncodingName);
+
+ xmljFreeOutputStreamContext (outputContext);
+}
+
+/*
+jobject
+xmljResolveURI (SaxErrorContext * saxErrorContext,
+ const char *URL, const char *ID)
+{
+ JNIEnv *env = saxErrorContext->env;
+
+ jstring hrefString = (*env)->NewStringUTF (env, URL);
+ jstring baseString = saxErrorContext->systemId;
+
+ jobject sourceWrapper = (*env)->CallObjectMethod (env,
+ saxErrorContext->
+ saxErrorAdapter,
+ saxErrorContext->
+ resolveURIMethodID,
+ hrefString,
+ baseString);
+ (*env)->DeleteLocalRef (env, hrefString);
+
+ if (NULL == sourceWrapper)
+ {
+ return NULL;
+ }
+ else
+ {
+ jobject sourceInputStream = (*env)->CallObjectMethod (env,
+ sourceWrapper,
+ saxErrorContext->
+ getInputStreamMethodID);
+
+ (*env)->DeleteLocalRef (env, sourceWrapper);
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ -* Report to ErrorAdapter here? *-
+ return NULL;
+ }
+
+ return sourceInputStream;
+ }
+}*/
+
+xmlDocPtr
+xmljResolveURIAndOpen (SAXParseContext *saxContext,
+ const char *URL,
+ const char *ID)
+{
+ jobject libxmlDocument;
+ xmlDocPtr doc;
+ JNIEnv *env = saxContext->env;
+
+ jstring hrefString = (*env)->NewStringUTF (env, URL);
+ jstring baseString = saxContext->systemId;
+
+ if (saxContext->resolveURIAndOpen == NULL)
+ {
+ jclass cls = (*env)->GetObjectClass (env, saxContext->obj);
+ saxContext->resolveURIAndOpen =
+ (*env)->GetMethodID (env, cls, "resolveURIAndOpen",
+ "Ljava/lang/String;Ljava/lang/String)Lgnu/xml/libxmlj/transform/LibxmlDocument;");
+ }
+ libxmlDocument =
+ (*env)->CallObjectMethod (env,
+ saxContext->obj,
+ saxContext->resolveURIAndOpen,
+ hrefString,
+ baseString);
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, libxmlDocument);
+
+ (*env)->DeleteLocalRef (env, libxmlDocument);
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* Report to ErrorAdapter here? */
+ return NULL;
+ }
+ else
+ {
+ return doc;
+ }
+}
+
+/*xmlParserInputPtr
+xmljLoadExternalEntity (const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt)
+{
+ SaxErrorContext *saxErrorContext = xmljGetThreadContext ();
+
+ JNIEnv *env = saxErrorContext->env;
+
+ jstring hrefString = (*env)->NewStringUTF (env, URL);
+ jstring baseString = saxErrorContext->systemId;
+
+ jobject sourceWrapper = (*env)->CallObjectMethod (env,
+ saxErrorContext->
+ saxErrorAdapter,
+ saxErrorContext->
+ resolveURIMethodID,
+ hrefString,
+ baseString);
+
+ (*env)->DeleteLocalRef (env, hrefString);
+
+ if (NULL == sourceWrapper)
+ {
+ return NULL;
+ }
+ else
+ {
+ InputStreamContext *inputContext;
+ xmlParserInputBufferPtr inputBuffer;
+ xmlParserInputPtr inputStream;
+
+ jobject sourceInputStream = (*env)->CallObjectMethod (env,
+ sourceWrapper,
+ saxErrorContext->
+ getInputStreamMethodID);
+
+ (*env)->DeleteLocalRef (env, sourceWrapper);
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ -* Report to ErrorAdapter *-
+ return NULL;
+ }
+
+ inputContext = xmljNewInputStreamContext (env, sourceInputStream);
+
+ inputBuffer
+ = xmlParserInputBufferCreateIO (xmljInputReadCallback,
+ xmljInputCloseCallback,
+ inputContext, XML_CHAR_ENCODING_NONE);
+
+ inputStream = xmlNewInputStream (ctxt);
+ if (inputStream == NULL)
+ {
+ return (NULL);
+ }
+
+ inputStream->filename = NULL;
+ inputStream->directory = NULL;
+ inputStream->buf = inputBuffer;
+
+ inputStream->base = inputStream->buf->buffer->content;
+ inputStream->cur = inputStream->buf->buffer->content;
+ inputStream->end = &inputStream->base[inputStream->buf->buffer->use];
+ if ((ctxt->directory == NULL) && (inputStream->directory != NULL))
+ ctxt->directory =
+ (char *) xmlStrdup ((const xmlChar *) inputStream->directory);
+ return (inputStream);
+ }
+}*/
+
+/* Key for the thread-specific buffer */
+static pthread_key_t thread_context_key;
+
+/* Once-only initialisation of the key */
+static pthread_once_t thread_context_once = PTHREAD_ONCE_INIT;
+
+static void
+thread_context_key_alloc (void);
+
+/* Allocate the key */
+static void
+thread_context_key_alloc ()
+{
+ pthread_key_create (&thread_context_key, NULL);
+}
+
+void
+xmljSetThreadContext (SAXParseContext * context)
+{
+ pthread_once (&thread_context_once, thread_context_key_alloc);
+ pthread_setspecific (thread_context_key, context);
+}
+
+void
+xmljClearThreadContext (void)
+{
+ pthread_setspecific (thread_context_key, NULL);
+}
+
+/* Return the thread-specific buffer */
+SAXParseContext *
+xmljGetThreadContext (void)
+{
+ return (SAXParseContext *) pthread_getspecific (thread_context_key);
+}
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_io.h b/libjava/classpath/native/jni/xmlj/xmlj_io.h
new file mode 100644
index 00000000000..871859aca51
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_io.h
@@ -0,0 +1,170 @@
+/* xmlj_io.h -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_IO_H
+#define XMLJ_IO_H
+
+#include <jni.h>
+#include <libxml/xmlIO.h>
+#include "xmlj_error.h"
+
+typedef struct _SAXParseContext
+{
+
+ JNIEnv *env; /* Current JNI environment */
+ jobject obj; /* The gnu.xml.libxmlj.sax.GnomeXmlReader instance */
+ xmlParserCtxtPtr ctx; /* libxml2 parser context */
+ xmlSAXLocatorPtr loc; /* libxml2 SAX locator */
+ xmlSAXHandlerPtr sax; /* pristine SAX handler */
+ jstring publicId;
+ jstring systemId;
+
+ jmethodID startDTD;
+ jmethodID externalEntityDecl;
+ jmethodID internalEntityDecl;
+ jmethodID resolveEntity;
+ jmethodID notationDecl;
+ jmethodID attributeDecl;
+ jmethodID elementDecl;
+ jmethodID unparsedEntityDecl;
+ jmethodID setDocumentLocator;
+ jmethodID startDocument;
+ jmethodID endDocument;
+ jmethodID startElement;
+ jmethodID endElement;
+ jmethodID characters;
+ jmethodID ignorableWhitespace;
+ jmethodID processingInstruction;
+ jmethodID comment;
+ jmethodID cdataBlock;
+ jmethodID warning;
+ jmethodID error;
+ jmethodID fatalError;
+
+ jmethodID resolveURIAndOpen; /* JavaProxy */
+ jclass stringClass;
+}
+SAXParseContext;
+
+SAXParseContext *
+xmljNewSAXParseContext (JNIEnv * env, jobject obj, xmlParserCtxtPtr ctx,
+ jstring publicId, jstring systemId);
+
+void
+xmljFreeSAXParseContext (SAXParseContext * saxCtx);
+
+xmlParserCtxtPtr
+xmljNewParserContext (JNIEnv * env,
+ jobject inputStream,
+ jbyteArray detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean coalesce,
+ jboolean expandEntities,
+ jboolean loadEntities);
+
+void
+xmljFreeParserContext (xmlParserCtxtPtr parserContext);
+
+xmlDocPtr
+xmljParseDocument (JNIEnv * env,
+ jobject self,
+ jobject in,
+ jbyteArray detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean coalesce,
+ jboolean expandEntities,
+ jboolean contentHandler,
+ jboolean dtdHandler,
+ jboolean entityResolver,
+ jboolean errorHandler,
+ jboolean declarationHandler,
+ jboolean lexicalHandler,
+ int saxMode);
+
+xmlDocPtr
+xmljParseDocument2 (JNIEnv * env,
+ xmlParserCtxtPtr ctx,
+ SAXParseContext *saxCtx,
+ xmlSAXHandlerPtr sax,
+ int saxMode);
+
+xmlParserInputPtr
+xmljNewParserInput (JNIEnv * env,
+ jobject inputStream,
+ jbyteArray detectBuffer,
+ xmlParserCtxtPtr parserContext);
+
+xmlParserInputBufferPtr
+xmljNewParserInputBuffer (JNIEnv * env,
+ jobject inputStream,
+ xmlCharEncoding encoding);
+
+void
+xmljSaveFileToJavaOutputStream (JNIEnv * env, jobject outputStream,
+ xmlDocPtr tree,
+ const char *outputEncoding);
+
+/*
+xmlParserInputPtr
+xmljLoadExternalEntity (const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt);
+
+jobject
+xmljResolveURI (SaxErrorContext * saxErrorContext, const char *URL,
+ const char *ID);
+*/
+xmlDocPtr
+xmljResolveURIAndOpen (SAXParseContext *saxContext,
+ const char *URL, const char *ID);
+
+
+void
+xmljSetThreadContext (SAXParseContext * ctxt);
+
+SAXParseContext *
+xmljGetThreadContext (void);
+
+void
+xmljClearThreadContext (void);
+
+#endif /* !defined XMLJ_IO_H */
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_node.c b/libjava/classpath/native/jni/xmlj/xmlj_node.c
new file mode 100644
index 00000000000..20832678a25
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_node.c
@@ -0,0 +1,203 @@
+/* xmlj_node.c -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_error.h"
+#include "xmlj_node.h"
+#include "xmlj_util.h"
+#include <libxml/xmlstring.h>
+
+/*
+ * Returns the node ID for the given GnomeNode object.
+ */
+xmlNodePtr
+xmljGetNodeID (JNIEnv * env, jobject self)
+{
+ jclass cls;
+ jfieldID field;
+ jobject id;
+ xmlNodePtr node;
+
+ if (self == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ return NULL;
+ }
+ cls = (*env)->GetObjectClass (env, self);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ field = (*env)->GetFieldID (env, cls, "id", "Ljava/lang/Object;");
+ if (field == NULL)
+ {
+ return NULL;
+ }
+ id = (*env)->GetObjectField (env, self, field);
+ node = (xmlNodePtr) xmljAsPointer (env, id);
+ if (node == NULL)
+ {
+ xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
+ }
+ return node;
+}
+
+/*
+ * Returns the Java node instanced corresponding to the specified node ID.
+ */
+jobject
+xmljGetNodeInstance (JNIEnv * env, xmlNodePtr node)
+{
+ jclass cls;
+ jmethodID method;
+ xmlElementType type;
+
+ if (node == NULL)
+ return NULL;
+
+ /* Invoke the GnomeNode.newInstance class method */
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeNode");
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ method = (*env)->GetStaticMethodID (env, cls, "newInstance",
+ "(Ljava/lang/Object;Ljava/lang/Object;I)Lgnu/xml/libxmlj/dom/GnomeNode;");
+
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ type = node->type;
+ switch (type)
+ {
+ case XML_DTD_NODE:
+ type = XML_DOCUMENT_TYPE_NODE;
+ break;
+ case XML_ATTRIBUTE_DECL:
+ type = XML_ATTRIBUTE_NODE;
+ break;
+ case XML_ENTITY_DECL:
+ type = XML_ENTITY_NODE;
+ break;
+ default:
+ break;
+ }
+ return (*env)->CallStaticObjectMethod (env, cls, method,
+ xmljAsField (env, node->doc),
+ xmljAsField (env, node),
+ type);
+}
+
+void
+xmljFreeDoc (JNIEnv * env, xmlDocPtr doc)
+{
+ jclass cls;
+ jmethodID method;
+
+ /* Invoke the GnomeNode.freeDocument class method */
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeNode");
+ if (cls == NULL)
+ {
+ return;
+ }
+ method = (*env)->GetStaticMethodID (env, cls, "freeDocument",
+ "(Ljava/lang/Object;)V");
+ if (method == NULL)
+ {
+ return;
+ }
+ (*env)->CallStaticVoidMethod (env, cls, method, xmljAsField (env, doc));
+}
+
+int
+xmljMatch (const xmlChar * name, xmlNodePtr node)
+{
+ switch (node->type)
+ {
+ case XML_ELEMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ return xmlStrcmp (node->name, name);
+ default:
+ return 1;
+ }
+}
+
+int
+xmljMatchNS (const xmlChar * uri, const xmlChar * localName, xmlNodePtr node)
+{
+ xmlNsPtr ns;
+ const xmlChar *nodeLocalName;
+ int *len;
+ int ret;
+
+ switch (node->type)
+ {
+ case XML_ELEMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ len = (int *) malloc (sizeof (int));
+ if (xmlSplitQName3 (node->name, len) != NULL)
+ {
+ nodeLocalName = node->name + (*len);
+ }
+ else
+ {
+ nodeLocalName = node->name;
+ }
+ free (len);
+ ns = node->ns;
+ if (ns == NULL || ns->href == NULL)
+ {
+ if (uri != NULL)
+ {
+ return 0;
+ }
+ ret = xmlStrcmp (localName, nodeLocalName);
+ }
+ else
+ {
+ if (uri == NULL)
+ {
+ return 0;
+ }
+ ret = (xmlStrcmp (localName, nodeLocalName) &&
+ xmlStrcmp (uri, ns->href));
+ }
+ return ret;
+ default:
+ return 1;
+ }
+}
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_node.h b/libjava/classpath/native/jni/xmlj/xmlj_node.h
new file mode 100644
index 00000000000..11f5e308b82
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_node.h
@@ -0,0 +1,72 @@
+/* xmlj_node.h -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_NODE_H
+#define XMLJ_NODE_H
+
+#include <jni.h>
+#include <libxml/tree.h>
+
+/* -- Utility method definitions -- */
+
+/*
+ * Returns the node for the given Java node instance
+ */
+xmlNodePtr xmljGetNodeID (JNIEnv *, jobject);
+
+/*
+ * Returns the Java node instance for the given node
+ */
+jobject xmljGetNodeInstance (JNIEnv *, xmlNodePtr);
+
+/*
+ * Frees the specified document pointer,
+ * releasing all its nodes from the cache.
+ */
+void xmljFreeDoc (JNIEnv *, xmlDocPtr);
+
+/*
+ * Match a node name
+ */
+int xmljMatch (const xmlChar *, xmlNodePtr);
+
+/*
+ * Match a node name and namespace
+ */
+int xmljMatchNS (const xmlChar *, const xmlChar *, xmlNodePtr);
+
+#endif /* !defined XMLJ_NODE_H */
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_sax.c b/libjava/classpath/native/jni/xmlj/xmlj_sax.c
new file mode 100644
index 00000000000..78991bdad73
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_sax.c
@@ -0,0 +1,1445 @@
+/* xmlj_sax.c -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_sax.h"
+#include "xmlj_io.h"
+#include "xmlj_util.h"
+#include <unistd.h>
+#include <string.h>
+
+xmlExternalEntityLoader defaultLoader = NULL;
+
+void
+xmljDispatchError (xmlParserCtxtPtr ctx,
+ xmlSAXLocatorPtr loc,
+ JNIEnv *env,
+ jobject target,
+ jmethodID method,
+ const char *msg,
+ va_list args);
+
+/* -- GnomeLocator -- */
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_sax_GnomeLocator_publicId (JNIEnv * env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject j_ctx,
+ jobject j_loc)
+{
+ xmlParserCtxtPtr ctx;
+ xmlSAXLocatorPtr loc;
+ SAXParseContext *sax;
+
+ ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
+ loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
+ sax = (SAXParseContext *) ctx->_private;
+
+ return sax->publicId;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_sax_GnomeLocator_systemId (JNIEnv * env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject j_ctx,
+ jobject j_loc)
+{
+ xmlParserCtxtPtr ctx;
+ xmlSAXLocatorPtr loc;
+ SAXParseContext *sax;
+
+ ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
+ loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
+ sax = (SAXParseContext *) ctx->_private;
+
+ return sax->systemId;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_sax_GnomeLocator_lineNumber (JNIEnv * env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject j_ctx,
+ jobject j_loc)
+{
+ xmlParserCtxtPtr ctx;
+ xmlSAXLocatorPtr loc;
+
+ ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
+ loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
+ if (ctx == NULL || ctx->input == NULL)
+ {
+ return -1;
+ }
+ return ctx->input->line;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_sax_GnomeLocator_columnNumber (JNIEnv * env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject j_ctx,
+ jobject j_loc)
+{
+ xmlParserCtxtPtr ctx;
+ xmlSAXLocatorPtr loc;
+
+ ctx = (xmlParserCtxtPtr) xmljAsPointer (env, j_ctx);
+ loc = (xmlSAXLocatorPtr) xmljAsPointer (env, j_loc);
+ if (ctx == NULL || ctx->input == NULL)
+ {
+ return -1;
+ }
+ return ctx->input->col;
+}
+
+/* -- GnomeXMLReader -- */
+
+/*
+ * Entry point for SAX parsing.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_sax_GnomeXMLReader_parseStream (JNIEnv * env,
+ jobject self,
+ jobject in,
+ jbyteArray detectBuffer,
+ jstring publicId,
+ jstring systemId,
+ jstring base,
+ jboolean validate,
+ jboolean contentHandler,
+ jboolean dtdHandler,
+ jboolean entityResolver,
+ jboolean errorHandler,
+ jboolean
+ declarationHandler,
+ jboolean lexicalHandler)
+{
+ xmljParseDocument (env,
+ self,
+ in,
+ detectBuffer,
+ publicId,
+ systemId,
+ base,
+ validate,
+ 0,
+ 0,
+ contentHandler,
+ dtdHandler,
+ entityResolver,
+ errorHandler,
+ declarationHandler,
+ lexicalHandler,
+ 0);
+}
+
+xmlParserInputPtr
+xmljExternalEntityLoader (const char *url, const char *id,
+ xmlParserCtxtPtr ctx)
+{
+ const xmlChar *systemId;
+ const xmlChar *publicId;
+ xmlParserInputPtr ret;
+
+ systemId = xmlCharStrdup (url);
+ publicId = xmlCharStrdup (id);
+ /* TODO convert systemId to absolute URI */
+ ret = xmljSAXResolveEntity (ctx, publicId, systemId);
+ if (ret == NULL)
+ {
+ ret = defaultLoader (url, id, ctx);
+ }
+ return ret;
+}
+
+/*
+ * Allocates and configures a SAX handler that can report the various
+ * classes of callback.
+ */
+xmlSAXHandlerPtr
+xmljNewSAXHandler (jboolean contentHandler,
+ jboolean dtdHandler,
+ jboolean entityResolver,
+ jboolean errorHandler,
+ jboolean declarationHandler,
+ jboolean lexicalHandler)
+{
+ xmlSAXHandlerPtr sax;
+
+ sax = (xmlSAXHandlerPtr) malloc (sizeof (xmlSAXHandler));
+ if (sax == NULL)
+ {
+ return NULL;
+ }
+ memset (sax, 0, sizeof (xmlSAXHandler));
+ xmlSAXVersion (sax, 1); /* TODO SAX2 */
+
+ if (dtdHandler)
+ {
+ sax->internalSubset = &xmljSAXInternalSubset;
+ }
+ if (defaultLoader == NULL)
+ {
+ defaultLoader = xmlGetExternalEntityLoader ();
+ xmlSetExternalEntityLoader (xmljExternalEntityLoader);
+ }
+ if (entityResolver)
+ {
+ sax->resolveEntity = &xmljSAXResolveEntity;
+ }
+
+ if (declarationHandler)
+ {
+ sax->entityDecl = &xmljSAXEntityDecl;
+ sax->notationDecl = &xmljSAXNotationDecl;
+ sax->attributeDecl = &xmljSAXAttributeDecl;
+ sax->elementDecl = &xmljSAXElementDecl;
+ sax->unparsedEntityDecl = &xmljSAXUnparsedEntityDecl;
+ }
+
+ /* We always listen for the locator callback */
+ sax->setDocumentLocator = &xmljSAXSetDocumentLocator;
+ if (contentHandler)
+ {
+ sax->startDocument = &xmljSAXStartDocument;
+ sax->endDocument = &xmljSAXEndDocument;
+ sax->startElement = &xmljSAXStartElement;
+ sax->endElement = &xmljSAXEndElement;
+ sax->characters = &xmljSAXCharacters;
+ sax->ignorableWhitespace = &xmljSAXIgnorableWhitespace;
+ sax->processingInstruction = &xmljSAXProcessingInstruction;
+ }
+
+ /* We always intercept getEntity */
+ /* TODO this should only be if lexicalHandler */
+ sax->getEntity = &xmljSAXGetEntity;
+ if (lexicalHandler)
+ {
+ sax->getEntity = &xmljSAXGetEntity;
+ sax->reference = &xmljSAXReference;
+ sax->comment = &xmljSAXComment;
+ sax->cdataBlock = &xmljSAXCDataBlock;
+ }
+ else if (contentHandler)
+ {
+ sax->cdataBlock = &xmljSAXCharacters;
+ }
+
+ if (errorHandler)
+ {
+ sax->warning = &xmljSAXWarning;
+ sax->error = &xmljSAXError;
+ sax->fatalError = &xmljSAXFatalError;
+ }
+
+ return sax;
+}
+
+/* -- Callback functions -- */
+
+void
+xmljSAXInternalSubset (void *vctx,
+ const xmlChar * name,
+ const xmlChar * publicId, const xmlChar * systemId)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jstring j_publicId;
+ jstring j_systemId;
+
+ xmlSAX2InternalSubset (vctx, name, publicId, systemId);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->startDTD == NULL)
+ {
+ sax->startDTD =
+ xmljGetMethodID (env,
+ target,
+ "startDTD",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->startDTD == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+ j_publicId = xmljNewString (env, publicId);
+ j_systemId = xmljNewString (env, systemId);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->startDTD,
+ j_name,
+ j_publicId,
+ j_systemId);
+}
+
+xmlParserInputPtr
+xmljSAXResolveEntity (void *vctx,
+ const xmlChar * publicId, const xmlChar * systemId)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_publicId;
+ jstring j_systemId;
+ jobject inputStream;
+
+ /* xmlSAX2ResolveEntity (vctx, publicId, systemId); */
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ if (ctx->_private == NULL)
+ {
+ /* Not in Kansas */
+ return NULL;
+ }
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+
+ if (sax->resolveEntity == NULL)
+ {
+ sax->resolveEntity =
+ xmljGetMethodID (env,
+ target,
+ "resolveEntity",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/io/InputStream;");
+ if (sax->resolveEntity == NULL)
+ {
+ return NULL;
+ }
+ }
+
+ j_publicId = xmljNewString (env, publicId);
+ j_systemId = xmljNewString (env, systemId);
+
+ inputStream = (*env)->CallObjectMethod (env,
+ target,
+ sax->resolveEntity,
+ j_publicId,
+ j_systemId,
+ sax->systemId);
+
+ /* Return an xmlParserInputPtr corresponding to the input stream */
+ if (inputStream != NULL)
+ {
+ jbyteArray detectBuffer;
+ jmethodID getDetectBuffer;
+
+ /* Get the detect buffer from the NamedInputStream */
+ getDetectBuffer = xmljGetMethodID (env, inputStream, "getDetectBuffer",
+ "()[B");
+ if (getDetectBuffer == NULL)
+ {
+ return NULL;
+ }
+ detectBuffer = (*env)->CallObjectMethod (env, inputStream,
+ getDetectBuffer);
+
+ return xmljNewParserInput (env, inputStream, detectBuffer, ctx);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+xmlEntityPtr
+xmljSAXGetEntity (void *vctx __attribute__((__unused__)), const xmlChar * name)
+{
+ xmlEntityPtr ret;
+
+ /* TODO */
+ /* ret = xmlSAX2GetEntity (vctx, name); */
+ ret = NULL;
+ return ret;
+}
+
+void
+xmljSAXEntityDecl (void *vctx,
+ const xmlChar * name,
+ int type,
+ const xmlChar * publicId,
+ const xmlChar * systemId,
+ xmlChar * content)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jstring j_publicId;
+ jstring j_systemId;
+ jstring j_value;
+
+ xmlSAX2EntityDecl (vctx, name, type, publicId, systemId, content);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ j_name = xmljNewString (env, name);
+ switch (type)
+ {
+ case XML_INTERNAL_GENERAL_ENTITY:
+ case XML_INTERNAL_PARAMETER_ENTITY:
+ case XML_INTERNAL_PREDEFINED_ENTITY:
+ if (sax->internalEntityDecl == NULL)
+ {
+ sax->internalEntityDecl =
+ xmljGetMethodID (env,
+ target,
+ "internalEntityDecl",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->internalEntityDecl == NULL)
+ {
+ return;
+ }
+ }
+ j_value = xmljNewString (env, content);
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->internalEntityDecl,
+ j_name,
+ j_value);
+ break;
+ default:
+ if (sax->externalEntityDecl == NULL)
+ {
+ sax->externalEntityDecl =
+ xmljGetMethodID (env,
+ target,
+ "externalEntityDecl",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->externalEntityDecl == NULL)
+ {
+ return;
+ }
+ }
+ j_publicId = xmljNewString (env, publicId);
+ j_systemId = xmljNewString (env, systemId);
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->externalEntityDecl,
+ j_name,
+ j_publicId,
+ j_systemId);
+ }
+}
+
+void
+xmljSAXNotationDecl (void *vctx,
+ const xmlChar * name,
+ const xmlChar * publicId,
+ const xmlChar * systemId)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jstring j_publicId;
+ jstring j_systemId;
+
+ xmlSAX2NotationDecl (vctx, name, publicId, systemId);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->notationDecl == NULL)
+ {
+ sax->notationDecl =
+ xmljGetMethodID (env,
+ target,
+ "notationDecl",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->notationDecl == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+ j_publicId = xmljNewString (env, publicId);
+ j_systemId = xmljNewString (env, systemId);
+
+ /* Invoke the method */
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->notationDecl,
+ j_name,
+ j_publicId,
+ j_systemId);
+}
+
+void
+xmljSAXAttributeDecl (void *vctx,
+ const xmlChar * elem,
+ const xmlChar * fullName,
+ int type,
+ int def,
+ const xmlChar * defaultValue,
+ xmlEnumerationPtr tree)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_eName;
+ jstring j_aName;
+ jstring j_type;
+ jstring j_mode;
+ jstring j_value;
+
+ xmlSAX2AttributeDecl (vctx, elem, fullName, type, def, defaultValue, tree);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->attributeDecl == NULL)
+ {
+ sax->attributeDecl =
+ xmljGetMethodID (env,
+ target,
+ "attributeDecl",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->attributeDecl == NULL)
+ {
+ return;
+ }
+ }
+
+ j_eName = xmljNewString (env, elem);
+ j_aName = xmljNewString (env, fullName);
+ j_type = xmljAttributeTypeName (env, type);
+ j_mode = xmljAttributeModeName (env, def);
+ j_value = xmljNewString (env, defaultValue);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->attributeDecl,
+ j_eName,
+ j_aName,
+ j_type,
+ j_mode,
+ j_value);
+}
+
+void
+xmljSAXElementDecl (void *vctx,
+ const xmlChar * name,
+ int type,
+ xmlElementContentPtr content)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jstring j_model;
+
+ xmlSAX2ElementDecl (vctx, name, type, content);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->elementDecl == NULL)
+ {
+ sax->elementDecl =
+ xmljGetMethodID (env,
+ target,
+ "elementDecl",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->elementDecl == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+ j_model = NULL; /* TODO */
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->elementDecl,
+ j_name,
+ j_model);
+}
+
+void
+xmljSAXUnparsedEntityDecl (void *vctx,
+ const xmlChar * name,
+ const xmlChar * publicId,
+ const xmlChar * systemId,
+ const xmlChar * notationName)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jstring j_publicId;
+ jstring j_systemId;
+ jstring j_notationName;
+
+ xmlSAX2UnparsedEntityDecl (vctx, name, publicId, systemId, notationName);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->unparsedEntityDecl == NULL)
+ {
+ sax->unparsedEntityDecl =
+ xmljGetMethodID (env,
+ target,
+ "unparsedEntityDecl",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->unparsedEntityDecl == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+ j_publicId = xmljNewString (env, publicId);
+ j_systemId = xmljNewString (env, systemId);
+ j_notationName = xmljNewString (env, notationName);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->unparsedEntityDecl,
+ j_name,
+ j_publicId,
+ j_systemId,
+ j_notationName);
+}
+
+void
+xmljSAXSetDocumentLocator (void *vctx, xmlSAXLocatorPtr loc)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+
+ xmlSAX2SetDocumentLocator (vctx, loc);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ if (target == NULL)
+ {
+ /* No Java parse context */
+ return;
+ }
+
+ /* Update locator on sax context */
+ sax->loc = loc;
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->setDocumentLocator == NULL)
+ {
+ sax->setDocumentLocator = xmljGetMethodID (env,
+ target,
+ "setDocumentLocator",
+ "(Ljava/lang/Object;Ljava/lang/Object;)V");
+ if (sax->setDocumentLocator == NULL)
+ {
+ return;
+ }
+ }
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->setDocumentLocator,
+ xmljAsField (env, ctx),
+ xmljAsField (env, loc));
+}
+
+void
+xmljSAXStartDocument (void *vctx)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+
+ xmlSAX2StartDocument (vctx);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->startDocument == NULL)
+ {
+ sax->startDocument = xmljGetMethodID (env,
+ target,
+ "startDocument",
+ "(Z)V");
+ if (sax->startDocument == NULL)
+ {
+ return;
+ }
+ }
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->startDocument,
+ ctx->standalone);
+}
+
+void
+xmljSAXEndDocument (void *vctx)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+
+ xmlSAX2EndDocument (vctx);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->endDocument == NULL)
+ {
+ sax->endDocument = xmljGetMethodID (env,
+ target,
+ "endDocument",
+ "()V");
+ if (sax->endDocument == NULL)
+ {
+ return;
+ }
+ }
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->endDocument);
+}
+
+void
+xmljSAXStartElement (void *vctx,
+ const xmlChar * name,
+ const xmlChar ** attrs)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+ jobjectArray j_attrs;
+ jstring j_attr;
+ jsize len;
+
+ xmlSAX2StartElement (vctx, name, attrs);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->startElement == NULL)
+ {
+ sax->startElement =
+ xmljGetMethodID (env,
+ target,
+ "startElement",
+ "(Ljava/lang/String;[Ljava/lang/String;)V");
+ if (sax->startElement == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+ /* build attributes array */
+ len = 0;
+ for (len = 0; attrs && attrs[len]; len++)
+ {
+ }
+ if (len)
+ {
+ if (sax->stringClass == NULL)
+ {
+ sax->stringClass = (*env)->FindClass (env, "java/lang/String");
+ if (sax->stringClass == NULL)
+ {
+ fprintf (stderr, "Can't find java.lang.String class!\n");
+ return;
+ }
+ }
+ j_attrs = (*env)->NewObjectArray (env, len, sax->stringClass, NULL);
+ if (j_attrs == NULL)
+ {
+ fprintf (stderr, "Can't allocate attributes array!\n");
+ return;
+ }
+ len = 0;
+ for (len = 0; attrs && attrs[len]; len++)
+ {
+ j_attr = xmljNewString (env, attrs[len]);
+ (*env)->SetObjectArrayElement (env, j_attrs, len, j_attr);
+ }
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->startElement,
+ j_name,
+ j_attrs);
+ (*env)->DeleteLocalRef (env, j_attrs);
+ }
+ else
+ {
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->startElement,
+ j_name,
+ NULL);
+
+ }
+}
+
+void
+xmljSAXEndElement (void *vctx,
+ const xmlChar * name)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_name;
+
+ xmlSAX2EndElement (vctx, name);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->endElement == NULL)
+ {
+ sax->endElement = xmljGetMethodID (env,
+ target,
+ "endElement",
+ "(Ljava/lang/String;)V");
+ if (sax->endElement == NULL)
+ {
+ return;
+ }
+ }
+
+ j_name = xmljNewString (env, name);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->endElement,
+ j_name);
+}
+
+void
+xmljSAXReference (void *vctx,
+ const xmlChar * name)
+{
+ xmlSAX2Reference (vctx, name);
+}
+
+void
+xmljSAXCharacters (void *vctx,
+ const xmlChar * ch,
+ int len)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_ch;
+ xmlChar *dup;
+
+ xmlSAX2Characters (vctx, ch, len);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->characters == NULL)
+ {
+ sax->characters = xmljGetMethodID (env,
+ target,
+ "characters",
+ "(Ljava/lang/String;)V");
+ if (sax->characters == NULL)
+ {
+ return;
+ }
+ }
+
+ dup = xmlStrndup (ch, len);
+ j_ch = xmljNewString (env, dup);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->characters,
+ j_ch);
+ xmlFree (dup);
+}
+
+void
+xmljSAXIgnorableWhitespace (void *vctx,
+ const xmlChar * ch,
+ int len)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_ch;
+ xmlChar *dup;
+
+ xmlSAX2IgnorableWhitespace (vctx, ch, len);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->ignorableWhitespace == NULL)
+ {
+ sax->ignorableWhitespace = xmljGetMethodID (env,
+ target,
+ "ignorableWhitespace",
+ "(Ljava/lang/String;)V");
+ if (sax->ignorableWhitespace == NULL)
+ {
+ return;
+ }
+ }
+
+ dup = xmlStrndup (ch, len);
+ j_ch = xmljNewString (env, dup);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->ignorableWhitespace,
+ j_ch);
+ xmlFree (dup);
+}
+
+void
+xmljSAXProcessingInstruction (void *vctx,
+ const xmlChar * targ,
+ const xmlChar * data)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_targ;
+ jstring j_data;
+
+ xmlSAX2ProcessingInstruction (vctx, targ, data);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->processingInstruction == NULL)
+ {
+ sax->processingInstruction =
+ xmljGetMethodID (env,
+ target,
+ "processingInstruction",
+ "(Ljava/lang/String;Ljava/lang/String;)V");
+ if (sax->processingInstruction == NULL)
+ {
+ return;
+ }
+ }
+
+ j_targ = xmljNewString (env, targ);
+ j_data = xmljNewString (env, data);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->processingInstruction,
+ j_targ,
+ j_data);
+}
+
+void
+xmljSAXComment (void *vctx,
+ const xmlChar * value)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_text;
+
+ xmlSAX2Comment (vctx, value);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->comment == NULL)
+ {
+ sax->comment =
+ xmljGetMethodID (env,
+ target,
+ "comment",
+ "(Ljava/lang/String;)V");
+ if (sax->comment == NULL)
+ {
+ return;
+ }
+ }
+
+ j_text = xmljNewString (env, value);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->comment,
+ j_text);
+}
+
+void
+xmljSAXCDataBlock (void *vctx,
+ const xmlChar * ch,
+ int len)
+{
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ JNIEnv *env;
+ jobject target;
+ jstring j_ch;
+ xmlChar *dup;
+
+ xmlSAX2CDataBlock (vctx, ch, len);
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ env = sax->env;
+ target = sax->obj;
+
+ xmljCheckWellFormed (ctx);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+
+ if (sax->cdataBlock == NULL)
+ {
+ sax->cdataBlock =
+ xmljGetMethodID (env,
+ target,
+ "cdataBlock",
+ "(Ljava/lang/String;)V");
+ if (sax->cdataBlock == NULL)
+ {
+ return;
+ }
+ }
+
+ dup = xmlStrndup (ch, len);
+ j_ch = xmljNewString (env, dup);
+
+ (*env)->CallVoidMethod (env,
+ target,
+ sax->cdataBlock,
+ j_ch);
+ xmlFree (dup);
+}
+
+void
+xmljDispatchError (xmlParserCtxtPtr ctx,
+ xmlSAXLocatorPtr loc,
+ JNIEnv *env,
+ jobject target,
+ jmethodID method,
+ const char *msg,
+ va_list args)
+{
+ jint lineNumber;
+ jint columnNumber;
+ jstring publicId;
+ jstring systemId;
+ char buffer[2048] = "";
+
+ if (msg != NULL)
+ {
+ vsnprintf (buffer, sizeof buffer, msg, args);
+ }
+ lineNumber = loc->getLineNumber (ctx);
+ columnNumber = loc->getColumnNumber (ctx);
+ publicId = xmljNewString (env, loc->getPublicId (ctx));
+ systemId = xmljNewString (env, loc->getSystemId (ctx));
+ (*env)->CallVoidMethod (env,
+ target,
+ method,
+ (*env)->NewStringUTF (env, buffer),
+ lineNumber,
+ columnNumber,
+ publicId,
+ systemId);
+}
+
+void
+xmljSAXWarning (void *vctx,
+ const char *msg,
+ ...)
+{
+ va_list args;
+
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ xmlSAXLocatorPtr loc;
+ JNIEnv *env;
+ jobject target;
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ loc = (xmlSAXLocatorPtr) sax->loc;
+ env = sax->env;
+ target = sax->obj;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+ if (sax->warning == NULL)
+ {
+ sax->warning =
+ xmljGetMethodID (env,
+ target,
+ "warning",
+ "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
+ if (sax->warning == NULL)
+ {
+ return;
+ }
+ }
+
+ va_start (args, msg);
+ /* xmlParserWarning (vctx, msg, args); */
+ xmljDispatchError (ctx, loc, env, target, sax->warning, msg, args);
+ va_end (args);
+}
+
+void
+xmljSAXError (void *vctx,
+ const char *msg,
+ ...)
+{
+ va_list args;
+
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ xmlSAXLocatorPtr loc;
+ JNIEnv *env;
+ jobject target;
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ loc = (xmlSAXLocatorPtr) sax->loc;
+ env = sax->env;
+ target = sax->obj;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+ if (sax->error == NULL)
+ {
+ sax->error =
+ xmljGetMethodID (env,
+ target,
+ "error",
+ "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
+ if (sax->error == NULL)
+ {
+ return;
+ }
+ }
+
+ va_start (args, msg);
+ /* xmlParserError (vctx, msg, args); */
+ xmljDispatchError (ctx, loc, env, target, sax->error, msg, args);
+ va_end (args);
+}
+
+void
+xmljSAXFatalError (void *vctx,
+ const char *msg,
+ ...)
+{
+ va_list args;
+
+ xmlParserCtxtPtr ctx;
+ SAXParseContext *sax;
+ xmlSAXLocatorPtr loc;
+ JNIEnv *env;
+ jobject target;
+
+ ctx = (xmlParserCtxtPtr) vctx;
+ sax = (SAXParseContext *) ctx->_private;
+ loc = (xmlSAXLocatorPtr) sax->loc;
+ env = sax->env;
+ target = sax->obj;
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ return;
+ }
+ if (sax->fatalError == NULL)
+ {
+ sax->fatalError =
+ xmljGetMethodID (env,
+ target,
+ "fatalError",
+ "(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;)V");
+ if (sax->fatalError == NULL)
+ {
+ return;
+ }
+ }
+
+ va_start (args, msg);
+ /* xmlParserError (vctx, msg, args); */
+ xmljDispatchError (ctx, loc, env, target, sax->fatalError, msg, args);
+ va_end (args);
+}
+
+void
+xmljCheckWellFormed (xmlParserCtxtPtr ctx)
+{
+ if (!ctx->wellFormed)
+ {
+ xmljSAXFatalError (ctx, "document is not well-formed");
+ }
+ if (ctx->validate && !ctx->valid)
+ {
+ xmljSAXFatalError (ctx, "document is not valid");
+ }
+}
+
+/*
+ * Convert a libxml2 attribute type to a string.
+ */
+jstring
+xmljAttributeTypeName (JNIEnv * env, int type)
+{
+ const char *text;
+
+ switch (type)
+ {
+ case XML_ATTRIBUTE_CDATA:
+ text = "CDATA";
+ break;
+ case XML_ATTRIBUTE_ID:
+ text = "ID";
+ break;
+ case XML_ATTRIBUTE_IDREF:
+ text = "IDREF";
+ break;
+ case XML_ATTRIBUTE_IDREFS:
+ text = "IDREFS";
+ break;
+ case XML_ATTRIBUTE_NMTOKEN:
+ text = "NMTOKEN";
+ break;
+ case XML_ATTRIBUTE_NMTOKENS:
+ text = "NMTOKENS";
+ break;
+ case XML_ATTRIBUTE_ENTITY:
+ text = "ID";
+ break;
+ case XML_ATTRIBUTE_ENTITIES:
+ text = "ID";
+ break;
+ default:
+ return NULL;
+ }
+
+ return (*env)->NewStringUTF (env, text);
+}
+
+/*
+ * Convert a libxml2 attribute default value type to a string.
+ */
+jstring
+xmljAttributeModeName (JNIEnv * env, int type)
+{
+ const char *text;
+
+ switch (type)
+ {
+ case XML_ATTRIBUTE_IMPLIED:
+ text = "#IMPLIED";
+ break;
+ case XML_ATTRIBUTE_REQUIRED:
+ text = "#REQUIRED";
+ break;
+ case XML_ATTRIBUTE_FIXED:
+ text = "#FIXED";
+ break;
+ default:
+ return NULL;
+ }
+
+ return (*env)->NewStringUTF (env, text);
+}
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_sax.h b/libjava/classpath/native/jni/xmlj/xmlj_sax.h
new file mode 100644
index 00000000000..249929ce02a
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_sax.h
@@ -0,0 +1,160 @@
+/* xmlj_sax.h -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_SAX_H
+#define XMLJ_SAX_H
+
+#include "gnu_xml_libxmlj_sax_GnomeLocator.h"
+#include "gnu_xml_libxmlj_sax_GnomeXMLReader.h"
+
+#include <libxml/SAX.h>
+#include <libxml/parser.h>
+
+xmlSAXHandlerPtr
+xmljNewSAXHandler (jboolean contentHandler,
+ jboolean dtdHandler,
+ jboolean entityResolver,
+ jboolean errorHandler,
+ jboolean declarationHandler,
+ jboolean lexicalHandler);
+
+xmlParserInputPtr
+xmljExternalEntityLoader (const char *systemId, const char *publicId,
+ xmlParserCtxtPtr context);
+
+/* -- Function declarations for callback functions -- */
+
+void xmljSAXInternalSubset(void *ctx,
+ const xmlChar *name,
+ const xmlChar *publicId,
+ const xmlChar *systemId);
+
+xmlParserInputPtr xmljSAXResolveEntity(void *ctx,
+ const xmlChar *publicId,
+ const xmlChar *systemId);
+
+xmlEntityPtr xmljSAXGetEntity(void *ctx,
+ const xmlChar *name);
+
+void xmljSAXEntityDecl(void *ctx,
+ const xmlChar *name,
+ int type,
+ const xmlChar *publicId,
+ const xmlChar *systemId,
+ xmlChar *content);
+
+void xmljSAXNotationDecl(void *ctx,
+ const xmlChar *name,
+ const xmlChar *publicId,
+ const xmlChar *systemId);
+
+void xmljSAXAttributeDecl(void *ctx,
+ const xmlChar *elem,
+ const xmlChar *fullName,
+ int type,
+ int def,
+ const xmlChar *defaultValue,
+ xmlEnumerationPtr tree);
+
+void xmljSAXElementDecl(void *ctx,
+ const xmlChar *name,
+ int type,
+ xmlElementContentPtr content);
+
+void xmljSAXUnparsedEntityDecl(void *ctx,
+ const xmlChar *name,
+ const xmlChar *publicId,
+ const xmlChar *systemId,
+ const xmlChar *notationName);
+
+void xmljSAXSetDocumentLocator(void *ctx,
+ xmlSAXLocatorPtr loc);
+
+void xmljSAXStartDocument(void *ctx);
+
+void xmljSAXEndDocument(void *ctx);
+
+void xmljSAXStartElement(void *ctx,
+ const xmlChar *name,
+ const xmlChar **atts);
+
+void xmljSAXEndElement(void *ctx,
+ const xmlChar *name);
+
+void xmljSAXReference(void *ctx,
+ const xmlChar *name);
+
+void xmljSAXCharacters(void *ctx,
+ const xmlChar *ch,
+ int len);
+
+void xmljSAXIgnorableWhitespace(void *ctx,
+ const xmlChar *ch,
+ int len);
+
+void xmljSAXProcessingInstruction(void *ctx,
+ const xmlChar *target,
+ const xmlChar *data);
+
+void xmljSAXComment(void *ctx,
+ const xmlChar *value);
+
+void xmljSAXCDataBlock(void *ctx,
+ const xmlChar *ch,
+ int len);
+
+void xmljSAXWarning(void *ctx,
+ const char *msg,
+ ...);
+
+void xmljSAXError(void *ctx,
+ const char *msg,
+ ...);
+
+void xmljSAXFatalError(void *ctx,
+ const char *msg,
+ ...);
+
+void xmljCheckWellFormed(xmlParserCtxtPtr ctx);
+
+jstring xmljAttributeTypeName (JNIEnv *env,
+ int type);
+
+jstring xmljAttributeModeName (JNIEnv *env,
+ int type);
+
+#endif /* !defined XMLJ_SAX_H */
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_transform.c b/libjava/classpath/native/jni/xmlj/xmlj_transform.c
new file mode 100644
index 00000000000..075409ad10a
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_transform.c
@@ -0,0 +1,868 @@
+/* xmlj_transform.c -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "gnu_xml_libxmlj_transform_GnomeTransformerFactory.h"
+#include "gnu_xml_libxmlj_transform_GnomeTransformer.h"
+
+#include "xmlj_dom.h"
+#include "xmlj_io.h"
+#include "xmlj_error.h"
+#include "xmlj_node.h"
+#include "xmlj_sax.h"
+#include "xmlj_util.h"
+
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlIO.h>
+#include <libxml/xinclude.h>
+#include <libxml/parser.h>
+#include <libxml/catalog.h>
+#include <libxslt/keys.h>
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
+#include <libxslt/functions.h>
+#include <libxslt/extensions.h>
+#include <libxslt/documents.h>
+
+/* Local function prototypes */
+
+void
+xmljDocumentFunction (xmlXPathParserContextPtr ctxt, int nargs);
+
+xsltStylesheetPtr
+xmljGetStylesheetID (JNIEnv * env, jobject transformer);
+
+jobject
+xmljGetTransformerProperties (JNIEnv *env, jobject transformer);
+
+const xmlChar *
+xmljBooleanToString (int value);
+
+void
+xmljSetOutputProperties (JNIEnv *env, jobject transformer,
+ xsltStylesheetPtr stylesheet);
+
+jobjectArray
+xmljGetParameterArray (JNIEnv *env, jobject transformer);
+
+const char **
+xmljGetParameters (JNIEnv *env, jobjectArray pa);
+
+void
+xmljFreeParameters (JNIEnv *env, jobjectArray pa, const char **parameters);
+
+xmlDocPtr
+xmljTransform (JNIEnv *env, jobject transformer, xmlDocPtr source);
+
+void
+xmljTransformToSAX (JNIEnv *env, jobject transformer, xmlDocPtr source,
+ jobject callback);
+
+xmlDocPtr
+xmljDocLoader (const xmlChar *uri, xmlDictPtr dict, int options,
+ void *ctxt, xsltLoadType type);
+
+/* HACK: store stylesheet URL as context for resolving URIs in xmljDocLoader */
+static jstring stylesheetURL = NULL;
+
+/*
+ * --------------------------------------------------------------------------
+ *
+ * Native implementation for class
+ * gnu.xml.libxmlj.transform.GnomeTransformer follows.
+ */
+
+static void
+xmljSetProperty (JNIEnv * env, jobject outputProperties,
+ jmethodID setPropertyMethodID, const char *name,
+ const xmlChar * value)
+{
+ if (NULL != value)
+ {
+ jstring nameString = (*env)->NewStringUTF (env, name);
+ jstring valueString = (*env)->NewStringUTF (env, (const char *) value);
+
+ jobject prevValue = (*env)->CallObjectMethod (env, outputProperties,
+ setPropertyMethodID,
+ nameString, valueString);
+ if (NULL != prevValue)
+ {
+ (*env)->DeleteLocalRef (env, prevValue);
+ }
+
+ (*env)->DeleteLocalRef (env, nameString);
+ (*env)->DeleteLocalRef (env, valueString);
+ }
+}
+
+typedef struct CdataSectionScannerInfo_
+{
+ JNIEnv *env;
+ jobject stringBuffer;
+ jmethodID appendMethodID;
+ int isFirst;
+} CdataSectionScannerInfo;
+
+static void
+cdataSectionScanner (void *payload, void *data, xmlChar * name)
+{
+ CdataSectionScannerInfo *info = (CdataSectionScannerInfo *) data;
+ JNIEnv *env = info->env;
+ jstring nameString = (*env)->NewStringUTF (env, (const char *) name);
+ jstring blankString = (*env)->NewStringUTF (env, " ");
+ jobject stringBuffer;
+ if (!info->isFirst)
+ {
+ stringBuffer
+ = (*env)->CallObjectMethod (env,
+ info->stringBuffer,
+ info->appendMethodID, blankString);
+ (*env)->DeleteLocalRef (env, stringBuffer);
+ }
+ info->isFirst = 0;
+ stringBuffer
+ = (*env)->CallObjectMethod (env,
+ info->stringBuffer,
+ info->appendMethodID, nameString);
+ (*env)->DeleteLocalRef (env, stringBuffer);
+ (*env)->DeleteLocalRef (env, blankString);
+ (*env)->DeleteLocalRef (env, nameString);
+}
+
+void
+xmljDocumentFunction (xmlXPathParserContextPtr ctxt, int nargs)
+{
+ xmlXPathObjectPtr obj, obj2 = NULL;
+
+ if ((nargs < 1) || (nargs > 2))
+ {
+ xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
+ "document() : invalid number of args %d\n", nargs);
+ ctxt->error = XPATH_INVALID_ARITY;
+ return;
+ }
+ if (ctxt->value == NULL)
+ {
+ xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
+ "document() : invalid arg value\n");
+ ctxt->error = XPATH_INVALID_TYPE;
+ return;
+ }
+
+ if (nargs == 2)
+ {
+ if (ctxt->value->type != XPATH_NODESET)
+ {
+ xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
+ "document() : invalid arg expecting a nodeset\n");
+ ctxt->error = XPATH_INVALID_TYPE;
+ return;
+ }
+
+ obj2 = valuePop (ctxt);
+ }
+
+ if (ctxt->value->type == XPATH_NODESET)
+ {
+ int i;
+ xmlXPathObjectPtr newobj, ret;
+
+ obj = valuePop (ctxt);
+ ret = xmlXPathNewNodeSet (NULL);
+
+ if (obj->nodesetval)
+ {
+ for (i = 0; i < obj->nodesetval->nodeNr; i++)
+ {
+ valuePush (ctxt,
+ xmlXPathNewNodeSet (obj->nodesetval->nodeTab[i]));
+ xmlXPathStringFunction (ctxt, 1);
+ if (nargs == 2)
+ {
+ valuePush (ctxt, xmlXPathObjectCopy (obj2));
+ }
+ else
+ {
+ valuePush (ctxt,
+ xmlXPathNewNodeSet (obj->nodesetval->
+ nodeTab[i]));
+ }
+ xsltDocumentFunction (ctxt, 2);
+ newobj = valuePop (ctxt);
+ ret->nodesetval = xmlXPathNodeSetMerge (ret->nodesetval,
+ newobj->nodesetval);
+ xmlXPathFreeObject (newobj);
+ }
+ }
+
+ xmlXPathFreeObject (obj);
+ if (obj2 != NULL)
+ {
+ xmlXPathFreeObject (obj2);
+ }
+ valuePush (ctxt, ret);
+ return;
+ }
+ /*
+ * Make sure it's converted to a string
+ */
+ xmlXPathStringFunction (ctxt, 1);
+ if (ctxt->value->type != XPATH_STRING)
+ {
+ xsltTransformError (xsltXPathGetTransformContext (ctxt), NULL, NULL,
+ "document() : invalid arg expecting a string\n");
+ ctxt->error = XPATH_INVALID_TYPE;
+ if (obj2 != NULL)
+ xmlXPathFreeObject (obj2);
+ return;
+ }
+ obj = valuePop (ctxt);
+ if (obj->stringval == NULL)
+ {
+ valuePush (ctxt, xmlXPathNewNodeSet (NULL));
+ }
+ else
+ {
+
+ xsltTransformContextPtr tctxt;
+
+ tctxt = xsltXPathGetTransformContext (ctxt);
+
+ {
+ SAXParseContext *saxContext =
+ (SAXParseContext *) tctxt->style->_private;
+
+ xmlDocPtr tree = xmljResolveURIAndOpen (saxContext,
+ (const char*)obj->stringval,
+ NULL);
+
+ xsltNewDocument (tctxt, tree); /* FIXME - free at a later point */
+
+ valuePush (ctxt, xmlXPathNewNodeSet ((xmlNodePtr) tree));
+ }
+ }
+ xmlXPathFreeObject (obj);
+ if (obj2 != NULL) {
+ xmlXPathFreeObject (obj2);
+ }
+}
+
+/*
+ * Returns the stylesheet pointer for the given GnomeTransformer.
+ */
+xsltStylesheetPtr
+xmljGetStylesheetID (JNIEnv * env, jobject transformer)
+{
+ jclass cls;
+ jfieldID field;
+ jobject id;
+ xsltStylesheetPtr stylesheet;
+
+ if (transformer == NULL)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "Transformer is null");
+ return NULL;
+ }
+ cls = (*env)->GetObjectClass (env, transformer);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ field = (*env)->GetFieldID (env, cls, "stylesheet", "Ljava/lang/Object;");
+ if (field == NULL)
+ {
+ return NULL;
+ }
+ id = (*env)->GetObjectField (env, transformer, field);
+ stylesheet = (xsltStylesheetPtr) xmljAsPointer (env, id);
+ if (stylesheet == NULL)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "Stylesheet is null");
+ return NULL;
+ }
+ return stylesheet;
+}
+
+jobject
+xmljGetTransformerProperties (JNIEnv *env, jobject transformer)
+{
+ jclass cls;
+ jfieldID field;
+
+ cls = (*env)->GetObjectClass (env, transformer);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ field = (*env)->GetFieldID (env, cls, "outputProperties",
+ "Ljava/util/Properties;");
+ if (field == NULL)
+ {
+ return NULL;
+ }
+ return (*env)->GetObjectField (env, transformer, field);
+}
+
+const xmlChar *
+xmljBooleanToString (int value)
+{
+ return value ? BAD_CAST "yes" : BAD_CAST "no";
+}
+
+/*
+ * Sets the output properties for the given transformer,
+ * based on its stylesheet.
+ */
+void
+xmljSetOutputProperties (JNIEnv *env, jobject transformer,
+ xsltStylesheetPtr stylesheet)
+{
+ jobject outputProperties;
+ jclass propertiesClass;
+ jmethodID setPropertyMethod;
+
+ outputProperties = xmljGetTransformerProperties (env, transformer);
+ if (outputProperties == NULL)
+ {
+ return;
+ }
+ propertiesClass = (*env)->FindClass (env, "java/util/Properties");
+ if (propertiesClass == NULL)
+ {
+ return;
+ }
+ setPropertyMethod =
+ (*env)->GetMethodID (env, propertiesClass, "setProperty",
+ "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
+ if (setPropertyMethod == NULL)
+ {
+ return;
+ }
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "encoding", stylesheet->encoding);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "media-type", stylesheet->mediaType);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "doctype-public", stylesheet->doctypePublic);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "doctype-system", stylesheet->doctypeSystem);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "indent", xmljBooleanToString (stylesheet->indent));
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "method", stylesheet->method);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "standalone", xmljBooleanToString (stylesheet->standalone));
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "version", stylesheet->version);
+
+ xmljSetProperty (env, outputProperties, setPropertyMethod,
+ "omit-xml-declaration",
+ xmljBooleanToString (stylesheet->omitXmlDeclaration));
+
+ {
+ CdataSectionScannerInfo info;
+ jclass stringBufferClass
+ =
+ (*env)->FindClass (env,
+ "java/lang/StringBuffer");
+ jmethodID stringBufferConstructorID =
+ (*env)->GetMethodID (env, stringBufferClass,
+ "<init>", "()V");
+ jmethodID toStringMethodID =
+ (*env)->GetMethodID (env, stringBufferClass,
+ "toString",
+ "()Ljava/lang/String;");
+ info.env = env;
+ info.isFirst = 1;
+ info.stringBuffer
+ = (*env)->AllocObject (env, stringBufferClass);
+ (*env)->CallVoidMethod (env, info.stringBuffer,
+ stringBufferConstructorID);
+ info.appendMethodID =
+ (*env)->GetMethodID (env, stringBufferClass,
+ "append",
+ "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+
+ xmlHashScan (stylesheet->cdataSection,
+ cdataSectionScanner, &info);
+
+ {
+ jstring result = (jstring)
+ (*env)->CallObjectMethod (env,
+ info.stringBuffer,
+ toStringMethodID);
+
+ jstring nameString =
+ (*env)->NewStringUTF (env,
+ "cdata-section-elements");
+
+ jobject prevValue
+ =
+ (*env)->CallObjectMethod (env,
+ outputProperties,
+ setPropertyMethod,
+ nameString, result);
+ if (NULL != prevValue)
+ {
+ (*env)->DeleteLocalRef (env, prevValue);
+ }
+ (*env)->DeleteLocalRef (env, nameString);
+ }
+
+ (*env)->DeleteLocalRef (env, info.stringBuffer);
+ }
+}
+
+/*
+ * Returns the parameter array for the given GnomeTransformer.
+ */
+jobjectArray
+xmljGetParameterArray (JNIEnv *env, jobject transformer)
+{
+ jclass cls;
+ jmethodID method;
+
+ cls = (*env)->GetObjectClass (env, transformer);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ method = (*env)->GetMethodID (env, cls, "getParameterArray",
+ "()[Ljava/lang/String;");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ return (jobjectArray) (*env)->CallObjectMethod (env, transformer, method);
+}
+
+/* Convert parameter array to xmlChar ** */
+const char **
+xmljGetParameters (JNIEnv *env, jobjectArray pa)
+{
+ int i, len;
+ const char **parameters;
+
+ len = (*env)->GetArrayLength (env, pa);
+ parameters = (const char **) malloc ((len + 2) * sizeof (const char *));
+ if (parameters == NULL)
+ {
+ return NULL;
+ }
+
+ for (i = 0; i < len; i++)
+ {
+ jstring string = (jstring) (*env)->GetObjectArrayElement (env, pa, i);
+
+ if (string != NULL)
+ {
+ parameters[i] = (*env)->GetStringUTFChars (env, string, NULL);
+ }
+ else
+ {
+ parameters[i] = NULL;
+ }
+ }
+
+ parameters[len] = 0;
+ parameters[len + 1] = 0;
+ return parameters;
+}
+
+/* Release parameter strings */
+void
+xmljFreeParameters (JNIEnv *env, jobjectArray pa, const char **parameters)
+{
+ int i, len;
+
+ len = (*env)->GetArrayLength (env, pa);
+ for (i = 0; i < len; i++)
+ {
+ jstring string = (jstring) (*env)->GetObjectArrayElement (env, pa, i);
+ if (string != NULL)
+ {
+ (*env)->ReleaseStringUTFChars (env, string, parameters[i]);
+ }
+ }
+
+ free (parameters);
+}
+
+xmlDocPtr
+xmljTransform (JNIEnv *env, jobject transformer, xmlDocPtr source)
+{
+ xsltStylesheetPtr stylesheet;
+ xmlDocPtr result;
+ jobjectArray pa;
+ const char **parameters;
+
+ stylesheet = xmljGetStylesheetID (env, transformer);
+ pa = xmljGetParameterArray (env, transformer);
+ parameters = xmljGetParameters (env, pa);
+ if (parameters == NULL)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "Couldn't allocate memory for parameters");
+ return NULL;
+ }
+ result = xsltApplyStylesheet (stylesheet, source, parameters);
+ xmljFreeParameters (env, pa, parameters);
+ if (result == NULL)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "XSLT transformation failed");
+ }
+ return result;
+}
+
+void
+xmljTransformToSAX (JNIEnv *env, jobject transformer, xmlDocPtr source,
+ jobject callback)
+{
+ xsltStylesheetPtr stylesheet;
+ int ret;
+ jobjectArray pa;
+ const char **parameters;
+ xmlSAXHandlerPtr sax;
+
+ stylesheet = xmljGetStylesheetID (env, transformer);
+ pa = xmljGetParameterArray (env, transformer);
+ parameters = xmljGetParameters (env, pa);
+ if (parameters == NULL)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "Couldn't allocate memory for parameters");
+ return;
+ }
+ sax = NULL; /* TODO link up sax and callback */
+ ret = xsltRunStylesheet (stylesheet, source, parameters, NULL, sax, NULL);
+ xmljFreeParameters (env, pa, parameters);
+ if (ret == -1)
+ {
+ xmljThrowException (env, "javax/xml/transform/TransformerException",
+ "XSLT transformation failed");
+ }
+}
+
+xmlDocPtr
+xmljDocLoader (const xmlChar *uri, xmlDictPtr dict, int options,
+ void *ctxt, xsltLoadType type)
+{
+ JNIEnv *env;
+ jclass xmljClass;
+ jclass inputStreamClass;
+ jmethodID getInputStream;
+ jmethodID getDetectBuffer;
+ jstring systemId;
+ jobject inputStream;
+ jbyteArray detectBuffer;
+
+ fflush(stdout);
+ env = xmljGetJNIEnv ();
+ if (!env)
+ {
+ return NULL;
+ }
+ xmljClass = (*env)->FindClass (env, "gnu/xml/libxmlj/util/XMLJ");
+ if (!xmljClass)
+ {
+ return NULL;
+ }
+ getInputStream =
+ (*env)->GetStaticMethodID (env, xmljClass, "xmljGetInputStream",
+ "(Ljava/lang/String;Ljava/lang/String;)Lgnu/xml/libxmlj/util/NamedInputStream;");
+ if (!getInputStream)
+ {
+ return NULL;
+ }
+ systemId = xmljNewString (env, uri);
+ inputStream = (*env)->CallStaticObjectMethod (env, xmljClass, getInputStream,
+ stylesheetURL, systemId);
+ if (!inputStream)
+ {
+ return NULL;
+ }
+ inputStreamClass = (*env)->GetObjectClass (env, inputStream);
+ if (!inputStreamClass)
+ {
+ return NULL;
+ }
+ getDetectBuffer = (*env)->GetMethodID (env, inputStreamClass,
+ "getDetectBuffer", "()[B");
+ if (!getDetectBuffer)
+ {
+ return NULL;
+ }
+ detectBuffer = (*env)->CallObjectMethod (env, inputStream, getDetectBuffer);
+ if (!detectBuffer)
+ {
+ return NULL;
+ }
+ return xmljParseDocument (env, NULL, inputStream, detectBuffer,
+ NULL, systemId, stylesheetURL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2);
+}
+
+/* GnomeTransformer.newStylesheet */
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_newStylesheet (JNIEnv *env,
+ jobject self)
+{
+ xsltStylesheetPtr stylesheet;
+ jobject ret;
+
+ stylesheetURL = NULL;
+ xsltSetLoaderFunc (xmljDocLoader);
+ stylesheet = xsltNewStylesheet ();
+ xmljSetOutputProperties (env, self, stylesheet);
+ ret = xmljAsField (env, stylesheet);
+ if (ret == NULL)
+ {
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerConfigurationException",
+ "Can't create Java object for stylesheet");
+ }
+ return ret;
+}
+
+/* GnomeTransformer.newStylesheetFromStream */
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_newStylesheetFromStream
+(JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
+ jstring publicId, jstring systemId, jstring base,
+ jboolean entityResolver, jboolean errorHandler)
+{
+ xmlDocPtr doc;
+ xsltStylesheetPtr stylesheet;
+ jobject ret;
+
+ doc = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
+ base, 0, 0, 0, 0, 0,
+ entityResolver, errorHandler, 0, 0, 2);
+ if (doc == NULL)
+ {
+ return NULL;
+ }
+ stylesheetURL = systemId;
+ xsltSetLoaderFunc (xmljDocLoader);
+ stylesheet = xsltParseStylesheetDoc (doc);
+ if (stylesheet == NULL)
+ {
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerConfigurationException",
+ "Error parsing XSLT stylesheet");
+ return NULL;
+ }
+ xmljSetOutputProperties (env, self, stylesheet);
+ ret = xmljAsField (env, stylesheet);
+ if (ret == NULL)
+ {
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerConfigurationException",
+ "Can't create Java object for stylesheet");
+ }
+ return ret;
+}
+
+/* GnomeTransformer.newStylesheetFromDoc */
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_newStylesheetFromDoc
+(JNIEnv *env, jobject self, jobject in)
+{
+ xmlDocPtr doc;
+ xsltStylesheetPtr stylesheet;
+ jobject ret;
+
+ doc = (xmlDocPtr) xmljGetNodeID (env, in);
+ if (doc == NULL)
+ {
+ return NULL;
+ }
+ stylesheetURL = xmljNewString (env, doc->URL);
+ xsltSetLoaderFunc (xmljDocLoader);
+ stylesheet = xsltParseStylesheetDoc (doc);
+ if (stylesheet == NULL)
+ {
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerConfigurationException",
+ "Error parsing XSLT stylesheet");
+ }
+ xmljSetOutputProperties (env, self, stylesheet);
+ ret = xmljAsField (env, stylesheet);
+ if (ret == NULL)
+ {
+ xmljThrowException (env,
+ "javax/xml/transform/TransformerConfigurationException",
+ "Can't create Java object for stylesheet");
+ }
+ return ret;
+}
+
+/* GnomeTransformer.transformStreamToStream */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformStreamToStream
+(JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
+ jstring publicId, jstring systemId, jstring base,
+ jboolean entityResolver, jboolean errorHandler, jobject out)
+{
+ xmlDocPtr source;
+ xmlDocPtr result;
+
+ source = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
+ base, 0, 0, 0, 0, 0,
+ entityResolver, errorHandler, 0, 0, 2);
+ result = xmljTransform (env, self, source);
+ xmljSaveFileToJavaOutputStream (env, out, result,
+ (const char*) result->encoding);
+ xmlFreeDoc (result);
+}
+
+/* GnomeTransformer.transformStreamToDoc */
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformStreamToDoc
+(JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
+ jstring publicId, jstring systemId, jstring base,
+ jboolean entityResolver, jboolean errorHandler)
+{
+ xmlDocPtr source;
+ xmlDocPtr result;
+
+ source = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
+ base, 0, 0, 0, 0, 0,
+ entityResolver, errorHandler, 0, 0, 2);
+ result = xmljTransform (env, self, source);
+ return xmljGetNodeInstance (env, (xmlNodePtr) result);
+}
+
+/* GnomeTransformer.transformStreamToSAX */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformStreamToSAX
+(JNIEnv *env, jobject self, jobject in, jbyteArray detectBuffer,
+ jstring publicId, jstring systemId, jstring base,
+ jboolean entityResolver, jboolean errorHandler, jobject callback)
+{
+ xmlDocPtr source;
+
+ source = xmljParseDocument (env, self, in, detectBuffer, publicId, systemId,
+ base, 0, 0, 0, 0, 0,
+ entityResolver, errorHandler, 0, 0, 2);
+ xmljTransformToSAX (env, self, source, callback);
+}
+
+/* GnomeTransformer.transformDocToStream */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformDocToStream
+(JNIEnv *env, jobject self, jobject doc, jobject out)
+{
+ xmlDocPtr source;
+ xmlDocPtr result;
+
+ source = (xmlDocPtr) xmljGetNodeID (env, doc);
+ result = xmljTransform (env, self, source);
+ xmljSaveFileToJavaOutputStream (env, out, result,
+ (const char*) result->encoding);
+ xmlFreeDoc (result);
+}
+
+/* GnomeTransformer.transformDocToDoc */
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformDocToDoc
+(JNIEnv *env, jobject self, jobject doc)
+{
+ xmlDocPtr source;
+ xmlDocPtr result;
+
+ source = (xmlDocPtr) xmljGetNodeID (env, doc);
+ result = xmljTransform (env, self, source);
+ return xmljGetNodeInstance (env, (xmlNodePtr) result);
+}
+
+/* GnomeTransformer.transformDocToSAX */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_transformDocToSAX
+(JNIEnv *env, jobject self, jobject doc, jobject callback)
+{
+ xmlDocPtr source;
+
+ source = (xmlDocPtr) xmljGetNodeID (env, doc);
+ xmljTransformToSAX (env, self, source, callback);
+}
+
+/* GnomeTransformer.free */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformer_free (JNIEnv *env,
+ jobject self)
+{
+ xsltStylesheetPtr stylesheet;
+
+ stylesheet = xmljGetStylesheetID (env, self);
+ xsltFreeStylesheet (stylesheet);
+}
+
+/*
+ * --------------------------------------------------------------------------
+ * Native implementation for class
+ * gnu.xml.libxmlj.transform.GnomeTransformerFactory follows.
+ */
+
+/* GnomeTransformerFactory.freeLibxsltGlobal */
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_transform_GnomeTransformerFactory_freeLibxsltGlobal (
+ JNIEnv *env __attribute__((__unused__)),
+ jclass clazz __attribute__((__unused__)))
+{
+ xsltCleanupGlobals ();
+ xmlCleanupParser ();
+}
+
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_util.c b/libjava/classpath/native/jni/xmlj/xmlj_util.c
new file mode 100644
index 00000000000..498cb70923c
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_util.c
@@ -0,0 +1,301 @@
+/* xmlj_util.c
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "xmlj_util.h"
+#include "xmlj_error.h"
+#include <libxml/tree.h>
+#include <unistd.h>
+
+/* xmlChar->jstring cache */
+#ifdef XMLJ_STRING_CACHE
+#define XMLJ_STRING_CACHE_SIZE 1024
+xmlHashTablePtr xmljStringCache = NULL;
+
+void
+xmljHashDeallocate (void *data, xmlChar *name);
+
+void
+xmljHashDeallocate (void *data, xmlChar *name)
+{
+ /* NOOP */
+}
+#endif /* XMLJ_STRING_CACHE */
+
+jstring
+xmljNewString (JNIEnv * env, const xmlChar * text)
+{
+ jstring ret;
+
+ if (text == NULL || (*env)->ExceptionOccurred (env))
+ {
+ return NULL;
+ }
+#ifdef XMLJ_STRING_CACHE
+ if (xmljStringCache == NULL) /* Init cache */
+ {
+ xmljStringCache = xmlHashCreate (XMLJ_STRING_CACHE_SIZE);
+ }
+ ret = (jstring) xmlHashLookup (xmljStringCache, text);
+ if (ret == NULL)
+ {
+ ret = (*env)->NewStringUTF (env, (char *) text);
+ if (ret == NULL) /* Why? */
+ {
+ fprintf(stderr, "xmljNewString: ERROR: NewStringUTF returned null for \"%s\"\n", text);
+ fflush (stderr);
+ }
+ else
+ {
+ xmlHashAddEntry (xmljStringCache, text, ret);
+ }
+ }
+#else
+ ret = (*env)->NewStringUTF (env, (char *) text);
+ if (ret == NULL) /* Why? */
+ {
+ printf("xmljNewString: ERROR: NewStringUTF returned null for \"%s\"\n", text);
+ }
+#endif /* XMLJ_STRING_CACHE */
+ return ret;
+}
+
+void
+xmljClearStringCache ()
+{
+#ifdef XMLJ_STRING_CACHE
+ if (xmljStringCache != NULL)
+ {
+ xmlHashFree (xmljStringCache, &xmljHashDeallocate);
+ }
+#endif /* XMLJ_STRING_CACHE */
+}
+
+const xmlChar *
+xmljGetStringChars (JNIEnv * env, jstring text)
+{
+ const char *s_text;
+ xmlChar *x_text;
+
+ if (text == NULL)
+ {
+ return NULL;
+ }
+
+ s_text = (*env)->GetStringUTFChars (env, text, 0);
+ x_text = (s_text == NULL) ? NULL : xmlCharStrdup (s_text);
+ if (s_text != NULL && x_text == NULL)
+ {
+ /* TODO raise exception */
+ }
+ (*env)->ReleaseStringUTFChars (env, text, s_text);
+ return x_text;
+}
+
+const xmlChar *
+xmljGetPrefix (const xmlChar * qName)
+{
+ const xmlChar *localName;
+ const xmlChar *ret;
+ xmlChar **prefix;
+
+ prefix = (xmlChar **) malloc (sizeof (xmlChar *));
+ localName = xmlSplitQName2 (qName, prefix);
+ if (localName == NULL)
+ {
+ return NULL;
+ }
+ ret = *prefix;
+ free (prefix);
+ return ret;
+}
+
+const xmlChar *
+xmljGetLocalName (const xmlChar * qName)
+{
+ const xmlChar *localName;
+ xmlChar **prefix;
+
+ prefix = (xmlChar **) malloc (sizeof (xmlChar *));
+ localName = xmlSplitQName2 (qName, prefix);
+ if (localName == NULL)
+ {
+ return qName;
+ }
+ free (prefix);
+ return localName;
+}
+
+jmethodID xmljGetMethodID (JNIEnv *env,
+ jobject target,
+ const char *name,
+ const char *signature)
+{
+ jclass cls;
+ jmethodID ret;
+
+ cls = (*env)->GetObjectClass (env, target);
+ if (cls == NULL)
+ {
+ xmljThrowException (env,
+ "java/lang/ClassNotFoundException",
+ NULL);
+ return NULL;
+ }
+ ret = (*env)->GetMethodID (env,
+ cls,
+ name,
+ signature);
+ if (ret == NULL)
+ {
+ jclass clscls;
+ jmethodID nm;
+ jstring clsname;
+ const char *c_clsName;
+ char cat[512] = "[method signature too long]";
+
+ clscls = (*env)->FindClass (env, "java/lang/Class");
+ if (clscls == NULL)
+ {
+ return NULL;
+ }
+ nm = (*env)->GetMethodID (env, clscls, "getName",
+ "()Ljava/lang/String;");
+ if (nm == NULL)
+ {
+ return NULL;
+ }
+ clsname = (jstring) (*env)->CallObjectMethod (env,
+ (jobject)cls,
+ nm);
+ if (clsname == NULL)
+ {
+ return NULL;
+ }
+ c_clsName = (*env)->GetStringUTFChars (env, clsname, 0);
+ sprintf (cat, "%s.%s %s", c_clsName, name, signature);
+ xmljThrowException (env,
+ "java/lang/NoSuchMethodException",
+ cat);
+ (*env)->ReleaseStringUTFChars (env, clsname, c_clsName);
+ }
+ return ret;
+}
+
+void *
+xmljAsPointer (JNIEnv *env, jobject ptr)
+{
+ jclass cls;
+ jfieldID field;
+
+#if defined XMLJ_64BIT_POINTER
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ field = (*env)->GetFieldID (env, cls, "data", "J");
+ return (void *) (*env)->GetLongField (env, ptr, field);
+#else
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ field = (*env)->GetFieldID (env, cls, "data", "I");
+ return (void *) (*env)->GetIntField (env, ptr, field);
+#endif
+}
+
+jobject
+xmljAsField (JNIEnv *env, void * ptr)
+{
+ jclass cls;
+ jmethodID method;
+
+#if defined XMLJ_64BIT_POINTER
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(J)V");
+ return (*env)->NewObject (env, cls, method, (jlong) ptr);
+#else
+ cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
+ return (*env)->NewObject (env, cls, method, (jint) ptr);
+#endif
+}
+
+JNIEnv *
+xmljGetJNIEnv ()
+{
+ JavaVM **jvms;
+ jsize *jvm_count;
+ JavaVM *jvm;
+ JNIEnv **envs;
+ JNIEnv *env;
+
+ jvms = (JavaVM **) malloc (sizeof (JavaVM *));
+ if (!jvms)
+ {
+ return NULL;
+ }
+ jvm_count = (jsize *) malloc (sizeof (jsize));
+ if (!jvm_count)
+ {
+ free (jvms);
+ return NULL;
+ }
+ if (JNI_GetCreatedJavaVMs (jvms, 1, jvm_count))
+ {
+ free (jvms);
+ free (jvm_count);
+ return NULL;
+ }
+ jvm = *jvms;
+ envs = (JNIEnv **) malloc (sizeof (JNIEnv *));
+ if (!envs)
+ {
+ free (jvms);
+ free (jvm_count);
+ return NULL;
+ }
+ (*jvm)->AttachCurrentThread (jvm, (void **) envs, NULL);
+ (*jvm)->GetEnv (jvm, (void **) envs, JNI_VERSION_1_2);
+ if (envs)
+ {
+ env = *envs;
+ free (envs);
+ }
+ else
+ {
+ env = NULL;
+ }
+ free (jvms);
+ free (jvm_count);
+ return env;
+}
+
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_util.h b/libjava/classpath/native/jni/xmlj/xmlj_util.h
new file mode 100644
index 00000000000..7bbe78b8e1f
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_util.h
@@ -0,0 +1,69 @@
+/* xmlj_util.h -
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef XMLJ_UTIL_H
+#define XMLJ_UTIL_H
+
+#if defined __64BIT__ || defined __LP64 || defined _LP64 || defined __LP64__ || defined _ADDR64
+# define XMLJ_64BIT_POINTER 1
+#endif
+
+#include <jni.h>
+#include <libxml/xmlstring.h>
+
+jstring xmljNewString (JNIEnv *, const xmlChar *);
+
+void xmljClearStringCache (void);
+
+const xmlChar *xmljGetStringChars (JNIEnv *, jstring);
+
+const xmlChar *xmljGetPrefix (const xmlChar * qName);
+
+const xmlChar *xmljGetLocalName (const xmlChar * qName);
+
+jmethodID xmljGetMethodID (JNIEnv *env,
+ jobject target,
+ const char *name,
+ const char *signature);
+
+void * xmljAsPointer (JNIEnv *env, jobject field);
+
+jobject xmljAsField (JNIEnv *env, void * ptr);
+
+JNIEnv * xmljGetJNIEnv (void);
+
+#endif /* !defined XMLJ_UTIL_H */
diff --git a/libjava/classpath/native/jni/xmlj/xmlj_xpath.c b/libjava/classpath/native/jni/xmlj/xmlj_xpath.c
new file mode 100644
index 00000000000..6d014cefc91
--- /dev/null
+++ b/libjava/classpath/native/jni/xmlj/xmlj_xpath.c
@@ -0,0 +1,625 @@
+/* xmlj_xpath.c -
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "gnu_xml_libxmlj_dom_GnomeDocument.h"
+#include "gnu_xml_libxmlj_dom_GnomeElement.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathExpression.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathNodeList.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathNSResolver.h"
+#include "gnu_xml_libxmlj_dom_GnomeXPathResult.h"
+#include "xmlj_node.h"
+#include "xmlj_util.h"
+#include <libxml/xpath.h>
+
+/* Local function prototypes */
+
+xmlXPathContextPtr
+xmljCreateXPathContextPtr (xmlNodePtr node);
+
+jobject
+xmljGetXPathResult (JNIEnv *env, xmlXPathObjectPtr obj);
+
+jobject
+xmljGetXPathNodeList (JNIEnv *env, xmlXPathObjectPtr obj);
+
+xmlXPathObjectPtr
+xmljGetXPathObjectID (JNIEnv *env, jobject obj);
+
+/**
+ * Creates an XPath context for the given node.
+ */
+xmlXPathContextPtr
+xmljCreateXPathContextPtr (xmlNodePtr node)
+{
+ xmlXPathContextPtr ctx;
+
+ ctx = xmlXPathNewContext (node->doc);
+ ctx->node = node;
+ return ctx;
+}
+
+/**
+ * Converts an xmlXPathObjectPtr to a Java XPathResult.
+ */
+jobject
+xmljGetXPathResult (JNIEnv *env, xmlXPathObjectPtr obj)
+{
+ jclass cls;
+ jmethodID method;
+ jobject ret;
+ jobject val;
+
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeXPathResult");
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ method = (*env)->GetMethodID (env, cls, "<init>", "(Ljava/lang/Object;)V");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ val = xmljAsField (env, obj);
+ ret = (*env)->NewObject (env, cls, method, val);
+
+ return ret;
+}
+
+/**
+ * Converts an xmlXPathObjectPtr to a Java XPathNodeList.
+ */
+jobject
+xmljGetXPathNodeList (JNIEnv *env, xmlXPathObjectPtr obj)
+{
+ jclass cls;
+ jmethodID method;
+ jobject ret;
+ jobject val;
+
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeXPathNodeList");
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ method = (*env)->GetMethodID (env, cls, "<init>", "(Ljava/lang/Object;)V");
+ if (method == NULL)
+ {
+ return NULL;
+ }
+ val = xmljAsField (env, obj);
+ ret = (*env)->NewObject (env, cls, method, val);
+
+ return ret;
+}
+
+xmlXPathObjectPtr
+xmljGetXPathObjectID (JNIEnv *env, jobject obj)
+{
+ jclass cls;
+ jfieldID field;
+ jobject val;
+ xmlXPathObjectPtr ret;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ if (cls == NULL)
+ {
+ return NULL;
+ }
+ field = (*env)->GetFieldID (env, cls, "obj", "Ljava/lang/Object;");
+ if (field == NULL)
+ {
+ return NULL;
+ }
+ val = (*env)->GetObjectField (env, obj, field);
+ ret = (xmlXPathObjectPtr) xmljAsPointer (env, val);
+
+ return ret;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_evaluate (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jstring expression,
+ jobject contextNode,
+ jobject resolver,
+ jshort type,
+ jobject result)
+{
+ const xmlChar *str;
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ str = xmljGetStringChars (env, expression);
+ node = xmljGetNodeID (env, contextNode);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ ctx = xmljCreateXPathContextPtr (node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathEval (str, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ xmlFree ((xmlChar *) str);
+ return xmljGetXPathResult (env, eval);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathExpression_init (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jstring expression)
+{
+ const xmlChar *str;
+ xmlXPathCompExprPtr ptr;
+
+ str = xmljGetStringChars (env, expression);
+ ptr = xmlXPathCompile (str);
+ xmlFree ((xmlChar *) str);
+ return xmljAsField (env, ptr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathExpression_free (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject ptr)
+{
+ xmlXPathCompExprPtr expr;
+
+ expr = (xmlXPathCompExprPtr) xmljAsPointer (env, ptr);
+ xmlXPathFreeCompExpr (expr);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathExpression_doEvaluate (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject ptr,
+ jobject contextNode,
+ jshort type,
+ jobject result)
+{
+ xmlXPathCompExprPtr expr;
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ expr = (xmlXPathCompExprPtr) xmljAsPointer (env, ptr);
+ node = xmljGetNodeID (env, contextNode);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ ctx = xmljCreateXPathContextPtr (node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathCompiledEval (expr, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ return xmljGetXPathResult (env, eval);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_free (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject obj)
+{
+ xmlXPathFreeObject ((xmlXPathObjectPtr) xmljAsPointer (env, obj));
+}
+
+JNIEXPORT jshort JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getResultType (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ switch (obj->type)
+ {
+ case XPATH_UNDEFINED:
+ return 0; /* ANY_TYPE */
+ case XPATH_NUMBER:
+ return 1; /* NUMBER_TYPE */
+ case XPATH_STRING:
+ return 2; /* STRING_TYPE */
+ case XPATH_BOOLEAN:
+ return 3; /* BOOLEAN_TYPE */
+ case XPATH_NODESET:
+ return 6; /* UNORDERED_NODE_SNAPSHOT_TYPE */
+ case XPATH_POINT:
+ case XPATH_RANGE:
+ case XPATH_LOCATIONSET:
+ case XPATH_USERS:
+ case XPATH_XSLT_TREE:
+ /* TODO */
+ default:
+ return -1; /* TODO */
+ }
+}
+
+JNIEXPORT jdouble JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getNumberValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return 0.0;
+ }
+ return obj->floatval;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getStringValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ return xmljNewString (env, obj->stringval);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getBooleanValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ return obj->boolval;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getSingleNodeValue (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval->nodeNr > 0)
+ {
+ return xmljGetNodeInstance (env, obj->nodesetval->nodeTab[0]);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+JNIEXPORT jboolean JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getInvalidIteratorState (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ return 0; /* TODO */
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_getSnapshotLength (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return -1;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return -1;
+ }
+ return obj->nodesetval->nodeNr;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_iterateNext (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ return NULL; /* TODO */
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathResult_snapshotItem (JNIEnv *env,
+ jobject self,
+ jint index)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval->nodeNr > 0)
+ {
+ return xmljGetNodeInstance (env, obj->nodesetval->nodeTab[index]);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/* -- GnomeXPathNodeList -- */
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getElementsByTagName (JNIEnv *env,
+ jobject self,
+ jstring name)
+{
+ return Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagName (env,
+ self,
+ name);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagName (JNIEnv *env,
+ jobject self,
+ jstring name)
+{
+ const xmlChar *s_name;
+ const xmlChar *format;
+ xmlChar expr[256];
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ node = xmljGetNodeID (env, self);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ s_name = xmljGetStringChars (env, name);
+ if (xmlStrEqual (s_name, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_name) == -1)
+ {
+ return NULL;
+ }
+ }
+ xmlFree ((xmlChar *) s_name);
+ ctx = xmljCreateXPathContextPtr (node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathEval (expr, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ return xmljGetXPathNodeList (env, eval);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeDocument_getElementsByTagNameNS (JNIEnv *env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ return Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagNameNS (env,
+ self,
+ uri,
+ localName);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeElement_getElementsByTagNameNS (JNIEnv *env,
+ jobject self,
+ jstring uri,
+ jstring localName)
+{
+ const xmlChar *s_uri;
+ const xmlChar *s_localName;
+ const xmlChar *format;
+ xmlChar expr[256];
+ xmlNodePtr node;
+ xmlXPathContextPtr ctx;
+ xmlXPathObjectPtr eval = NULL;
+
+ node = xmljGetNodeID (env, self);
+ if (node == NULL)
+ {
+ return NULL;
+ }
+ s_uri = xmljGetStringChars (env, uri);
+ s_localName = xmljGetStringChars (env, localName);
+ if (uri == NULL)
+ {
+ /* namespace URI is empty */
+ if (xmlStrEqual (s_localName, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='' and node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='' and local-name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_localName) == -1)
+ {
+ return NULL;
+ }
+ }
+ }
+ else if (xmlStrEqual (s_uri, BAD_CAST "*"))
+ {
+ /* matches all namespaces */
+ if (xmlStrEqual (s_localName, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[local-name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_localName) == -1)
+ {
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ if (xmlStrEqual (s_localName, BAD_CAST "*"))
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='%s' and node-type()=1]");
+ if (xmlStrPrintf (expr, 256, format, s_uri) == -1)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ format = xmlCharStrdup ("descendant-or-self::*[namespace-uri()='%s' and local-name()='%s']");
+ if (xmlStrPrintf (expr, 256, format, s_uri, s_localName) == -1)
+ {
+ return NULL;
+ }
+ }
+ }
+ xmlFree ((xmlChar *) s_uri);
+ xmlFree ((xmlChar *) s_localName);
+ ctx = xmljCreateXPathContextPtr (node);
+ if (ctx != NULL)
+ {
+ eval = xmlXPathEval (expr, ctx);
+ xmlXPathFreeContext (ctx);
+ }
+ return xmljGetXPathNodeList (env, eval);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathNodeList_free (JNIEnv *env,
+ jobject self
+ __attribute__((__unused__)),
+ jobject obj)
+{
+ xmlXPathFreeObject ((xmlXPathObjectPtr) xmljAsPointer (env, obj));
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathNodeList_getLength (JNIEnv *env,
+ jobject self)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return 0;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return 0;
+ }
+ return obj->nodesetval->nodeNr;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_xml_libxmlj_dom_GnomeXPathNodeList_item (JNIEnv *env,
+ jobject self,
+ jint index)
+{
+ xmlXPathObjectPtr obj;
+
+ obj = xmljGetXPathObjectID (env, self);
+ if (obj == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval == NULL)
+ {
+ return NULL;
+ }
+ if (obj->nodesetval->nodeNr > 0)
+ {
+ return xmljGetNodeInstance (env, obj->nodesetval->nodeTab[index]);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
diff --git a/libjava/classpath/native/target/.cvsignore b/libjava/classpath/native/target/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/target/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/target/Linux/.cvsignore b/libjava/classpath/native/target/Linux/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/target/Linux/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/target/Linux/Makefile.am b/libjava/classpath/native/target/Linux/Makefile.am
new file mode 100644
index 00000000000..bd267dc7f91
--- /dev/null
+++ b/libjava/classpath/native/target/Linux/Makefile.am
@@ -0,0 +1,10 @@
+## Input file for automake to generate the Makefile.in used by configure
+
+EXTRA_DIST = \
+target_native_io.h \
+target_native_misc.h \
+target_native.h \
+target_native_math_float.h \
+target_native_network.h \
+target_native_file.h \
+target_native_math_int.h
diff --git a/libjava/classpath/native/target/Linux/target_native.h b/libjava/classpath/native/target/Linux/target_native.h
new file mode 100644
index 00000000000..4e1d5136d55
--- /dev/null
+++ b/libjava/classpath/native/target/Linux/target_native.h
@@ -0,0 +1,79 @@
+/* ???.h - ???
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: Linux target global defintions
+Systems : all
+*/
+
+#ifndef __TARGET_NATIVE__
+#define __TARGET_NATIVE__
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* include rest of definitions from generic file (do not move it to
+ another position!) */
+#include "target_generic.h"
+
+#endif /* __TARGET_NATIVE__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/Linux/target_native_file.h b/libjava/classpath/native/target/Linux/target_native_file.h
new file mode 100644
index 00000000000..0c40b4471b6
--- /dev/null
+++ b/libjava/classpath/native/target/Linux/target_native_file.h
@@ -0,0 +1,79 @@
+/* ???.h - ???
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: Linux target defintions of file functions
+Systems : all
+*/
+
+#ifndef __TARGET_NATIVE_FILE__
+#define __TARGET_NATIVE_FILE__
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* include rest of definitions from generic file (do not move it to
+ another position!) */
+#include "target_generic_file.h"
+
+#endif /* __TARGET_NATIVE_FILE__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/Linux/target_native_io.h b/libjava/classpath/native/target/Linux/target_native_io.h
new file mode 100644
index 00000000000..03f43adf579
--- /dev/null
+++ b/libjava/classpath/native/target/Linux/target_native_io.h
@@ -0,0 +1,78 @@
+/* ???.h - ???
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: Linux target defintions of miscellaneous functions
+Systems : all
+*/
+
+#ifndef __TARGET_NATIVE_IO__
+#define __TARGET_NATIVE_IO__
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* include rest of definitions from generic file (do not move it to
+ another position!) */
+#include "target_generic_io.h"
+
+#endif /* __TARGET_NATIVE_MISC__ */
+
+/* end of file */
diff --git a/libjava/classpath/native/target/Linux/target_native_math_float.h b/libjava/classpath/native/target/Linux/target_native_math_float.h
new file mode 100644
index 00000000000..0f3455d2ae9
--- /dev/null
+++ b/libjava/classpath/native/target/Linux/target_native_math_float.h
@@ -0,0 +1,80 @@
+/* ???.h - ???
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: Linux target defintions of float/double constants/
+ macros/functions
+Systems : all
+*/
+
+#ifndef __TARGET_NATIVE_MATH_FLOAT__
+#define __TARGET_NATIVE_MATH_FLOAT__
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* include rest of definitions from generic file (do not move it to
+ another position!) */
+#include "target_generic_math_float.h"
+
+#endif /* __TARGET_NATIVE_MATH_FLOAT__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/Linux/target_native_math_int.h b/libjava/classpath/native/target/Linux/target_native_math_int.h
new file mode 100644
index 00000000000..4c5fc671d05
--- /dev/null
+++ b/libjava/classpath/native/target/Linux/target_native_math_int.h
@@ -0,0 +1,80 @@
+/* ???.h - ???
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: Linux target defintions of int/int64 constants/
+ macros/functions
+Systems : all
+*/
+
+#ifndef __TARGET_NATIVE_MATH_INT__
+#define __TARGET_NATIVE_MATH_INT__
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* include rest of definitions from generic file (do not move it to
+ another position!) */
+#include "target_generic_math_int.h"
+
+#endif /* __TARGET_NATIVE_MATH_INT__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/Linux/target_native_misc.h b/libjava/classpath/native/target/Linux/target_native_misc.h
new file mode 100644
index 00000000000..00bc7ac8da8
--- /dev/null
+++ b/libjava/classpath/native/target/Linux/target_native_misc.h
@@ -0,0 +1,79 @@
+/* ???.h - ???
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: Linux target defintions of miscellaneous functions
+Systems : all
+*/
+
+#ifndef __TARGET_NATIVE_MISC__
+#define __TARGET_NATIVE_MISC__
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* include rest of definitions from generic file (do not move it to
+ another position!) */
+#include "target_generic_misc.h"
+
+#endif /* __TARGET_NATIVE_MISC__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/Linux/target_native_network.h b/libjava/classpath/native/target/Linux/target_native_network.h
new file mode 100644
index 00000000000..23f9d0a6286
--- /dev/null
+++ b/libjava/classpath/native/target/Linux/target_native_network.h
@@ -0,0 +1,79 @@
+/* ???.h - ???
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: Linux target defintions of network functions
+Systems : all
+*/
+
+#ifndef __TARGET_NATIVE_NETWORK__
+#define __TARGET_NATIVE_NETWORK__
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* include rest of definitions from generic file (do not move it to
+ another position!) */
+#include "target_generic_network.h"
+
+#endif /* __TARGET_NATIVE_NETWORK__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/Makefile.am b/libjava/classpath/native/target/Makefile.am
new file mode 100644
index 00000000000..ba0ad791919
--- /dev/null
+++ b/libjava/classpath/native/target/Makefile.am
@@ -0,0 +1,5 @@
+## Input file for automake to generate the Makefile.in used by configure
+
+SUBDIRS = Linux generic
+
+EXTRA_DIST = readme.txt
diff --git a/libjava/classpath/native/target/generic/.cvsignore b/libjava/classpath/native/target/generic/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/target/generic/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/target/generic/Makefile.am b/libjava/classpath/native/target/generic/Makefile.am
new file mode 100644
index 00000000000..bc8413c3a75
--- /dev/null
+++ b/libjava/classpath/native/target/generic/Makefile.am
@@ -0,0 +1,10 @@
+## Input file for automake to generate the Makefile.in used by configure
+
+EXTRA_DIST = \
+target_generic_io.h \
+target_generic_misc.h \
+target_generic.h \
+target_generic_math_float.h \
+target_generic_network.h \
+target_generic_file.h \
+target_generic_math_int.h
diff --git a/libjava/classpath/native/target/generic/target_generic.h b/libjava/classpath/native/target/generic/target_generic.h
new file mode 100644
index 00000000000..e4ddf5c3bfa
--- /dev/null
+++ b/libjava/classpath/native/target/generic/target_generic.h
@@ -0,0 +1,171 @@
+/* generic_math_int64.h - Native methods for 64bit math operations
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: generic target global defintions
+Systems : all
+*/
+
+#ifndef __TARGET_GENERIC__
+#define __TARGET_GENERIC__
+
+/* check if target_native_network.h included */
+#ifndef __TARGET_NATIVE__
+ #error Do NOT INCLUDE generic target files! Include the corresponding native target files instead!
+#endif
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include "config.h"
+
+#include <stdlib.h>
+#include <errno.h>
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+#define TARGET_NATIVE_OK 1
+#define TARGET_NATIVE_ERROR 0
+
+#ifndef TARGET_NATIVE_ERROR_PERMISION_DENIED
+ #define TARGET_NATIVE_ERROR_PERMISION_DENIED EACCES
+#endif
+#ifndef TARGET_NATIVE_ERROR_BAD_FILE_DESCRIPTOR
+ #define TARGET_NATIVE_ERROR_BAD_FILE_DESCRIPTOR EBADF
+#endif
+#ifndef TARGET_NATIVE_ERROR_FILE_EXISTS
+ #define TARGET_NATIVE_ERROR_FILE_EXISTS EEXIST
+#endif
+#ifndef TARGET_NATIVE_ERROR_INPUT_OUTPUT
+ #define TARGET_NATIVE_ERROR_INPUT_OUTPUT EIO
+#endif
+#ifndef TARGET_NATIVE_ERROR_TOO_MANY_OPEN_FILES
+ #define TARGET_NATIVE_ERROR_TOO_MANY_OPEN_FILES EMFILE
+#endif
+#ifndef TARGET_NATIVE_ERROR_FILENAME_TO_LONG
+ #define TARGET_NATIVE_ERROR_FILENAME_TO_LONG ENAMETOOLONG
+#endif
+#ifndef TARGET_NATIVE_ERROR_NO_SUCH_DEVICE
+ #define TARGET_NATIVE_ERROR_NO_SUCH_DEVICE ENODEV
+#endif
+#ifndef TARGET_NATIVE_ERROR_NO_SUCH_FILE
+ #define TARGET_NATIVE_ERROR_NO_SUCH_FILE ENOENT
+#endif
+#ifndef TARGET_NATIVE_ERROR_NO_SPACE_LEFT
+ #define TARGET_NATIVE_ERROR_NO_SPACE_LEFT ENOSPC
+#endif
+#ifndef TARGET_NATIVE_ERROR_DIRECTORY_NOT_EMPTY
+ #define TARGET_NATIVE_ERROR_DIRECTORY_NOT_EMPTY ENOTEMPTY
+#endif
+#ifndef TARGET_NATIVE_ERROR_OPERATION_NOT_PERMITTED
+ #define TARGET_NATIVE_ERROR_OPERATION_NOT_PERMITTED EPERM
+#endif
+#ifndef TARGET_NATIVE_ERROR_READ_ONLY_FILE_SYSTEM
+ #define TARGET_NATIVE_ERROR_READ_ONLY_FILE_SYSTEM EROFS
+#endif
+#ifndef TARGET_NATIVE_ERROR_INVALID_SEEK
+ #define TARGET_NATIVE_ERROR_INVALID_SEEK ESPIPE
+#endif
+#ifndef TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL
+ #define TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL EINTR
+#endif
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_LAST_ERROR
+* Purpose : return last error code
+* Input : -
+* Output : -
+* Return : error code
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_LAST_ERROR
+ #include <errno.h>
+ #define TARGET_NATIVE_LAST_ERROR() \
+ errno
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_LAST_ERROR_STRING
+* Purpose : return last error string
+* Input : -
+* Output : -
+* Return : error string (read only!)
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_LAST_ERROR_STRING
+ #include <string.h>
+ #include <errno.h>
+ #define TARGET_NATIVE_LAST_ERROR_STRING() \
+ strerror(errno)
+#endif
+
+#ifndef TARGET_NATIVE_LAST_ERROR_STRING_FORMAT
+ #include <string.h>
+ #include <errno.h>
+ #define TARGET_NATIVE_LAST_ERROR_STRING_FORMAT(buffer,bufferSize,format) \
+ do { \
+ sprintf(buffer,format); \
+ strcat(" (error: "); \
+ strcat(strerror(errno)); \
+ strcat(")"); \
+ } while (0)
+#endif
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TARGET_GENERIC__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/generic/target_generic_file.h b/libjava/classpath/native/target/generic/target_generic_file.h
new file mode 100644
index 00000000000..cd90e733ced
--- /dev/null
+++ b/libjava/classpath/native/target/generic/target_generic_file.h
@@ -0,0 +1,844 @@
+/* target_generic_file - Native methods for file operations
+ Copyright (C) 1998, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: generic target defintions of file functions
+Systems : all
+*/
+
+#ifndef __TARGET_GENERIC_FILE__
+#define __TARGET_GENERIC_FILE__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* check if target_native_file.h included */
+#ifndef __TARGET_NATIVE_FILE__
+ #error Do NOT INCLUDE generic target files! Include the corresponding native target files instead!
+#endif
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include "config.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <fcntl.h>
+
+#include "target_native.h"
+#include "target_native_math_int.h"
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_NONE
+ #define TARGET_NATIVE_FILE_FILEFLAG_NONE 0
+#endif
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_CREATE
+ #define TARGET_NATIVE_FILE_FILEFLAG_CREATE O_CREAT
+#endif
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_CREATE_FORCE
+ #define TARGET_NATIVE_FILE_FILEFLAG_CREATE_FORCE (O_CREAT|O_EXCL)
+#endif
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_READ
+ #define TARGET_NATIVE_FILE_FILEFLAG_READ O_RDONLY
+#endif
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_WRITE
+ #define TARGET_NATIVE_FILE_FILEFLAG_WRITE O_WRONLY
+#endif
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_READWRITE
+ #define TARGET_NATIVE_FILE_FILEFLAG_READWRITE O_RDWR
+#endif
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_TRUNCATE
+ #define TARGET_NATIVE_FILE_FILEFLAG_TRUNCATE O_TRUNC
+#endif
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_APPEND
+ #define TARGET_NATIVE_FILE_FILEFLAG_APPEND O_APPEND
+#endif
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_SYNC
+ #if !defined (O_SYNC) && defined (O_FSYNC)
+ #define TARGET_NATIVE_FILE_FILEFLAG_SYNC O_FSYNC
+ #else
+ #define TARGET_NATIVE_FILE_FILEFLAG_SYNC O_SYNC
+ #endif
+#endif
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_DSYNC
+ #ifdef O_DSYNC
+ #define TARGET_NATIVE_FILE_FILEFLAG_DSYNC 0
+ #else
+ #define TARGET_NATIVE_FILE_FILEFLAG_DSYNC TARGET_NATIVE_FILE_FILEFLAG_SYNC
+ #endif
+#endif
+#ifndef TARGET_NATIVE_FILE_FILEFLAG_BINARY
+ #define TARGET_NATIVE_FILE_FILEFLAG_BINARY O_BINARY
+#endif
+
+#ifndef TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL
+ #define TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
+#endif
+
+#ifndef TARGET_NATIVE_FILE_FILEPERMISSION_PRIVATE
+ #define TARGET_NATIVE_FILE_FILEPERMISSION_PRIVATE (S_IRUSR | S_IWUSR)
+#endif
+
+#ifndef TARGET_NATIVE_FILE_FILEPERMISSION_READONLY
+ #define TARGET_NATIVE_FILE_FILEPERMISSION_READONLY (~(S_IWRITE|S_IWGRP|S_IWOTH))
+#endif
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_OPEN
+* Purpose : open a file
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : file is created if it does not exist
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_OPEN
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #define TARGET_NATIVE_FILE_OPEN(filename,filedescriptor,flags,permissions,result) \
+ do { \
+ filedescriptor=open(filename, \
+ flags, \
+ permissions \
+ ); \
+ if (filedescriptor >= 0) \
+ fcntl (filedescriptor,F_SETFD,FD_CLOEXEC); \
+ result=(filedescriptor>=0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_OPEN_CREATE
+* Purpose : create a file
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : file is created if it does not exist
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_OPEN_CREATE
+ #define TARGET_NATIVE_FILE_OPEN_CREATE(filename,filedescriptor,result) \
+ TARGET_NATIVE_FILE_OPEN(filename,\
+ filedescriptor,\
+ TARGET_NATIVE_FILE_FILEFLAG_CREATE_FORCE, \
+ TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL, \
+ result \
+ )
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_OPEN_READ
+* Purpose : open an existing file for reading
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_OPEN_READ
+ #define TARGET_NATIVE_FILE_OPEN_READ(filename,filedescriptor,result) \
+ TARGET_NATIVE_FILE_OPEN(filename, \
+ filedescriptor,\
+ TARGET_NATIVE_FILE_FILEFLAG_READ, \
+ TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL, \
+ result \
+ )
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_OPEN_WRITE
+* Purpose : open an existing file for writing
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_OPEN_WRITE
+ #define TARGET_NATIVE_FILE_OPEN_WRITE(filename,filedescriptor,result) \
+ TARGET_NATIVE_FILE_OPEN(filename, \
+ filedescriptor, \
+ TARGET_NATIVE_FILE_FILEFLAG_WRITE, \
+ TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL, \
+ result \
+ )
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_OPEN_READWRITE
+* Purpose : create/open a file for reading/writing
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : file is created if it does not exist
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_OPEN_READWRITE
+ #define TARGET_NATIVE_FILE_OPEN_READWRITE(filename,filedescriptor,result) \
+ TARGET_NATIVE_FILE_OPEN(filename, \
+ filedescriptor, \
+ TARGET_NATIVE_FILE_FILEFLAG_READWRITE, \
+ TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL, \
+ result \
+ )
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_OPEN_READWRITE
+* Purpose : create/open a file for append
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : file is created if it does not exist
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_OPEN_APPEND
+ #define TARGET_NATIVE_FILE_OPEN_APPEND(filename,filedescriptor,result) \
+ TARGET_NATIVE_FILE_OPEN_APPEND(filename, \
+ filedescriptor, \
+ TARGET_NATIVE_FILE_FILEFLAG_CREATE_FORCE|TARGET_NATIVE_FILE_FILEFLAG_APPEND, \
+ TARGET_NATIVE_FILE_FILEPERMISSION_NORMAL, \
+ result \
+ )
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_CLOSE
+* Purpose : close a file
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_CLOSE
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_CLOSE(filedescriptor,result) \
+ do { \
+ result=(close(filedescriptor)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_VALID_FILE_DESCRIPTOR
+* Purpose : check if file-descriptor is valid
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_VALID_FILE_DESCRIPTOR
+ #if defined(HAVE_FCNTL)
+ #include <unistd.h>
+ #include <fcntl.h>
+ #define TARGET_NATIVE_FILE_VALID_FILE_DESCRIPTOR(filedescriptor,result) \
+ do { \
+ result=(fcntl(filedescriptor,F_GETFL,0)!=-1)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while(0)
+ #elif defined(HAVE_FSTAT)
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_VALID_FILE_DESCRIPTOR(filedescriptor,result) \
+ do { \
+ struct stat __stat; \
+ \
+ result=(fstat(filedescriptor,&__stat)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while(0)
+ #else
+ #error fcntl() nor fstat() available for checking if file descriptor is valid
+ #endif
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_TELL
+* Purpose : get current file position
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_TELL
+ #include <sys/types.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_TELL(filedescriptor,offset,result) \
+ do { \
+ offset=lseek(filedescriptor,TARGET_NATIVE_MATH_INT_INT64_CONST_0,SEEK_CUR); \
+ result=((offset)!=(off_t)-1)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_SEEK_BEGIN|CURRENT|END
+* Purpose : set file position relativ to begin/current/end
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_SEEK_BEGIN
+ #include <sys/types.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_SEEK_BEGIN(filedescriptor,offset,newoffset,result) \
+ do { \
+ newoffset=lseek(filedescriptor,offset,SEEK_SET); \
+ result=((newoffset)!=(off_t)-1)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_FILE_SEEK_CURRENT
+ #include <sys/types.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_SEEK_CURRENT(filedescriptor,offset,newoffset,result) \
+ do { \
+ newoffset=lseek(filedescriptor,offset,SEEK_CUR); \
+ result=((newoffset)!=(off_t)-1)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_FILE_SEEK_END
+ #include <sys/types.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_SEEK_END(filedescriptor,offset,newoffset,result) \
+ do { \
+ newoffset=lseek(filedescriptor,offset,SEEK_END); \
+ result=((newoffset)!=(off_t)-1)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_TRUNCATE
+* Purpose : truncate a file
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_TRUNCATE
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_TRUNCATE(filedescriptor,offset,result) \
+ do { \
+ result=(ftruncate(filedescriptor,offset)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_SIZE
+* Purpose : get size of file (in bytes)
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_SIZE
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_SIZE(filedescriptor,length,result) \
+ do { \
+ struct stat __statBuffer; \
+ \
+ result=(fstat(filedescriptor,&__statBuffer)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ length=TARGET_NATIVE_MATH_INT_INT32_TO_INT64(__statBuffer.st_size); \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_AVAILABLE
+* Purpose : get available bytes for read
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_AVAILABLE
+ #ifdef HAVE_SYS_IOCTL_H
+ #define BSD_COMP /* Get FIONREAD on Solaris2 */
+ #include <sys/ioctl.h>
+ #endif
+ #ifdef HAVE_SYS_FILIO_H /* Get FIONREAD on Solaris 2.5 */
+ #include <sys/filio.h>
+ #endif
+ #if defined (FIONREAD)
+ #define TARGET_NATIVE_FILE_AVAILABLE(filedescriptor,length,result) \
+ do { \
+ ssize_t __n; \
+ \
+ result=(ioctl(filedescriptor,FIONREAD,(char*)&__n)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ length=TARGET_NATIVE_MATH_INT_INT32_TO_INT64(__n); \
+ } while (0)
+ #elif defined(HAVE_FSTAT)
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_AVAILABLE(filedescriptor,length,result) \
+ do { \
+ struct stat __statBuffer; \
+ off_t __n; \
+ \
+ length=0; \
+ \
+ if ((fstat(filedescriptor,&__statBuffer)==0) && S_ISREG(__statBuffer.st_mode)) \
+ { \
+ __n=(lseek(filedescriptor,0,SEEK_CUR)); \
+ if (__n!=-1) \
+ { \
+ length=TARGET_NATIVE_MATH_INT_INT32_TO_INT64(__statBuffer.st_size-__n); \
+ result=TARGET_NATIVE_OK; \
+ } \
+ else \
+ { \
+ result=TARGET_NATIVE_ERROR; \
+ } \
+ } \
+ else \
+ { \
+ result=TARGET_NATIVE_ERROR; \
+ } \
+ } while (0)
+ #elif defined(HAVE_SELECT)
+ #include <string.h>
+ #include <sys/select.h>
+ #define TARGET_NATIVE_FILE_AVAILABLE(filedescriptor,length,result) \
+ do { \
+ fd_set __filedescriptset; \
+ struct timeval __timeval; \
+ \
+ length=0; \
+ \
+ FD_ZERO(&__filedescriptset); \
+ FD_SET(filedescriptor,&__filedescriptset); \
+ memset(&__timeval,0,sizeof(__timeval)); \
+ switch (select(filedescriptor+1,&__filedescriptset,NULL,NULL,&__timeval)==0) \
+ { \
+ case -1: result=TARGET_NATIVE_ERROR; break; \
+ case 0: length=JNI_JLONG_CONST_0; result=TARGET_NATIVE_OK; break; \
+ default: length=JNI_JLONG_CONST_1; result=TARGET_NATIVE_OK; break; \
+ } \
+ } while (0)
+ #else
+ #define TARGET_NATIVE_FILE_AVAILABLE(filedescriptor,length,result) \
+ do { \
+ errno=TARGET_NATIVE_ERROR_OPERATION_NOT_PERMITTED; \
+ length=0; \
+ result=TARGET_NATIVE_ERROR; \
+ } while (0)
+ #endif
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_READ|WRITE
+* Purpose : read/write from/to frile
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_READ
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_READ(filedescriptor,buffer,length,bytesRead,result) \
+ do { \
+ bytesRead=read(filedescriptor,buffer,length); \
+ result=(bytesRead!=-1)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_FILE_WRITE
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_WRITE(filedescriptor,buffer,length,bytesWritten,result) \
+ do { \
+ bytesWritten=write(filedescriptor,buffer,length); \
+ result=(bytesWritten!=-1)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_SET_MODE_READONLY
+* Purpose : set file mode to read-only
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_SET_MODE_READONLY
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_SET_MODE_READONLY(filename,result) \
+ do { \
+ struct stat __statBuffer; \
+ \
+ if (stat(filename,&__statBuffer)==0) { \
+ result=(chmod(filename,__statBuffer.st_mode & TARGET_NATIVE_FILE_FILEPERMISSION_READONLY)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } else { \
+ result=TARGET_NATIVE_ERROR; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_EXISTS
+* Purpose : check if file exists
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_EXISTS
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_EXISTS(filename,result) \
+ do { \
+ struct stat __statBuffer; \
+ \
+ result=(stat(filename,&__statBuffer)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_IS_FILE
+* Purpose : check if directory entry is a file
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_IS_FILE
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_IS_FILE(filename,result) \
+ do { \
+ struct stat __statBuffer; \
+ \
+ result=((stat(filename,&__statBuffer)==0) && (S_ISREG(__statBuffer.st_mode)))?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_IS_DIRECTORY
+* Purpose : check if directory entry is a directory
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_IS_DIRECTORY
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_IS_DIRECTORY(filename,result) \
+ do { \
+ struct stat __statBuffer; \
+ \
+ result=((stat(filename,&__statBuffer)==0) && (S_ISDIR(__statBuffer.st_mode)))?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_GET_LAST_MODIFIED
+* Purpose : get last modification time of file (milliseconds)
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_GET_LAST_MODIFIED
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_GET_LAST_MODIFIED(filename,time,result) \
+ do { \
+ struct stat __statBuffer; \
+ \
+ time=TARGET_NATIVE_MATH_INT_INT64_CONST_0; \
+ if (stat(filename,&__statBuffer)==0) { \
+ time=TARGET_NATIVE_MATH_INT_INT64_MUL(TARGET_NATIVE_MATH_INT_INT32_TO_INT64(__statBuffer.st_mtime), \
+ TARGET_NATIVE_MATH_INT_INT32_TO_INT64(1000) \
+ ); \
+ result=TARGET_NATIVE_OK; \
+ } else { \
+ result=TARGET_NATIVE_ERROR; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_SET_LAST_MODIFIED
+* Purpose : set last modification time of file (milliseconds)
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_SET_LAST_MODIFIED
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #ifdef HAVE_UTIME_H
+ #include <utime.h>
+ #elif HAVE_SYS_UTIME_H
+ #include <sys/utime.h>
+ #else
+ #error utime.h not found. Please check configuration.
+ #endif
+ #define TARGET_NATIVE_FILE_SET_LAST_MODIFIED(filename,time,result) \
+ do { \
+ struct stat __statBuffer; \
+ struct utimbuf __utimeBuffer; \
+ \
+ if (stat(filename,&__statBuffer)==0) { \
+ __utimeBuffer.actime =__statBuffer.st_atime; \
+ __utimeBuffer.modtime=TARGET_NATIVE_MATH_INT_INT64_TO_INT32(TARGET_NATIVE_MATH_INT_INT64_DIV(time, \
+ TARGET_NATIVE_MATH_INT_INT32_TO_INT64(1000) \
+ ) \
+ ); \
+ result=(utime(filename,&__utimeBuffer)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } else { \
+ result=TARGET_NATIVE_ERROR; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_DELETE
+* Purpose : delete a file,link or directory
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_DELETE
+ #define TARGET_NATIVE_FILE_DELETE(filename,result) \
+ do { \
+ result=((unlink(filename)==0) || (rmdir(filename)==0))?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_RENAME
+* Purpose : delete a file, link or directory
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_RENAME
+ #define TARGET_NATIVE_FILE_RENAME(oldfilename,newfilename,result) \
+ do { \
+ result=(rename(oldfilename,newfilename)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_MAKE_DIR
+* Purpose : create new directory
+* Input : name - directory name
+* Output : result - 1 if successful, 0 otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_MAKE_DIR
+ #include <sys/stat.h>
+ #define TARGET_NATIVE_FILE_MAKE_DIR(name,result) \
+ do { \
+ result=((mkdir(name,(S_IRWXO|S_IRWXG|S_IRWXU))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR); \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_GET_CWD
+* Purpose : get current working directory
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_GET_CWD
+ #include <unistd.h>
+ #define TARGET_NATIVE_FILE_GET_CWD(path,maxPathLength,result) \
+ do {\
+ result=(getcwd(path,maxPathLength)!=NULL)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_OPEN_DIR
+* Purpose : open directory for reading entries.
+* Input : -
+* Output : handle - handle if not error, NULL otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_OPEN_DIR
+ #include <sys/types.h>
+ #include <dirent.h>
+ #define TARGET_NATIVE_FILE_OPEN_DIR(filename,handle,result) \
+ do { \
+ handle=(void*)opendir(filename); \
+ result=(handle!=NULL)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while(0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_CLOSE_DIR
+* Purpose : close directory
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_CLOSE_DIR
+ #include <sys/types.h>
+ #include <dirent.h>
+ #define TARGET_NATIVE_FILE_CLOSE_DIR(handle,result) \
+ do { \
+ closedir((DIR*)handle); \
+ result=TARGET_NATIVE_OK; \
+ } while(0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_READ_DIR
+* Purpose : read directory entry
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+/* XXX ??? name als buffer? */
+#ifndef TARGET_NATIVE_FILE_READ_DIR
+ #include <sys/types.h>
+ #include <dirent.h>
+ #define TARGET_NATIVE_FILE_READ_DIR(handle,name,result) \
+ do { \
+ struct dirent *__direntBuffer; \
+ \
+ name=NULL; \
+ \
+ __direntBuffer=readdir((DIR*)handle); \
+ if (__direntBuffer!=NULL) { \
+ name=__direntBuffer->d_name; \
+ result=TARGET_NATIVE_OK; \
+ } else { \
+ result=TARGET_NATIVE_ERROR; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FILE_FSYNC
+* Purpose : do filesystem sync
+* Input : -
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_FILE_FSYNC
+ #define TARGET_NATIVE_FILE_FSYNC(filedescriptor,result) \
+ do { \
+ result=(fsync(filedescriptor)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while(0)
+#endif
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TARGET_GENERIC_FILE__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/generic/target_generic_io.h b/libjava/classpath/native/target/generic/target_generic_io.h
new file mode 100644
index 00000000000..cc24915ab19
--- /dev/null
+++ b/libjava/classpath/native/target/generic/target_generic_io.h
@@ -0,0 +1,82 @@
+/* generic_math_int64.h - Native methods for 64bit math operations
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: generic target defintions of miscellaneous functions
+Systems : all
+*/
+
+#ifndef __TARGET_GENERIC_IO__
+#define __TARGET_GENERIC_IO__
+
+/* check if target_native_io.h included */
+#ifndef __TARGET_NATIVE_IO__
+ #error Do NOT INCLUDE generic target files! Include the corresponding native target files instead!
+#endif
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include "config.h"
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "target_native.h"
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TARGET_GENERIC_IO__ */
+
+/* end of file */
diff --git a/libjava/classpath/native/target/generic/target_generic_math_float.h b/libjava/classpath/native/target/generic/target_generic_math_float.h
new file mode 100644
index 00000000000..e2085e08028
--- /dev/null
+++ b/libjava/classpath/native/target/generic/target_generic_math_float.h
@@ -0,0 +1,130 @@
+/* generic_math_int64.h - Native methods for 64bit math operations
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: generic target defintions of float/double constants/
+ macros/functions
+Systems : all
+*/
+
+#ifndef __TARGET_GENERIC_MATH_FLOAT__
+#define __TARGET_GENERIC_MATH_FLOAT__
+
+/* check if target_native_math_float.h included */
+#ifndef __TARGET_NATIVE_MATH_FLOAT__
+ #error Do NOT INCLUDE generic target files! Include the corresponding native target files instead!
+#endif
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include "config.h"
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include <jni.h>
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/* test float/double values for NaN,Inf */
+#ifndef TARGET_NATIVE_MATH_FLOAT_FLOAT_ISNAN
+ #include <math.h>
+ #define TARGET_NATIVE_MATH_FLOAT_FLOAT_ISNAN(f) isnan(f)
+#endif
+#ifndef TARGET_NATIVE_MATH_FLOAT_FLOAT_ISINF
+ #include <math.h>
+ #define TARGET_NATIVE_MATH_FLOAT_FLOAT_ISINF(f) isinf(f)
+#endif
+#ifndef TARGET_NATIVE_MATH_FLOAT_FLOAT_FINITE
+ #include <math.h>
+ #define TARGET_NATIVE_MATH_FLOAT_FLOAT_FINITE(f) finite(f)
+#endif
+
+#ifndef TARGET_NATIVE_MATH_FLOAT_DOUBLE_ISNAN
+ #include <math.h>
+ #define TARGET_NATIVE_MATH_FLOAT_DOUBLE_ISNAN(d) isnan(d)
+#endif
+#ifndef TARGET_NATIVE_MATH_FLOAT_DOUBLE_ISINF
+ #include <math.h>
+ #define TARGET_NATIVE_MATH_FLOAT_DOUBLE_ISINF(d) isinf(d)
+#endif
+#ifndef TARGET_NATIVE_MATH_FLOAT_DOUBLE_FINITE
+ #include <math.h>
+ #define TARGET_NATIVE_MATH_FLOAT_DOUBLE_FINITE(d) finite(d)
+#endif
+
+/* division, modulo operations (used to avoid unexcepted exceptions on some
+ targets; generic codes are direct operations without checks)
+*/
+#ifndef TARGET_NATIVE_MATH_FLOAT_FLOAT_DIV
+ #define TARGET_NATIVE_MATH_FLOAT_FLOAT_DIV(f0,f1) ((f0)/(f1))
+#endif
+#ifndef TARGET_NATIVE_MATH_FLOAT_FLOAT_MOD
+ #include <math.h>
+ #define TARGET_NATIVE_MATH_FLOAT_FLOAT_MOD(f0,f1) ((jfloat)fmod((jdouble)(f0),(jdouble)(f1)))
+#endif
+
+#ifndef TARGET_NATIVE_MATH_FLOAT_DOUBLE_DIV
+ #define TARGET_NATIVE_MATH_FLOAT_DOUBLE_DIV(d0,d1) ((d0)/(d1))
+#endif
+#ifndef TARGET_NATIVE_MATH_FLOAT_DOUBLE_MOD
+ #include <math.h>
+ #define TARGET_NATIVE_MATH_FLOAT_DOUBLE_MOD(d0,d1) fmod(d0,d1)
+#endif
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TARGET_GENERIC_MATH_FLOAT__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/generic/target_generic_math_int.h b/libjava/classpath/native/target/generic/target_generic_math_int.h
new file mode 100644
index 00000000000..c6861487efd
--- /dev/null
+++ b/libjava/classpath/native/target/generic/target_generic_math_int.h
@@ -0,0 +1,260 @@
+/* generic_math_int64.h - Native methods for 64bit math operations
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: generic target defintions of int/int64 constants/
+ macros/functions
+Systems : all
+*/
+
+#ifndef __TARGET_GENERIC_MATH_INT__
+#define __TARGET_GENERIC_MATH_INT__
+
+/* check if target_native_math_int.h included */
+#ifndef __TARGET_NATIVE_MATH_INT__
+ #error Do NOT INCLUDE generic target files! Include the corresponding native target files instead!
+#endif
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include "config.h"
+
+#include <stdlib.h>
+#include <assert.h>
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+#ifndef TARGET_NATIVE_MATH_INT_INT64_CONST_0
+ #define TARGET_NATIVE_MATH_INT_INT64_CONST_0 0LL
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_CONST_1
+ #define TARGET_NATIVE_MATH_INT_INT64_CONST_1 1LL
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1
+ #define TARGET_NATIVE_MATH_INT_INT64_CONST_MINUS_1 -1LL
+#endif
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/* math operations */
+#ifndef TARGET_NATIVE_MATH_INT_INT64_ADD
+ #define TARGET_NATIVE_MATH_INT_INT64_ADD(v1,v2) ((v1)+(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_SUB
+ #define TARGET_NATIVE_MATH_INT_INT64_SUB(v1,v2) ((v1)-(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_MUL
+ #define TARGET_NATIVE_MATH_INT_INT64_MUL(v1,v2) ((v1)*(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_DIV
+ #define TARGET_NATIVE_MATH_INT_INT64_DIV(v1,v2) ((v1)/(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_MOD
+ #define TARGET_NATIVE_MATH_INT_INT64_MOD(v1,v2) ((v1)%(v2))
+#endif
+
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_ADD
+ #define TARGET_NATIVE_MATH_INT_UINT64_ADD(v1,v2) ((v1)+(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_SUB
+ #define TARGET_NATIVE_MATH_INT_UINT64_SUB(v1,v2) ((v1)-(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_MUL
+ #define TARGET_NATIVE_MATH_INT_UINT64_MUL(v1,v2) ((v1)*(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_DIV
+ #define TARGET_NATIVE_MATH_INT_UINT64_DIV(v1,v2) ((v1)/(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_MOD
+ #define TARGET_NATIVE_MATH_INT_UINT64_MOD(v1,v2) ((v1)%(v2))
+#endif
+
+/* bit operations */
+#ifndef TARGET_NATIVE_MATH_INT_INT64_AND
+ #define TARGET_NATIVE_MATH_INT_INT64_AND(v1,v2) ((v1)&(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_OR
+ #define TARGET_NATIVE_MATH_INT_INT64_OR(v1,v2) ((v1)|(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_XOR
+ #define TARGET_NATIVE_MATH_INT_INT64_XOR(v1,v2) ((v1)^(v2))
+#endif
+
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_AND
+ #define TARGET_NATIVE_MATH_INT_UINT64_AND(v1,v2) ((v1)&(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_OR
+ #define TARGET_NATIVE_MATH_INT_UINT64_OR(v1,v2) ((v1)|(v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_XOR
+ #define TARGET_NATIVE_MATH_INT_UINT64_XOR(v1,v2) ((v1)^(v2))
+#endif
+
+/* shift operations */
+#ifndef TARGET_NATIVE_MATH_INT_INT64_SHIFTL
+ #define TARGET_NATIVE_MATH_INT_INT64_SHIFTL(v,l) ((v)<<(l))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_SHIFTR
+ #define TARGET_NATIVE_MATH_INT_INT64_SHIFTR(v,l) (((v)>>(l)) | (((v)>=0) ? 0 : (0xffffFFFFffffFFFFLL << (64-(l)))))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_SHIFTR
+ #define TARGET_NATIVE_MATH_INT_UINT64_SHIFTR(v,l) (((v)>>(l)) & ~(((v)>=0) ? 0 : (0xffffFFFFffffFFFFLL << (64-(l)))))
+#endif
+
+/* negation */
+#ifndef TARGET_NATIVE_MATH_INT_INT64_NEG
+ #define TARGET_NATIVE_MATH_INT_INT64_NEG(v) (-(v))
+#endif
+
+/* increment/decrement routines */
+#ifndef TARGET_NATIVE_MATH_INT_INT64_INC
+ #define TARGET_NATIVE_MATH_INT_INT64_INC(v) { v++; }
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_DEC
+ #define TARGET_NATIVE_MATH_INT_INT64_DEC(v) { v--; }
+#endif
+
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_INC
+ #define TARGET_NATIVE_MATH_INT_UINT64_INC(v) { v++; }
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_DEC
+ #define TARGET_NATIVE_MATH_INT_UINT64_DEC(v) { v--; }
+#endif
+
+/* comparison routines */
+#ifndef TARGET_NATIVE_MATH_INT_INT64_EQ
+ #define TARGET_NATIVE_MATH_INT_INT64_EQ(v1,v2) ((v1) == (v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_NE
+ #define TARGET_NATIVE_MATH_INT_INT64_NE(v1,v2) ((v1) != (v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_LT
+ #define TARGET_NATIVE_MATH_INT_INT64_LT(v1,v2) ((v1) < (v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_LE
+ #define TARGET_NATIVE_MATH_INT_INT64_LE(v1,v2) ((v1) <= (v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_GT
+ #define TARGET_NATIVE_MATH_INT_INT64_GT(v1,v2) ((v1) > (v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_GE
+ #define TARGET_NATIVE_MATH_INT_INT64_GE(v1,v2) ((v1) >= (v2))
+#endif
+
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_EQ
+ #define TARGET_NATIVE_MATH_INT_UINT64_EQ(v1,v2) ((v1) == (v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_NE
+ #define TARGET_NATIVE_MATH_INT_UINT64_NE(v1,v2) ((v1) != (v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_LT
+ #define TARGET_NATIVE_MATH_INT_UINT64_LT(v1,v2) ((v1) < (v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_LE
+ #define TARGET_NATIVE_MATH_INT_UINT64_LE(v1,v2) ((v1) <= (v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_GT
+ #define TARGET_NATIVE_MATH_INT_UINT64_GT(v1,v2) ((v1) > (v2))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_GE
+ #define TARGET_NATIVE_MATH_INT_UINT64_GE(v1,v2) ((v1) >= (v2))
+#endif
+
+/* type conversion routines */
+#ifndef TARGET_NATIVE_MATH_INT_INT32_TO_INT64
+ #define TARGET_NATIVE_MATH_INT_INT32_TO_INT64(v) ((jlong)(v))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT32_TO_UINT64
+ #define TARGET_NATIVE_MATH_INT_UINT32_TO_UINT64(v) ((jlong)(v))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_TO_INT32
+ #define TARGET_NATIVE_MATH_INT_INT64_TO_INT32(v) ((jint )(v))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_TO_UINT32
+ #define TARGET_NATIVE_MATH_INT_UINT64_TO_UINT32(v) ((jint)(v))
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_TO_DOUBLE
+ #define TARGET_NATIVE_MATH_INT_INT64_TO_DOUBLE(v) ((jdouble)(v))
+#endif
+
+/* combine/split int32 low/high values <-> int64 values */
+#ifndef TARGET_NATIVE_MATH_INT_INT32_LOW_HIGH_TO_INT64
+ #define TARGET_NATIVE_MATH_INT_INT32_LOW_HIGH_TO_INT64(low,high,v) \
+ do { \
+ (v)=((((jlong)(high)) << 32) | ((((jlong)(low)) << 0) & 0x00000000ffffFFFFLL)); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT32_LOW_HIGH_TO_UINT64
+ #define TARGET_NATIVE_MATH_INT_UINT32_LOW_HIGH_TO_UINT64(low,high,v) \
+ do { \
+ (v)=((((jlong)(high)) << 32) | ((((jlong)(low)) << 0) & 0x00000000ffffFFFFLL)); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_INT64_TO_INT32_LOW_HIGH
+ #define TARGET_NATIVE_MATH_INT_INT64_TO_INT32_LOW_HIGH(v,low,high) \
+ do { \
+ (high)=((v) & 0xFFFFffff00000000L) >> 32; \
+ (low) =((v) & 0x00000000FFFFffffL) >> 0; \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MATH_INT_UINT64_TO_UINT32_LOW_HIGH
+ #define TARGET_NATIVE_MATH_INT_UINT64_TO_UINT32_LOW_HIGH(v,low,high) \
+ do { \
+ (high)=((v) & 0xFFFFffff00000000L) >> 32; \
+ (low) =((v) & 0x00000000FFFFffffL) >> 0; \
+ } while (0)
+#endif
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TARGET_GENERIC_MATH_INT__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/generic/target_generic_misc.h b/libjava/classpath/native/target/generic/target_generic_misc.h
new file mode 100644
index 00000000000..1174aa83c7e
--- /dev/null
+++ b/libjava/classpath/native/target/generic/target_generic_misc.h
@@ -0,0 +1,203 @@
+/* generic_math_int64.h - Native methods for 64bit math operations
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: generic target defintions of miscellaneous functions
+Systems : all
+*/
+
+#ifndef __TARGET_GENERIC_MISC__
+#define __TARGET_GENERIC_MISC__
+
+/* check if target_native_misc.h included */
+#ifndef __TARGET_NATIVE_MISC__
+ #error Do NOT INCLUDE generic target files! Include the corresponding native target files instead!
+#endif
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include "config.h"
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "target_native.h"
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_MISC_FORMAT_STRING<n>
+* Purpose : format a string (with a fixed number of) arguments
+* Input : buffer - buffer for string
+* bufferSize - size of buffer
+* format - format string (like printf)
+* args - optional arguments (GNU CPP only!)
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : - this is a "safe" macro to format string; buffer-
+* overflows will be avoided. Direct usage of e. g.
+* snprintf() is not permitted because it is not ANSI C
+* (not portable!)
+* - do not use this routine in a function without
+* variable number of arguments (ellipses), because
+* va_list/va_start/va_end is used!
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING0
+ #include <stdarg.h>
+ #define TARGET_NATIVE_MISC_FORMAT_STRING0(buffer,bufferSize,format) \
+ do { \
+ snprintf(buffer,bufferSize,format); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING1
+ #include <stdarg.h>
+ #define TARGET_NATIVE_MISC_FORMAT_STRING1(buffer,bufferSize,format,arg1) \
+ do { \
+ snprintf(buffer,bufferSize,format,arg1); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING2
+ #include <stdarg.h>
+ #define TARGET_NATIVE_MISC_FORMAT_STRING2(buffer,bufferSize,format,arg1,arg2) \
+ do { \
+ snprintf(buffer,bufferSize,format,arg1,arg2); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING3
+ #include <stdarg.h>
+ #define TARGET_NATIVE_MISC_FORMAT_STRING3(buffer,bufferSize,format,arg1,arg2,arg3) \
+ do { \
+ snprintf(buffer,bufferSize,format,arg1,arg2,arg3); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING4
+ #include <stdarg.h>
+ #define TARGET_NATIVE_MISC_FORMAT_STRING4(buffer,bufferSize,format,arg1,arg2,arg3,arg4) \
+ do { \
+ snprintf(buffer,bufferSize,format,arg1,arg2,arg3,arg4); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING5
+ #include <stdarg.h>
+ #define TARGET_NATIVE_MISC_FORMAT_STRING5(buffer,bufferSize,format,arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ snprintf(buffer,bufferSize,format,arg1,arg2,arg3,arg4,arg5); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING6
+ #include <stdarg.h>
+ #define TARGET_NATIVE_MISC_FORMAT_STRING6(buffer,bufferSize,format,arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { \
+ snprintf(buffer,bufferSize,format,arg1,arg2,arg3,arg4,arg5,arg6); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING7
+ #include <stdarg.h>
+ #define TARGET_NATIVE_MISC_FORMAT_STRING7(buffer,bufferSize,format,arg1,arg2,arg3,arg14,arg5,arg6,arg7) \
+ do { \
+ snprintf(buffer,bufferSize,format,arg1,arg2,arg3,arg4,arg5,arg6,arg7); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING8
+ #include <stdarg.h>
+ #define TARGET_NATIVE_MISC_FORMAT_STRING8(buffer,bufferSize,format,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) \
+ do { \
+ snprintf(buffer,bufferSize,format,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); \
+ } while (0)
+#endif
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING9
+ #include <stdarg.h>
+ #define TARGET_NATIVE_MISC_FORMAT_STRING9(buffer,bufferSize,format,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) \
+ do { \
+ snprintf(buffer,bufferSize,format,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9); \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_FORMAT_STRING_ELLIPSE
+* Purpose : format a string with arguments
+* Input : buffer - buffer for string
+* bufferSize - size of buffer
+* format - format string (like printf)
+* Output : -
+* Return : -
+* Side-effect: unknown
+* Notes : - this is a "safe" macro to format string; buffer-
+* overflows will be avoided. Direct usage of e. g.
+* snprintf() is not permitted because it is not ANSI C
+* (not portable!)
+* - do not use this routine in a function without
+* variable number of arguments (ellipses), because
+* va_list/va_start/va_end is used!
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_MISC_FORMAT_STRING_ELLIPSE
+ #include <stdarg.h>
+ #define TARGET_NATIVE_FORMAT_STRING_ELLIPSE(buffer,bufferSize,format) \
+ do { \
+ va_list __arguments; \
+ \
+ va_start(__arguments,format); \
+ vsnprintf(buffer,bufferSize,format,__arguments); \
+ va_end(__arguments); \
+ } while (0)
+#endif
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TARGET_GENERIC_MISC__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/generic/target_generic_network.h b/libjava/classpath/native/target/generic/target_generic_network.h
new file mode 100644
index 00000000000..dbbd92e2c92
--- /dev/null
+++ b/libjava/classpath/native/target/generic/target_generic_network.h
@@ -0,0 +1,1278 @@
+/* target_generic_network.h - Native methods for network operations.
+ Copyright (C) 1998, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/*
+Description: generic target defintions of network functions
+Systems : all
+*/
+
+#ifndef __TARGET_GENERIC_NETWORK__
+#define __TARGET_GENERIC_NETWORK__
+
+/* check if target_native_network.h included */
+#ifndef __TARGET_NATIVE_NETWORK__
+ #error Do NOT INCLUDE generic target files! Include the corresponding native target files instead!
+#endif
+
+/****************************** Includes *******************************/
+/* do not move; needed here because of some macro definitions */
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "target_native.h"
+
+/****************** Conditional compilation switches *******************/
+
+/***************************** Constants *******************************/
+
+/***************************** Datatypes *******************************/
+
+/***************************** Variables *******************************/
+
+/****************************** Macros *********************************/
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT
+* Purpose : convert IP adddress (4 parts) into integer (host-format
+* 32bit)
+* Input : n0,n1,n2,n3 - IP address parts
+* Output : i - integer with IP address in host-format
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT
+ #define TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT(n0,n1,n2,n3,i) \
+ do { \
+ i=(((unsigned char)n0) << 24) | \
+ (((unsigned char)n1) << 16) | \
+ (((unsigned char)n2) << 8) | \
+ (((unsigned char)n3) << 0); \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES
+* Purpose : convert IP adddress (4 parts) into integer (host-format
+* 32bit)
+* Input : n0,n1,n2,n3 - IP address parts
+* Output : i - integer with IP address in host-format
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES
+ #define TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES(i,n0,n1,n2,n3) \
+ do { \
+ n0=(i & 0xFF000000) >> 24; \
+ n1=(i & 0x00FF0000) >> 16; \
+ n2=(i & 0x0000FF00) >> 8; \
+ n3=(i & 0x000000FF) >> 0; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_GET_HOSTNAME
+* Purpose : get hostname
+* Input : maxNameLen - max. length of name
+* Output : name - name (NUL terminated)
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_GET_HOSTNAME
+ #include <unistd.h>
+ #define TARGET_NATIVE_NETWORK_GET_HOSTNAME(name,maxNameLen,result) \
+ do { \
+ result=(gethostname(name,maxNameLen-1)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ name[maxNameLen-1]='\0'; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_ADDRESS
+* Purpose : get hostname by address
+* Input : address - IP address (32bit, NOT network byte order!)
+* maxNameLen - max. length of name
+* Output : name - name (NUL terminated)
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+/* XXX NYI??? reentrant? */
+#ifndef TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_ADDRESS
+ #include <netdb.h>
+ #define TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_ADDRESS(address,name,maxNameLen,result) \
+ do { \
+ int __networkAddress; \
+ struct hostent *__hostEntry; \
+ \
+ __networkAddress=htonl(address); \
+ __hostEntry = gethostbyaddr((char*)&__networkAddress,sizeof(__networkAddress),AF_INET); \
+ if (__hostEntry!=NULL) \
+ { \
+ strncpy(name,__hostEntry->h_name,maxNameLen-1); \
+ name[maxNameLen]='\0'; \
+ result=TARGET_NATIVE_OK; \
+ } \
+ else \
+ { \
+ result=TARGET_NATIVE_ERROR; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_NAME
+* Purpose : get hostname by name
+* Input : name - hostname
+* maxAddressSize - max. size of address array
+* Output : addresses - host adddresses (array, NOT in network
+* byte order!)
+* addressCount - number of entries in address array
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+/* XXX NYI??? reentrant? */
+#ifndef TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_NAME
+ #include <netdb.h>
+ #define TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_NAME(name,addresses,maxAddressSize,addressCount,result) \
+ do { \
+ struct hostent *__hostEntry; \
+ \
+ addressCount=0; \
+ \
+ __hostEntry = gethostbyname(name); \
+ if (__hostEntry!=NULL) \
+ { \
+ while ((addressCount<maxAddressSize) && (__hostEntry->h_addr_list[addressCount]!=NULL)) \
+ { \
+ addresses[addressCount]=ntohl(*(int*)(__hostEntry->h_addr_list[addressCount])); \
+ addressCount++; \
+ } \
+ result=TARGET_NATIVE_OK; \
+ } \
+ else \
+ { \
+ result=TARGET_NATIVE_ERROR; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_OPEN_STREAM
+* Purpose : open stream socket
+* Input : -
+* Output : socketDescriptor - socket descriptor
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_OPEN_STREAM
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <fcntl.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_OPEN_STREAM(socketDescriptor,result) \
+ do { \
+ socketDescriptor=socket(AF_INET,SOCK_STREAM,0); \
+ fcntl(socketDescriptor,F_SETFD,FD_CLOEXEC); \
+ result=(socketDescriptor!=-1)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_OPEN_DATAGRAM
+* Purpose : open datagram socket
+* Input : -
+* Output : socketDescriptor - socket descriptor
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_OPEN_DATAGRAM
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <fcntl.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_OPEN_DATAGRAM(socketDescriptor,result) \
+ do { \
+ socketDescriptor=socket(AF_INET,SOCK_DGRAM,0); \
+ fcntl(socketDescriptor,F_SETFD,FD_CLOEXEC); \
+ result=(socketDescriptor!=-1)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_CLOSE
+* Purpose : close socket
+* Input : socketDescriptor - socket descriptor
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_CLOSE
+ #include <unistd.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_CLOSE(socketDescriptor,result) \
+ do { \
+ result=(close(socketDescriptor)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_CONNECT
+* Purpose : connect socket
+* Input : socketDescriptor - socket descriptor
+* address - address (network format???)
+* port - port number (NOT in network byte order!)
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_CONNECT
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_CONNECT(socketDescriptor,address,port,result) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ \
+ memset(&__socketAddress,0,sizeof(__socketAddress)); \
+ __socketAddress.sin_family = AF_INET; \
+ __socketAddress.sin_addr.s_addr = htonl(address); \
+ __socketAddress.sin_port = htons(((short)port)); \
+ \
+ result=(connect(socketDescriptor,(struct sockaddr*)&__socketAddress,sizeof(__socketAddress))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_BIND
+* Purpose : bind socket
+* Input : socketDescriptor - socket descriptor
+* address - address (NOT ??? in network byte order!)
+* port - port (NOT in network byte order!)
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+/* XXX ??? address in network byte order? */
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_BIND
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_BIND(socketDescriptor,address,port,result) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ \
+ memset(&__socketAddress,0,sizeof(__socketAddress)); \
+ __socketAddress.sin_family = AF_INET; \
+ __socketAddress.sin_addr.s_addr = htonl(address); \
+ __socketAddress.sin_port = htons(((short)port)); \
+ \
+ result=(bind(socketDescriptor,(struct sockaddr*)&__socketAddress,sizeof(__socketAddress))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_LISTEN
+* Purpose : listen socket
+* Input : socketDescriptor - socket descriptor
+* maxQueueLength - max. number of pending connections
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+/* XXX ??? address in network byte order? */
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_LISTEN
+ #include <sys/socket.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_LISTEN(socketDescriptor,maxQueueLength,result) \
+ do { \
+ result=(listen(socketDescriptor,maxQueueLength)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_ACCEPT
+* Purpose : accept socket
+* Input : socketDescriptor - socket descriptor
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+/* XXX ??? address in network byte order? */
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_ACCEPT
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_ACCEPT(socketDescriptor,newSocketDescriptor,result) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ socklen_t __socketAddressLength; \
+ \
+ memset(&__socketAddress,0,sizeof(__socketAddress)); \
+ __socketAddressLength=sizeof(__socketAddress); \
+ newSocketDescriptor=accept(socketDescriptor,(struct sockaddr*)&__socketAddress,&__socketAddressLength); \
+ result=(newSocketDescriptor!=-1)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO
+* Purpose : get local socket data info
+* Input : socketDescriptor - socket descriptor
+* Output : localAddress - local address (NOT in network byte order!)
+* localPort - local port number (NOT in network byte order!)
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO(socketDescriptor,localAddress,localPort,result) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ socklen_t __socketAddressLength; \
+ \
+ localAddress=0; \
+ localPort =0; \
+ \
+ __socketAddressLength=sizeof(__socketAddress); \
+ result=(getsockname(socketDescriptor,(struct sockaddr*)&__socketAddress,&__socketAddressLength)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ localAddress=ntohl(__socketAddress.sin_addr.s_addr); \
+ localPort =ntohs(__socketAddress.sin_port); \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO
+* Purpose : get remote socket data info
+* Input : socketDescriptor - socket descriptor
+* Output : remoteAddress - remote address (NOT in network byte order!)
+* remotePort - remote port number (NOT in network byte order!)
+* : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO(socketDescriptor,remoteAddress,remotePort,result) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ socklen_t __socketAddressLength; \
+ \
+ remoteAddress=0; \
+ remotePort =0; \
+ \
+ __socketAddressLength=sizeof(__socketAddress); \
+ result=(getpeername(socketDescriptor,(struct sockaddr*)&__socketAddress,&__socketAddressLength)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ remoteAddress=ntohl(__socketAddress.sin_addr.s_addr); \
+ remotePort =ntohs(__socketAddress.sin_port); \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_AVAILABLE
+* Purpose : get number of available bytes for receive
+* Input : socketDescriptor - socket descriptor
+* Output : bytesAvailable - available bytes for receive
+* : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_AVAILABLE
+ #include <sys/ioctl.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_AVAILABLE(socketDescriptor,bytesAvailable,result) \
+ do { \
+ int __value; \
+ \
+ bytesAvailable=0; \
+ \
+ result=(ioctl(socketDescriptor,FIONREAD,&__value)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ bytesAvailable=__value; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_RECEIVE
+* Purpose : receive data from socket
+* Input : socketDescriptor - socket descriptor
+* maxLength - max. size of bfufer
+* Output : buffer - received data
+* bytesReceive - length of received data
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_RECEIVE
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_RECEIVE(socketDescriptor,buffer,maxLength,bytesReceived) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ socklen_t __socketAddressLength; \
+ \
+ memset(&__socketAddress,0,sizeof(__socketAddress)); \
+ __socketAddressLength=sizeof(__socketAddress); \
+ bytesReceived=recv(socketDescriptor,buffer,maxLength,0); \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_WITH_ADDRESS_PORT
+* Purpose : receive data from socket
+* Input : socketDescriptor - socket descriptor
+* maxLength - max. size of bfufer
+* Output : buffer - received data
+* address - from address (NOT in network byte order!)
+* port - from port (NOT in network byte order!)
+* bytesReceive - length of received data
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_WITH_ADDRESS_PORT
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_WITH_ADDRESS_PORT(socketDescriptor,buffer,maxLength,address,port,bytesReceived) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ socklen_t __socketAddressLength; \
+ \
+ port=0; \
+ \
+ memset(&__socketAddress,0,sizeof(__socketAddress)); \
+ __socketAddressLength=sizeof(__socketAddress); \
+ bytesReceived=recvfrom(socketDescriptor,buffer,maxLength,0,(struct sockaddr*)&__socketAddress,&__socketAddressLength); \
+ if (__socketAddressLength==sizeof(__socketAddress)) \
+ { \
+ address=ntohl(__socketAddress.sin_addr.s_addr); \
+ port =ntohs(__socketAddress.sin_port); \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SEND
+* Purpose : send data to socket
+* Input : socketDescriptor - socket descriptor
+* : buffer - data to send
+* length - length of data to send
+* Output : bytesSent - number of bytes sent, -1 otherwise
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SEND
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SEND(socketDescriptor,buffer,length,bytesSent) \
+ do { \
+ bytesSent=send(socketDescriptor,buffer,length,0); \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SEND_WITH_ADDRESS_PORT
+* Purpose : send data to socket
+* Input : socketDescriptor - socket descriptor
+* : buffer - data to send
+* length - length of data to send
+* Address - to address (NOT in network byte order!)
+* Port - to port (NOT in network byte order!)
+* Output : bytesSent - number of bytes sent, -1 otherwise
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SEND_WITH_ADDRESS_PORT
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SEND_WITH_ADDRESS_PORT(socketDescriptor,buffer,length,address,port,bytesSent) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ \
+ memset(&__socketAddress,0,sizeof(__socketAddress)); \
+ __socketAddress.sin_family = AF_INET; \
+ __socketAddress.sin_addr.s_addr = htonl(address); \
+ __socketAddress.sin_port = htons((short)port); \
+ bytesSent=sendto(socketDescriptor,buffer,length,0,(struct sockaddr*)&__socketAddress,sizeof(__socketAddress)); \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_TCP_NODELAY
+* Purpose : set socket option TCP_NODELAY
+* Input : socketDescriptor - socket descriptor
+* flag - 1 or 0
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_TCP_NODELAY
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/tcp.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_TCP_NODELAY(socketDescriptor,flag,result) \
+ do { \
+ int __value; \
+ \
+ __value=flag; \
+ result=(setsockopt(socketDescriptor,IPPROTO_TCP,TCP_NODELAY,&__value,sizeof(__value))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER
+* Purpose : set socket option SO_LINGER
+* Input : socketDescriptor - socket descriptor
+* flag - 1 or 0
+* value - linger value
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER(socketDescriptor,flag,value,result) \
+ do { \
+ struct linger __linger; \
+ \
+ memset(&__linger,0,sizeof(__linger)); \
+ if (flag) \
+ { \
+ __linger.l_onoff=0; \
+ } \
+ else \
+ { \
+ __linger.l_linger=value; \
+ __linger.l_onoff =1; \
+ } \
+ result=(setsockopt(socketDescriptor,SOL_SOCKET,SO_LINGER,&__linger,sizeof(__linger))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT
+* Purpose : set socket option SO_TIMEOUT
+* Input : socketDescriptor - socket descriptor
+* flag - 1 or 0
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT(socketDescriptor,flag,result) \
+ do { \
+ struct timeval __value; \
+ \
+ __value.tv_sec = flag / 1000; \
+ __value.tv_usec = (flag % 1000) * 1000; \
+ result=(setsockopt(socketDescriptor,SOL_SOCKET,SO_TIMEOUT,&__value,sizeof(__value))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_SNDBUF
+* Purpose : set socket option SO_SNDBUF
+* Input : socketDescriptor - socket descriptor
+* size - size of send buffer
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_SNDBUF
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_SNDBUF(socketDescriptor,size,result) \
+ do { \
+ int __value; \
+ \
+ __value=size; \
+ result=(setsockopt(socketDescriptor,SOL_SOCKET,SO_SNDBUF,&__value,sizeof(__value))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_RCDBUF
+* Purpose : set socket option SO_RCDBUF
+* Input : socketDescriptor - socket descriptor
+* size - size of receive buffer
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_RCDBUF
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_RCDBUF(socketDescriptor,size,result) \
+ do { \
+ int __value; \
+ \
+ __value=size; \
+ result=(setsockopt(socketDescriptor,SOL_SOCKET,SO_RCVBUF,&__value,sizeof(__value))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_TTL
+* Purpose : set socket option IP_TTL
+* Input : socketDescriptor - socket descriptor
+* value - value
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_TTL
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_TTL(socketDescriptor,value,result) \
+ do { \
+ int __value; \
+ \
+ __value=value; \
+ result=(setsockopt(socketDescriptor,IPPROTO_IP,IP_TTL,&__value,sizeof(__value))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_MULTICAST_IF
+* Purpose : set socket option IP_MULTICAST_IF
+* Input : socketDescriptor - socket descriptor
+* address - integer with IP address in host-format
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_MULTICAST_IF
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_MULTICAST_IF(socketDescriptor,address,result) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ \
+ memset(&__socketAddress,0,sizeof(__socketAddress)); \
+ __socketAddress.sin_family = AF_INET; \
+ __socketAddress.sin_addr.s_addr = htonl(address); \
+ result=(setsockopt(socketDescriptor,IPPROTO_IP,IP_MULTICAST_IF,&__socketAddress,sizeof(__socketAddress))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_REUSE_ADDRESS
+* Purpose : set socket option REUSE_ADDRESS
+* Input : socketDescriptor - socket descriptor
+* flag - 1 or 0
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_REUSE_ADDRESS
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_REUSE_ADDRESS(socketDescriptor,flag,result) \
+ do { \
+ int __value; \
+ \
+ __value=flag; \
+ result=(setsockopt(socketDescriptor,SOL_SOCKET,SO_REUSEADDR,&__value,sizeof(__value))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_ADD_MEMBERSHIP
+* Purpose : set socket option IP_ADD_MEMBERSHIP
+* Input : socketDescriptor - socket descriptor
+* address - network address (host-format)
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_ADD_MEMBERSHIP
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_ADD_MEMBERSHIP(socketDescriptor,address,result) \
+ do { \
+ struct ip_mreq __request; \
+ \
+ memset(&__request,0,sizeof(__request)); \
+ __request.imr_multiaddr.s_addr=htonl(address); \
+ __request.imr_interface.s_addr=INADDR_ANY; \
+ result=(setsockopt(socketDescriptor,IPPROTO_IP,IP_ADD_MEMBERSHIP,&__request,sizeof(__request))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_DROP_MEMBERSHIP
+* Purpose : set socket option IP_DROP_MEMBERSHIP
+* Input : socketDescriptor - socket descriptor
+* address - network address (host-format)
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_DROP_MEMBERSHIP
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_DROP_MEMBERSHIP(socketDescriptor,address,result) \
+ do { \
+ struct ip_mreq __request; \
+ \
+ memset(&__request,0,sizeof(__request)); \
+ __request.imr_multiaddr.s_addr=htonl(address); \
+ __request.imr_interface.s_addr=INADDR_ANY; \
+ result=(setsockopt(socketDescriptor,IPPROTO_IP,IP_DROP_MEMBERSHIP,&__request,sizeof(__request))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_KEEP_ALIVE
+* Purpose : set socket option KEEP_ALIVE
+* Input : socketDescriptor - socket descriptor
+* flag - 1 or 0
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_KEEP_ALIVE
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_KEEP_ALIVE(socketDescriptor,flag,result) \
+ do { \
+ int __value; \
+ \
+ __value=flag; \
+ result=(setsockopt(socketDescriptor,SOL_SOCKET,SO_KEEPALIVE,&__value,sizeof(__value))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_BROADCAST
+* Purpose : set socket option SO_BROADCAST
+* Input : socketDescriptor - socket descriptor
+* flag - 1 or 0
+* Output : result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_BROADCAST
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/tcp.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_BROADCAST(socketDescriptor,flag,result) \
+ do { \
+ int __value; \
+ \
+ __value=flag; \
+ result=(setsockopt(socketDescriptor,SOL_SOCKET,SO_BROADCAST,&__value,sizeof(__value))==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ } while (0)
+#endif
+
+/*---------------------------------------------------------------------*/
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_TCP_NODELAY
+* Purpose : get socket option TCP_NODELAY
+* Input : socketDescriptor - socket descriptor
+* Output : flag - 1 or 0
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_TCP_NODELAY
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/tcp.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_TCP_NODELAY(socketDescriptor,flag,result) \
+ do { \
+ int __value; \
+ socklen_t __len; \
+ \
+ flag=0; \
+ \
+ __len=sizeof(__value); \
+ result=(getsockopt(socketDescriptor,IPPROTO_TCP,TCP_NODELAY,&__value,&__len)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ flag=__value; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_LINGER
+* Purpose : get socket option SO_LINGER
+* Input : socketDescriptor - socket descriptor
+* Output : flag - 1 or 0
+* value - linger value
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_LINGER
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_LINGER(socketDescriptor,flag,value,result) \
+ do { \
+ struct linger __linger; \
+ socklen_t __len; \
+ \
+ flag =0; \
+ value=0; \
+ \
+ __len=sizeof(__linger); \
+ result=(getsockopt(socketDescriptor,SOL_SOCKET,SO_LINGER,&__linger,&__len)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ flag =__linger.l_onoff; \
+ value=__linger.l_linger; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_TIMEOUT
+* Purpose : get socket option SO_TIMEOUT
+* Input : socketDescriptor - socket descriptor
+* Output : flag - 1 or 0
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_TIMEOUT
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_TIMEOUT(socketDescriptor,flag,result) \
+ do { \
+ struct timeval __value; \
+ socklen_t __len; \
+ \
+ flag=0; \
+ \
+ __len=sizeof(__value); \
+ result=(getsockopt(socketDescriptor,SOL_SOCKET,SO_TIMEOUT,&__value,&__len)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ flag = (__value.tv_sec * 1000LL) + (__value.tv_usec / 1000LL); \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_SNDBUF
+* Purpose : get socket option SO_SNDBUF
+* Input : socketDescriptor - socket descriptor
+* Output : size - size of send buffer
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_SNDBUF
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_SNDBUF(socketDescriptor,size,result) \
+ do { \
+ int __value; \
+ socklen_t __len; \
+ \
+ size=0; \
+ \
+ __len=sizeof(__value); \
+ result=(getsockopt(socketDescriptor,SOL_SOCKET,SO_SNDBUF,&__value,&__len)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ size=__value; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_RCDBUF
+* Purpose : get socket option SO_RCDBUF
+* Input : socketDescriptor - socket descriptor
+* Output : size - size of receive buffer
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_RCDBUF
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_RCDBUF(socketDescriptor,size,result) \
+ do { \
+ int __value; \
+ socklen_t __len; \
+ \
+ size=0; \
+ \
+ __len=sizeof(__value); \
+ result=(getsockopt(socketDescriptor,SOL_SOCKET,SO_RCVBUF,&__value,&__len)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ size=__value; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_TTL
+* Purpose : get socket option IP_TTL
+* Input : socketDescriptor - socket descriptor
+* Output : flag - 1 or 0
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_TTL
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_TTL(socketDescriptor,flag,result) \
+ do { \
+ int __value; \
+ socklen_t __len; \
+ \
+ flag=0; \
+ \
+ __len=sizeof(__value); \
+ result=(getsockopt(socketDescriptor,IPPROTO_IP,IP_TTL,&__value,&__len)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ flag=__value; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_MULTICAST_IF
+* Purpose : get socket option IP_MULTICAST_IF
+* Input : socketDescriptor - socket descriptor
+* Output : address - integer with IP address in host-format
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_MULTICAST_IF
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_MULTICAST_IF(socketDescriptor,address,result) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ socklen_t __socketAddressLength; \
+ \
+ address=0;\
+ \
+ memset(&__socketAddress,0,sizeof(__socketAddress)); \
+ __socketAddress.sin_family = AF_INET; \
+ __socketAddress.sin_addr.s_addr = htonl(address); \
+ __socketAddressLength=sizeof(__socketAddress); \
+ result=(getsockopt(socketDescriptor,IPPROTO_IP,IP_MULTICAST_IF,&__socketAddress,&__socketAddressLength)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ address=ntohl(__socketAddress.sin_addr.s_addr); \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BIND_ADDRESS
+* Purpose : get socket option SOCKOPT_SO_BINDADDR
+* Input : socketDescriptor - socket descriptor
+* Output : address - integer with IP address in host-format
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BIND_ADDRESS
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BIND_ADDRESS(socketDescriptor,address,result) \
+ do { \
+ struct sockaddr_in __socketAddress; \
+ socklen_t __socketAddressLength; \
+ \
+ address=0;\
+ \
+ memset(&__socketAddress,0,sizeof(__socketAddress)); \
+ __socketAddressLength=sizeof(__socketAddress); \
+ result=(getsockname(socketDescriptor,(struct sockaddr*)&__socketAddress,&__socketAddressLength)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ address=ntohl(__socketAddress.sin_addr.s_addr); \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_REUSE_ADDRESS
+* Purpose : get socket option REUSE_ADDRESS
+* Input : socketDescriptor - socket descriptor
+* Output : flag - 1 or 0
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_REUSE_ADDRESS
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_REUSE_ADDRESS(socketDescriptor,flag,result) \
+ do { \
+ int __value; \
+ socklen_t __len; \
+ \
+ flag=0; \
+ \
+ __len=sizeof(__value); \
+ result=(getsockopt(socketDescriptor,SOL_SOCKET,SO_REUSEADDR,&__value,&__len)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ flag=__value; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_KEEP_ALIVE
+* Purpose : get socket option KEEP_ALIVE
+* Input : socketDescriptor - socket descriptor
+* Output : flag - 1 or 0
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_KEEP_ALIVE
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_KEEP_ALIVE(socketDescriptor,flag,result) \
+ do { \
+ int __value; \
+ socklen_t __len; \
+ \
+ flag=0; \
+ \
+ __len=sizeof(__value); \
+ result=(getsockopt(socketDescriptor,SOL_SOCKET,SO_KEEPALIVE,&__value,&__len)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ flag=__value; \
+ } \
+ } while (0)
+#endif
+
+/***********************************************************************\
+* Name : TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BROADCAST
+* Purpose : get socket option SO_BROADCAST
+* Input : socketDescriptor - socket descriptor
+* Output : flag - 1 or 0
+* result - TARGET_NATIVE_OK if no error occurred,
+* TARGET_NATIVE_ERROR otherwise
+* Return : -
+* Side-effect: unknown
+* Notes : -
+\***********************************************************************/
+
+#ifndef TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BROADCAST
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/tcp.h>
+ #define TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BROADCAST(socketDescriptor,flag,result) \
+ do { \
+ int __value; \
+ socklen_t __len; \
+ \
+ flag=0; \
+ \
+ __len=sizeof(__value); \
+ result=(getsockopt(socketDescriptor,SOL_SOCKET,SO_BROADCAST,&__value,&__len)==0)?TARGET_NATIVE_OK:TARGET_NATIVE_ERROR; \
+ if (result==TARGET_NATIVE_OK) \
+ { \
+ flag=__value; \
+ } \
+ } while (0)
+#endif
+
+/***************************** Functions *******************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TARGET_GENERIC_NETWORK__ */
+
+/* end of file */
+
diff --git a/libjava/classpath/native/target/readme.txt b/libjava/classpath/native/target/readme.txt
new file mode 100644
index 00000000000..6fee79eba63
--- /dev/null
+++ b/libjava/classpath/native/target/readme.txt
@@ -0,0 +1,149 @@
+The GNU classpath native layer
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To enable GNU classpath to run on a diverse array of different hardware
+platforms, a new native software layer has been added. This layer hide all
+machine and hardware dependent issues except common available definitions,
+which are ANSI C functions. For each targets system where the GNU classpath
+library is to be used, a specific set of native layer functions have to be
+provided. A generic set of functions is provided for Unix like systems
+(currently tested only with Linux). For a new target system, some or
+all native layer functions have to be rewritten. The following scheme
+illustrate the native layer.
+
+ Java API
+ ----------------------
+ | Java classes |
+ | -------------------- |
+ | C native functions |
+ | -------------------- |
+ >> | C native layer | <<
+ | -------------------- |
+ | operating system |
+ | -------------------- |
+ | hardware |
+ ----------------------
+
+The C native layer is implemented as a set of C pre-processor native macros.
+These macros expand to the appropriated native code. Macros are used
+instead function calls to give optimal performance and small code size.
+Of course in special cases, a macro can also expand to a function call
+if this is needed. This approach provide a flexible and efficient
+implementation of the native layer.
+
+The naming pattern for native macros is like follows:
+
+ TARGET_NATIVE_<module name>_<macro name>
+
+where <module name> is a name of a module, e. g. FILE; <macro name> is
+the name of the specific native macro, e. g. OPEN_READ.
+
+The parameters for the macro use in general (with a few exceptions) the
+scheme
+
+ <parameter>,<parameter>,...,<result>
+
+where <parameter> is input/output parameter and <result> is the result
+code TARGET_NATIVE_OK or TARGET_NATIVE_ERROR. Specific error codes
+and error strings can be gotten with
+
+ TARGET_NATIVE_LAST_ERROR and
+ TARGET_NATIVE_LAST_ERROR_STRING
+
+(see also file target_generic.h).
+
+For a single target system there exists two sets of native macros in
+the files
+
+ a) <target name>/target_native_<module name>.h
+ b) generic/target_generic_<module name>.h
+
+The macros in "a" are target specific implementations of native
+functions, the macros in "b" are generic implementations (for Unix) of
+the same native functions. If a native macro is not defined in the file
+"a", then the definition in file "b" is used (there is a check to see if
+a native macros is already defined elsewhere). This technique enables
+"a" to 'overwrite' single generic native macros with specific native
+macros for a specific target. In the default case, where only the
+generic implementation of the native macros is used, the files in the
+directory '<target name>' are empty except for the mandatory include of the
+generic header file in the directory 'generic' at the end. Please
+look at the existing Linux target specific files.
+
+The directory and file structure is as follows.
+
+ native
+ ...
+ |
+ |--- target
+ | |
+ | |--- Linux
+ | | |--- target_native_<module name>.h
+ | | |--- ...
+ | | ...
+ | |--- ...
+ | |--- generic
+ | | |--- target_generic_<module name>.h
+ | | |--- ...
+ ... ... ...
+
+
+Include hierarchy is as follows.
+
+ native file <name>
+ --> include 'target_native_<module name>.h'
+ ...
+ <target specific definitions>
+ ...
+ --> include 'target_generic_<module name>.h'
+ ...
+ <generic definitions>
+ ...
+
+When writing native code, please take care with the following.
+
+ - Use _only_ ANSI C specific functions directly which are available
+ on all target systems with the same parameters, e. g. strdup() is
+ not an ANSI C function, thus is is not available on all systems; mkdir()
+ expect on some systems different parameters.
+
+ !!!Do NOT use this functions in your native code!!!
+
+ Instead
+
+ * if a function is not available, create a native macro in the file
+
+ <target name>/target_native_<module name>.h
+
+ * if it is a generic function, include a generic implementation in
+
+ generic/target_generic_<module name>.h
+
+ * Then use this macro in your native code.
+
+ - Avoid _all_ OS specific data types and constants, e. g. structures or error
+ numbers. Instead, wrap them in a native macro and convert the values to
+ basic scalar types like char, int, double or long.
+
+ - Take care with 64 bit values; the are machine dependent. Not all
+ target system support 64 bit operations. The macros in
+ target_generic_math_int.h give a set of macros implementing 64 bit
+ operations and constants.
+
+ - Avoid - if possible - non-reentrant functions. Non-reentrant functions
+ cause strange problems on some multitasking systems.
+
+ - Avoid - if possible - dynamic data types created by malloc() and similar
+ functions. Instead use (local) static variables to avoid stack usage.
+ On some target systems, dynamic memory management is either slow or even
+ dangerous. Moreover malloc()-calls can cause fragmentation of the system
+ memory, which could result in a system crash or an application failure.
+
+For some examples, please look in the current implementation for
+Linux in the directory 'target/Linux' and the generic implementation in
+the directory 'target/generic'.
+
+
+ aicas GmbH, February 2003
+
+
diff --git a/libjava/classpath/native/testsuite/.cvsignore b/libjava/classpath/native/testsuite/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/testsuite/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/testsuite/Makefile.am b/libjava/classpath/native/testsuite/Makefile.am
new file mode 100644
index 00000000000..26f2f828b16
--- /dev/null
+++ b/libjava/classpath/native/testsuite/Makefile.am
@@ -0,0 +1,2 @@
+##bin_PROGRAMS = guile-jvm
+
diff --git a/libjava/classpath/native/testsuite/guile-jvm.c b/libjava/classpath/native/testsuite/guile-jvm.c
new file mode 100644
index 00000000000..c372f75f2d8
--- /dev/null
+++ b/libjava/classpath/native/testsuite/guile-jvm.c
@@ -0,0 +1,223 @@
+/*
+ * Guile/JNI/JVM Testing Framework
+ *
+ * Copyright (c) 1998 Free Software Foundation, Inc.
+ * Written by Paul Fisher (rao@gnu.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <libguile.h>
+#include <guile/gh.h>
+#include <jni.h>
+
+static JNIEnv *env;
+static jclass test_class, result_class;
+static jmethodID test_mid, test_name_mid, result_name_mid, result_msg_mid;
+
+SCM
+abort_test (SCM name, char *exception)
+{
+ (*env)->ExceptionClear (env);
+ return gh_list (name,
+ gh_symbol2scm ("ERROR"),
+ gh_str02scm (exception),
+ SCM_UNDEFINED);
+}
+
+SCM
+handle_test_exception (jobject test_name_obj)
+{
+ jthrowable throwable;
+ jclass object_class;
+ jobject err_msg_obj;
+ char *err_msg, *test_name;
+ const char *utf;
+ SCM result;
+ jboolean is_copy;
+ static jmethodID obj_toString_mid = NULL;
+
+ throwable = (*env)->ExceptionOccurred (env);
+ (*env)->ExceptionClear (env);
+
+ if (obj_toString_mid == NULL)
+ obj_toString_mid = (*env)->GetMethodID (env,
+ (*env)->FindClass (env,
+ "java/lang/Object"),
+ "toString",
+ "()Ljava/lang/String;");
+
+ err_msg_obj = (*env)->CallObjectMethod (env, throwable, obj_toString_mid);
+
+ utf = (*env)->GetStringUTFChars (env, err_msg_obj, &is_copy);
+ err_msg = strdup (utf);
+ (*env)->ReleaseStringUTFChars (env, err_msg_obj, utf);
+
+ utf = (*env)->GetStringUTFChars (env, test_name_obj, &is_copy);
+ test_name = strdup (utf);
+ (*env)->ReleaseStringUTFChars (env, test_name_obj, utf);
+
+ result = abort_test (gh_str02scm (test_name), err_msg);
+
+ free (err_msg);
+ free (test_name);
+
+ return result;
+}
+
+SCM
+perform_test (SCM clazz_scm_name)
+{
+ char *clazz_name, *test_name, *result_name, *msg;
+ const char *utf;
+ jclass clazz;
+ jmethodID mid;
+ jobject test_obj, result_obj, test_name_obj, result_name_obj, msg_obj;
+ jboolean is_copy;
+ SCM scm_test_name, scm_result_name, scm_result_msg;
+
+ clazz_name = gh_scm2newstr (clazz_scm_name, NULL);
+ clazz = (*env)->FindClass (env, clazz_name);
+ if (clazz == NULL)
+ {
+ SCM clazz_err = gh_str02scm (clazz_name);
+ free (clazz_name);
+ return abort_test (clazz_err, "Unable to find class");
+ }
+
+ mid = (*env)->GetMethodID (env, clazz, "<init>", "()V");
+ test_obj = (*env)->NewObject (env, clazz, mid);
+
+ if ((*env)->IsInstanceOf (env, test_obj, test_class) == JNI_FALSE)
+ {
+ SCM clazz_err = gh_str02scm (clazz_name);
+ free (clazz_name);
+ return abort_test (clazz_err, "Not an instanceof gnu.test.Test");
+ }
+ free (clazz_name);
+
+ /* Call all the Java testing methods */
+ test_name_obj = (*env)->CallObjectMethod (env, test_obj, test_name_mid);
+ result_obj = (*env)->CallObjectMethod (env, test_obj, test_mid);
+
+ /* Handle an exception if one occurred */
+ if ((*env)->ExceptionOccurred (env))
+ return handle_test_exception (test_name_obj);
+
+ result_name_obj = (*env)->CallObjectMethod (env, result_obj,
+ result_name_mid);
+ msg_obj = (*env)->CallObjectMethod (env, result_obj, result_msg_mid);
+
+ /* Grab all the C result messages */
+ utf = (*env)->GetStringUTFChars (env, test_name_obj, &is_copy);
+ test_name = strdup (utf);
+ (*env)->ReleaseStringUTFChars (env, test_name_obj, utf);
+
+ utf = (*env)->GetStringUTFChars (env, result_name_obj, &is_copy);
+ result_name = strdup (utf);
+ (*env)->ReleaseStringUTFChars (env, result_name_obj, utf);
+
+ utf = (*env)->GetStringUTFChars (env, msg_obj, &is_copy);
+ msg = strdup (utf);
+ (*env)->ReleaseStringUTFChars (env, msg_obj, utf);
+
+ /* Convert the C result messages to Scheme */
+ scm_test_name = gh_str02scm (test_name);
+ scm_result_name = gh_symbol2scm (result_name);
+ scm_result_msg = gh_str02scm (msg);
+
+ /* Free up the C result messages */
+ free (test_name);
+ free (result_name);
+ free (msg);
+
+ return gh_list (scm_test_name,
+ scm_result_name,
+ scm_result_msg,
+ SCM_UNDEFINED);
+}
+
+int
+init_testing_framework ()
+{
+ JavaVM *jvm;
+ JDK1_1InitArgs vm_args;
+
+ vm_args.version = 0x00010001;
+ JNI_GetDefaultJavaVMInitArgs (&vm_args);
+ vm_args.classpath = getenv ("CLASSPATH");
+ if (JNI_CreateJavaVM (&jvm, &env, &vm_args) < 0)
+ return -1;
+
+ test_class = (*env)->FindClass (env, "gnu/test/Test");
+ if (test_class == NULL)
+ {
+ fprintf (stderr, "Unable to locate gnu.test.Test\n");
+ return -1;
+ }
+ test_class = (*env)->NewGlobalRef (env, test_class);
+
+ result_class = (*env)->FindClass (env, "gnu/test/Result");
+ if (result_class == NULL)
+ {
+ fprintf (stderr, "Unable to locate gnu.test.Result\n");
+ return -1;
+ }
+ result_class = (*env)->NewGlobalRef (env, result_class);
+
+ test_mid = (*env)->GetMethodID (env, test_class, "test",
+ "()Lgnu/test/Result;");
+ test_name_mid = (*env)->GetMethodID (env, test_class, "getName",
+ "()Ljava/lang/String;");
+ if (test_mid == NULL || test_name_mid == NULL)
+ {
+ fprintf (stderr, "Malformed gnu.test.Test class\n");
+ return -1;
+ }
+
+ result_name_mid = (*env)->GetMethodID (env, result_class, "getName",
+ "()Ljava/lang/String;");
+ result_msg_mid = (*env)->GetMethodID (env, result_class, "getMsg",
+ "()Ljava/lang/String;");
+ if (result_name_mid == NULL || result_msg_mid == NULL)
+ {
+ fprintf (stderr, "Malformed gnu.test.Result class\n");
+ return -1;
+ }
+
+ gh_new_procedure1_0 ("test", perform_test);
+ return 0;
+}
+
+static void
+inner_main (void *closure, int argc, char **argv)
+{
+ if (init_testing_framework () < 0)
+ {
+ fprintf (stderr, "Unable to instantiate JVM.\n");
+ exit (1);
+ }
+ scm_shell (argc, argv);
+}
+
+int
+main (int argc, char **argv)
+{
+ scm_boot_guile (argc, argv, inner_main, 0);
+ return 0;
+}
diff --git a/libjava/classpath/native/vmi/.cvsignore b/libjava/classpath/native/vmi/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/vmi/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/vmi/Makefile.am b/libjava/classpath/native/vmi/Makefile.am
new file mode 100644
index 00000000000..11b462a3d19
--- /dev/null
+++ b/libjava/classpath/native/vmi/Makefile.am
@@ -0,0 +1,6 @@
+## Input file for automake to generate the Makefile.in used by configure
+
+EXTRA_DIST = \
+TODO \
+vmi.c \
+vmi.h
diff --git a/libjava/classpath/native/vmi/TODO b/libjava/classpath/native/vmi/TODO
new file mode 100644
index 00000000000..8107ad4440b
--- /dev/null
+++ b/libjava/classpath/native/vmi/TODO
@@ -0,0 +1,28 @@
+TODO for JCL VMI library:
+
+API:
+- More functions will almost certainly be required. I am
+ adding them in only as needs arise to keep the job as
+ easy as possible in the short term. The full JVMDI
+ will presumably need to be mimicked.
+
+Japhar 1.1:
+- Using the JVMDI for many functions, since Japhar
+ implements JVMDI. Several JVMDI functions are not
+ implemented yet, though, so it becomes a question of
+ waiting til they are or implementing them ourselves.
+- Specifically, the JVMDI functions not yet implemented in
+ Japhar that the VMI calls are:
+ - JVMDI_GetClassModifiers()
+ - JVMDI_GetClassName()
+ - JVMDI_GetClassMethods()
+ - JVMDI_GetClassFields()
+ - JVMDI_GetImplementedInterfaces()
+ - JVMDI_IsInterface()
+ - JVMDI_IsArray()
+ - JVMDI_ClassLoader()
+ - JVMDI_GetMethodModifiers()
+ - JVMDI_GetThrownExceptions()
+ - JVMDI_GetFieldName()
+ - JVMDI_GetFieldDeclaringClass()
+ - JVMDI_GetFieldModifiers()
diff --git a/libjava/classpath/native/vmi/vmi.c b/libjava/classpath/native/vmi/vmi.c
new file mode 100755
index 00000000000..6022bedfde3
--- /dev/null
+++ b/libjava/classpath/native/vmi/vmi.c
@@ -0,0 +1,143 @@
+/* Japhar implementation of VMI.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#include <jcl.h>
+#include <vmi.h>
+#include <jvmdi.h>
+#include <interp.h>
+#include <native-threads.h>
+
+JNIEXPORT vmiError JNICALL
+VMI_GetFrameClass(JNIEnv *env,
+ jframeID frame,
+ jclass *clazz) {
+
+ return VMI_ERROR_NONE;
+}
+
+JNIEXPORT vmiError JNICALL
+VMI_GetFrameObject(JNIEnv *env,
+ jframeID frame,
+ jobject *obj) {
+ StackFrame *sframe = (StackFrame*)frame;
+ if(env == NULL || obj == NULL)
+ return VMI_ERROR_NULL_POINTER;
+ if(frame == NULL)
+ return VMI_ERROR_INVALID_FRAMEID;
+
+ *obj = THISPTR(sframe);
+ return VMI_ERROR_NONE;
+}
+
+JNIEXPORT vmiError JNICALL
+VMI_GetThisFrame(JNIEnv *env, jframeID *frame) {
+ JThreadInfo *thread_info;
+
+ if(env == NULL || frame == NULL)
+ return VMI_ERROR_NULL_POINTER;
+
+ thread_info = THREAD_getJavaInfo();
+ *frame = (jframeID)TOPFRAME(thread_info);
+ return VMI_ERROR_NONE;
+}
+
+JNIEXPORT vmiError JNICALL
+VMI_GetThisThreadObject(JNIEnv* env, jthread *thread) {
+ JThreadInfo *thread_info;
+ if(env == NULL || thread == NULL)
+ return VMI_ERROR_NULL_POINTER;
+ thread_info = THREAD_getJavaInfo();
+ *thread = (jthread)thread_info->java_thread;
+ return VMI_ERROR_NONE;
+}
+
+JNIEXPORT void JNICALL
+VMI_ThrowAppropriateException(JNIEnv *env, vmiError err) {
+ switch(err) {
+ case VMI_ERROR_NONE:
+ JCL_ThrowException(env, "java/lang/InternalError", "ERROR_NONE passed to VMI exception thrower.");
+ break;
+ case VMI_ERROR_NULL_POINTER:
+ JCL_ThrowException(env, "java/lang/NullPointerException", "null pointer in VMI detected.");
+ break;
+ case VMI_ERROR_OUT_OF_MEMORY:
+ JCL_ThrowException(env, "java/lang/OutOfMemoryError", "Out of memory! (in VMI).");
+ break;
+ case VMI_ERROR_INVALID_METHODID:
+ JCL_ThrowException(env, "java/lang/InternalError", "VMI error: INVALID_METHODID");
+ break;
+ case VMI_ERROR_INVALID_CLASS:
+ JCL_ThrowException(env, "java/lang/InternalError", "VMI error: INVALID_CLASS");
+ break;
+ case VMI_ERROR_INVALID_BCI:
+ JCL_ThrowException(env, "java/lang/InternalError", "VMI error: INVALID_BCI");
+ break;
+ case VMI_ERROR_NO_SUCH_BREAKPOINT:
+ JCL_ThrowException(env, "java/lang/InternalError", "VMI error: NO_SUCH_BREAKPOINT");
+ break;
+ case VMI_ERROR_VM_DEAD:
+ JCL_ThrowException(env, "java/lang/InternalError", "VMI error: VM Dead! Kinda makes ya wonder how this exception got thrown, huh?");
+ break;
+ case VMI_ERROR_INVALID_FRAMEID:
+ JCL_ThrowException(env, "java/lang/IllegalThreadStateException", "NULL Frame ID detected in VMI.");
+ break;
+ case VMI_ERROR_INVALID_SLOT:
+ JCL_ThrowException(env, "java/lang/InternalError", "VMI error: INVALID_SLOT");
+ break;
+ case VMI_ERROR_TYPE_MISMATCH:
+ JCL_ThrowException(env, "java/lang/InternalError", "VMI error: INVALID_SLOT");
+ break;
+ case VMI_ERROR_NATIVE_FRAME:
+ JCL_ThrowException(env, "java/lang/InternalError", "VMI error: NATIVE_FRAME");
+ break;
+ case VMI_ERROR_NO_MORE_FRAMES:
+ JCL_ThrowException(env, "java/lang/InternalError", "VMI error: NO_MORE_FRAMES");
+ break;
+ case VMI_ERROR_INVALID_THREAD:
+ JCL_ThrowException(env, "java/lang/IllegalThreadStateException", "Invalid thread in VMI.");
+ break;
+ case VMI_ERROR_THREAD_NOT_SUSPENDED:
+ JCL_ThrowException(env, "java/lang/IllegalThreadStateException", "Attempt to introspect unsuspended thread in VMI.");
+ break;
+ default:
+ JCL_ThrowException(env, "java/lang/UnknownError", "VMI returned erroneous error value ...");
+ break;
+ }
+}
+
+
diff --git a/libjava/classpath/native/vmi/vmi.h b/libjava/classpath/native/vmi/vmi.h
new file mode 100755
index 00000000000..1a8e26a8174
--- /dev/null
+++ b/libjava/classpath/native/vmi/vmi.h
@@ -0,0 +1,92 @@
+/* Japhar implementation of VMI.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef __VMI_H__
+#define __VMI_H__
+
+#include <jni.h>
+
+typedef void * jframeID;
+typedef void * jthread;
+
+typedef enum {
+ VMI_ERROR_NONE,
+ VMI_ERROR_NULL_POINTER,
+ VMI_ERROR_OUT_OF_MEMORY,
+ VMI_ERROR_INVALID_METHODID,
+ VMI_ERROR_INVALID_CLASS,
+ VMI_ERROR_INVALID_BCI,
+ VMI_ERROR_NO_SUCH_BREAKPOINT,
+ VMI_ERROR_VM_DEAD,
+ VMI_ERROR_INVALID_FRAMEID,
+ VMI_ERROR_INVALID_SLOT,
+ VMI_ERROR_TYPE_MISMATCH,
+ VMI_ERROR_NATIVE_FRAME,
+ VMI_ERROR_NO_MORE_FRAMES,
+ VMI_ERROR_INVALID_THREAD,
+ VMI_ERROR_THREAD_NOT_SUSPENDED
+} vmiError;
+
+
+#define VMI_MOD_PUBLIC 0x0001
+#define VMI_MOD_PRIVATE 0x0002
+#define VMI_MOD_PROTECTED 0x0004
+#define VMI_MOD_STATIC 0x0008
+#define VMI_MOD_FINAL 0x0010
+#define VMI_MOD_SYNCHRONIZED 0x0020
+#define VMI_MOD_VOLATILE 0x0040
+#define VMI_MOD_TRANSIENT 0x0080
+#define VMI_MOD_NATIVE 0x0100
+#define VMI_MOD_INTERFACE 0x0200
+#define VMI_MOD_ABSTRACT 0x0400
+
+JNIEXPORT vmiError JNICALL
+VMI_GetFrameClass(JNIEnv *env, jframeID frame, jobject *obj);
+
+JNIEXPORT vmiError JNICALL
+VMI_GetFrameObject(JNIEnv *env, jframeID frame, jobject *obj);
+
+JNIEXPORT vmiError JNICALL
+VMI_GetThisFrame(JNIEnv *env, jframeID *frame);
+
+JNIEXPORT vmiError JNICALL
+VMI_GetThisThreadObject(JNIEnv *env, jthread *thread);
+
+JNIEXPORT void JNICALL
+VMI_ThrowAppropriateException(JNIEnv *env, vmiError err);
+
+#endif