changeset 1461:6b24535880de

Merge from IcedTea6. 2008-12-02 Andrew John Hughes <ahughes@redhat.com> Merge from IcedTea6. * .hgignore, * ChangeLog, * HACKING, * IcedTeaPlugin.cc, * Makefile.am, * autogen.sh, * configure.ac, * javac.in, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/NetxPanel.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPPolicy.java, * overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarSigner.java, * overlays/openjdk/jdk/test/com/sun/media/sound/EmergencySoundbank/TestCreateSoundbank.java, * overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Available.java, * overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Close.java, * overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/MarkReset.java, * overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/MarkSupported.java, * overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Read.java, * overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/ReadByte.java, * overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/ReadByteIntInt.java, * overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Skip.java, * overlays/openjdk/jdk/test/com/sun/media/sound/SoftAudioSynthesizer/DummySourceDataLine.java, * overlays/openjdk/jdk/test/com/sun/media/sound/SoftFilter/TestProcessAudio.java: Merged. * patches/icedtea-4486841.patch, * patches/icedtea-6484091.patch, * patches/icedtea-6497740.patch, * patches/icedtea-6588160.patch, * patches/icedtea-6592792.patch, * patches/icedtea-6721753.patch, * patches/icedtea-6726779.patch, * patches/icedtea-6728542-epoll.patch, * patches/icedtea-6733959.patch, * patches/icedtea-6734167.patch, * patches/icedtea-6755943.patch, * patches/icedtea-6766136.patch, * patches/icedtea-ecj-pr261.patch, * patches/icedtea-samejvm-safe.patch, * patches/icedtea-stroker-finish.patch, * patches/icedtea-xrender-000.patch, * patches/icedtea-xrender-001.patch, * patches/icedtea-xrender-002.patch, * patches/icedtea-xrender-003.patch, * patches/icedtea-xrender-004.patch, * patches/icedtea-xrender-005.patch, * patches/icedtea-xrender-006.patch, * patches/icedtea-xrender-007.patch, * patches/icedtea-xrender-008.patch, * patches/icedtea-xrender-009.patch: Added. * plugin/icedtea/netscape/javascript/JSObject.java, * plugin/icedtea/sun/applet/GetWindowPluginCallRequest.java, * plugin/icedtea/sun/applet/PluginAppletSecurityContext.java, * plugin/icedtea/sun/applet/PluginAppletViewer.java, * plugin/icedtea/sun/applet/PluginMessageHandlerWorker.java, * ports/hotspot/src/share/vm/shark/sharkBlock.cpp, * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp, * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp, * ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp, * ports/hotspot/src/share/vm/shark/sharkFunction.cpp, * ports/hotspot/src/share/vm/shark/sharkValue.hpp, * test/jtreg/com/sun/javatest/regtest/Main.java, * test/jtreg/com/sun/javatest/regtest/RegressionParameters.java, * test/jtreg/com/sun/javatest/regtest/RegressionScript.java: Merged.
author Andrew John Hughes <gnu_andrew@member.fsf.org>
date Tue, 02 Dec 2008 13:58:24 +0000
parents d8e977068163 (current diff) a599dbe81c3d (diff)
children 744a654041ac
files .hgignore ChangeLog HACKING IcedTeaPlugin.cc Makefile.am configure.ac javac.in overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/NetxPanel.java overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPPolicy.java overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarSigner.java
diffstat 62 files changed, 19804 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri Nov 21 10:29:58 2008 +0000
+++ b/.hgignore	Tue Dec 02 13:58:24 2008 +0000
@@ -38,6 +38,7 @@
 test/langtools
 test/jtreg.jar
 test/jtreg/classes
+test/jtreg-summary.log
 test/check-.*log
 rt/com/sun/jdi/AbsentInformationException.java
 rt/com/sun/jdi/Accessible.java
--- a/ChangeLog	Fri Nov 21 10:29:58 2008 +0000
+++ b/ChangeLog	Tue Dec 02 13:58:24 2008 +0000
@@ -1,3 +1,126 @@
+2008-12-02  Andrew John Hughes  <ahughes@redhat.com>
+
+	Merge from IcedTea6.
+	* .hgignore,
+	* ChangeLog,
+	* HACKING,
+	* IcedTeaPlugin.cc,
+	* Makefile.am,
+	* autogen.sh,
+	* configure.ac,
+	* javac.in,
+	* overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/NetxPanel.java,
+	* overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java,
+	* overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPPolicy.java,
+	* overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarSigner.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/EmergencySoundbank/TestCreateSoundbank.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Available.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Close.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/MarkReset.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/MarkSupported.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Read.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/ReadByte.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/ReadByteIntInt.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Skip.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/SoftAudioSynthesizer/DummySourceDataLine.java,
+	* overlays/openjdk/jdk/test/com/sun/media/sound/SoftFilter/TestProcessAudio.java: Merged.
+	* patches/icedtea-4486841.patch,
+	* patches/icedtea-6484091.patch,
+	* patches/icedtea-6497740.patch,
+	* patches/icedtea-6588160.patch,
+	* patches/icedtea-6592792.patch,
+	* patches/icedtea-6721753.patch,
+	* patches/icedtea-6726779.patch,
+	* patches/icedtea-6728542-epoll.patch,
+	* patches/icedtea-6733959.patch,
+	* patches/icedtea-6734167.patch,
+	* patches/icedtea-6755943.patch,
+	* patches/icedtea-6766136.patch,
+	* patches/icedtea-ecj-pr261.patch,
+	* patches/icedtea-samejvm-safe.patch,
+	* patches/icedtea-stroker-finish.patch,
+	* patches/icedtea-xrender-000.patch,
+	* patches/icedtea-xrender-001.patch,
+	* patches/icedtea-xrender-002.patch,
+	* patches/icedtea-xrender-003.patch,
+	* patches/icedtea-xrender-004.patch,
+	* patches/icedtea-xrender-005.patch,
+	* patches/icedtea-xrender-006.patch,
+	* patches/icedtea-xrender-007.patch,
+	* patches/icedtea-xrender-008.patch,
+	* patches/icedtea-xrender-009.patch: Added.
+	* plugin/icedtea/netscape/javascript/JSObject.java,
+	* plugin/icedtea/sun/applet/GetWindowPluginCallRequest.java,
+	* plugin/icedtea/sun/applet/PluginAppletSecurityContext.java,
+	* plugin/icedtea/sun/applet/PluginAppletViewer.java,
+	* plugin/icedtea/sun/applet/PluginMessageHandlerWorker.java,
+	* ports/hotspot/src/share/vm/shark/sharkBlock.cpp,
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.cpp,
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.hpp,
+	* ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp,
+	* ports/hotspot/src/share/vm/shark/sharkFunction.cpp,
+	* ports/hotspot/src/share/vm/shark/sharkValue.hpp,
+	* test/jtreg/com/sun/javatest/regtest/Main.java,
+	* test/jtreg/com/sun/javatest/regtest/RegressionParameters.java,
+	* test/jtreg/com/sun/javatest/regtest/RegressionScript.java: Merged.
+
+2008-12-02  Lillian Angel  <langel@redhat.com>
+
+	* Makefile.am
+	(ICEDTEA_PATCHES): Added new OpenJDK security patches.
+	* patches/icedtea-4486841.patch,
+	patches/icedtea-6484091.patch,
+	patches/icedtea-6497740.patch,
+	patches/icedtea-6588160.patch,
+	patches/icedtea-6592792.patch,
+	patches/icedtea-6721753.patch,
+	patches/icedtea-6726779.patch,
+	patches/icedtea-6733959.patch,
+	patches/icedtea-6734167.patch,
+	patches/icedtea-6755943.patch,
+	patches/icedtea-6766136.patch: New file
+	
+2008-11-30  Mark Wielaard  <mark@klomp.org>
+
+	* patches/icedtea-xrender-001.patch: Remove !xrender bug fix.
+	* patches/icedtea-xrender-009.patch: New upstream patch, includes
+	bug fix.
+
+2008-11-30  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (stamps/native-ecj.stamp): Use -findirect-dispatch.
+	* javac.in: Use ecj binary if available and no native-ecj.
+
+2008-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Add and check --enable-xrender.
+	* Makefile.am: Add XRENDER_PATCHES when ENABLE_XRENDER set.
+	* patches/icedtea-xrender-00[0-8].patch: New patches.
+	* HACKING: Document new patches.
+
+2008-11-28  Gary Benson  <gbenson@redhat.com>
+
+	PR icedtea/265:
+	* patches/icedtea-6728542-epoll.patch: New file.
+	* Makefile.am (ICEDTEA_PATCHES): Apply the above.
+	* HACKING: Document the above.
+
+2008-11-28  Gary Benson  <gbenson@redhat.com>
+
+	PR icedtea/261:
+	* patches/icedtea-ecj-pr261.patch: New file.
+	* Makefile.am (ICEDTEA_ECJ_PATCHES): Apply the above.
+	* HACKING: Document the above.
+
+2008-11-28  Mark Wielaard  <mark@klomp.org>
+
+	* autogen.sh: Check for autoconf > 2.61.
+	* configure.ac: Remove AC_PREREQ([2.61]).
+
+2008-11-26  Mark Wielaard  <mark@klomp.org>
+
+	* .hgignore: Add test/jtreg-summary.log.
+
 2008-11-21  Andrew John Hughes  <ahughes@redhat.com>
 
 	* Makefile.am:
@@ -16,7 +139,6 @@
 	* configure.ac: Bump to 1.8.
 
 2008-11-20  Andrew John Hughes  <ahughes@redhat.com>
-
 	PR icedtea/236:
 	* gcjwebplugin.cc,
 	* Makefile.am,
@@ -140,6 +262,120 @@
 	* test/jtreg/excludelist.langtools.jtx:
 	Exclude broken tests.
 
+2008-11-25  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (jtregcheck): Fix regexp.
+
+2008-11-24  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (jtregcheck): Clean up jtreg-summary.log a bit more.
+
+2008-11-24  Mark Wielaard  <mark@klomp.org>
+
+	* overlays/openjdk/jdk/test/com/sun/media/sound/
+	EmergencySoundbank/TestCreateSoundbank.java
+	ModelByteBuffer/RandomFileInputStream/Available.java
+	ModelByteBuffer/RandomFileInputStream/Close.java
+	ModelByteBuffer/RandomFileInputStream/MarkReset.java
+	ModelByteBuffer/RandomFileInputStream/MarkSupported.java
+	ModelByteBuffer/RandomFileInputStream/Read.java
+	ModelByteBuffer/RandomFileInputStream/ReadByte.java
+	ModelByteBuffer/RandomFileInputStream/ReadByteIntInt.java
+	ModelByteBuffer/RandomFileInputStream/Skip.java
+	SoftAudioSynthesizer/DummySourceDataLine.java
+	SoftFilter/TestProcessAudio.java
+	SoftSynthesizer/DummySourceDataLine.java: Add missing Gervill
+	test files.
+
+2008-11-23  Mark Wielaard  <mark@klomp.org>
+
+	* patches/icedtea-samejvm-safe.patch: New patch.
+	* Makefile.am (ICEDTEA_PATCHES): Add new patch.
+	(check-jdk): Run jtreg with -samevm.
+	* HACKING: Document new patch.
+
+2008-11-23  Mark Wielaard  <mark@klomp.org>
+
+	* test/jtreg/com/sun/javatest/regtest/Main.java
+	(createParameters): Set same jvm safe dirs when non-null.
+	(getSameJVMSafeDirs): New method that reads samejvmsafe property
+	from TEST.ROOT.
+	(sameJVMSafeDirs): New private field.
+	* test/jtreg/com/sun/javatest/regtest/RegressionParameters.java
+	(SAME_JVM_SAFE_DIRS): New static final field.
+	(load): Read same jvm safe dirs.
+	(save0): Write same jvm safe dirs.
+	(getSameJVMSafeDirs): New method.
+	(setSameJVMSafeDirs): New method.
+	* test/jtreg/com/sun/javatest/regtest/RegressionScript.java
+	(run): Set testDirPath.
+	(isOtherJVM): Take same jvm safe into account.
+	(isSameJVMSafe): New method.
+	(testDirPath): New private field.
+
+2008-11-21  Deepak Bhole  <dbhole@redhat.com>
+
+	* IcedTeaPlugin.cc: Fix a mistake in previous commit re: integer overflow.
+
+2008-11-21  Mark Wielaard  <mark@klomp.org>
+
+	* patches/icedtea-stroker-finish.patch: New patch.
+	* Makefile.am (ICEDTEA_PATCHES): Add new patch.
+	* HACKING: Document new patch.
+
+2008-11-21  Deepak Bhole  <dbhole@redhat.com>
+
+	* IcedTeaPlugin.cc: Handle memory address->string encoding correctly
+	depending on arch/word size.
+	* plugin/icedtea/netscape/javascript/JSObject.java: Use only long for
+	internal variable, to be on the safe side.
+	* plugin/icedtea/sun/applet/GetWindowPluginCallRequest.java: Ditto.
+	* plugin/icedtea/sun/applet/PluginAppletViewer.java: Rewrite
+	network->local image cache mapping code to prevent freezes on certain
+	sites. Add support for java_code, java_codebase, etc.
+	* plugin/icedtea/sun/applet/PluginMessageHandlerWorker.java: Fix race
+	condition that froze the vm under the right circumstances.
+	* rt/net/sourceforge/jnlp/NetxPanel.java: Provide function to return the
+	applet classloader.
+
+2008-11-21 Andrew Haley <aph@redhat.com>
+
+	* ports/hotspot/src/share/vm/shark/sharkValue.hpp
+	(class SharkComputableValue): Use IRBuilder<>, not IRBuilder.
+	(class SharkValue): Use IRBuilder<>, not IRBuilder.
+	* ports/hotspot/src/share/vm/shark/sharkFunction.cpp
+	(SharkFunction::CreatePopFrame): Change a few jint_types to
+	intptr_types.
+	* ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp
+	(SharkConstantPool::cache_entry_at): Byte-swap the cache index.
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.cpp
+	(SharkBuilder::SharkBuilder) Inherit from template class
+	IRBuilder<>.
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.hpp:
+	(SharkBuilder::SharkBuilder) Inherit from template class
+	IRBuilder<>.
+	Change a few jint_types to intptr_types.
+	* ports/hotspot/src/share/vm/shark/sharkBlock.cpp
+	(SharkBlock::get_interface_callee): Change a few jint_types to
+	intptr_types.
+
+2008-11-18  Deepak Bhole  <dbhole@redhat.com>
+	* IcedTeaPlugin.cc: Encode newline characters instead of stripping them.
+	* plugin/icedtea/sun/applet/PluginAppletSecurityContext.java: Minor debug
+	output change.
+	* plugin/icedtea/sun/applet/PluginAppletViewer.java: Fix bug in code that
+	computed width factor. Try to load images from local cache first. Decode
+	newline characters. Update parser to skip comments in applet tag.
+	* rt/net/sourceforge/jnlp/runtime/JNLPPolicy.java: Take into consideration
+	system policy in addition to applet policy when determining permissions.
+	* rt/net/sourceforge/jnlp/tools/JarSigner.java: Return immediately if jar
+	could not be fetched.
+
+2008-11-17  Omair Majid  <omajid@redhat.com>
+
+	* HACKING: Document icedtea-alsa-default-device.patch and
+	icedtea-linker-libs-order.patch.
+
 2008-11-17  Matthias Klose  <doko@ubuntu.com>
 
 	* fsg.sh: Don't remove xml-stylesheet files.
--- a/HACKING	Fri Nov 21 10:29:58 2008 +0000
+++ b/HACKING	Tue Dec 02 13:58:24 2008 +0000
@@ -64,12 +64,18 @@
 * icedtea-alt-jar.patch: Add support for using an alternate jar tool in JDK building. 
 * icedtea-hotspot7-tests.patch: Adds hotspot compiler tests from jdk7 tree.
 * icedtea-renderer-crossing.patch: Check whether crossing is initialized in Pisces Renderer.
+* icedtea-stroker-finish.patch: Make sure cap calculation doesn't result in
+  divide by zero on tiny paths.
+* icedtea-alsa-default-device.patch: Fix problems with using the ALSA 'default' device.
+* icedtea-linker-libs-order.patch: When linking, put the referenced libraries after the object files (PR237).
 * icedtea-f2i-overflow.patch: Replaces the code used by [fd]2[il] bytecodes to correctly handle overflows. (PR244)
 * icedtea-cc-interp-no-fer.patch: Report that we cannot force early returns with the C++ interpreter.
 * icedtea-6761856-freetypescaler.patch: Fix IcedTea bug #227, OpenJDK bug
   #6761856, swing TextLayout.getBounds() returns shifted bounds.
 * icedtea-display-mode-changer.patch: Add extra test class.
 * icedtea-testenv.patch: Provide public reachable machines for net/nio tests.
+* icedtea-samejvm-safe.patch: Add samejvmsafe dirs to TEST.ROOT.
+* icedtea-6728542-epoll.patch: Make EPoll work on non-x86 platforms. (PR265)
 
 The following patches are only applied to OpenJDK6 in IcedTea6:
 
@@ -104,7 +110,8 @@
   javac executable with Ant, remove -Werror from javac call, don't build JDK demos,
   don't run sun.awt.X11.ToBin, explicitly pull in timezone data and rt.jar in javac
   calls, replace hexadecimal floating point literals with decimal variants in
-  java.lang.Double and java.lang.Float.   
+  java.lang.Double and java.lang.Float.
+* icedtea-ecj-pr261.patch: Adds a couple of classes that are omitted from rt.jar. (PR261)
 
 The following patches are only applied for IcedTea builds using the zero-assembler:
 
@@ -140,6 +147,11 @@
 
 * icedtea-cacao.patch: Don't run 'java' in a new thread.
 
+The following patches are to support Xrender pipeline (-Dsun.java2d.xrender):
+
+* icedtea-xrender-xxx.patch: Numbered patches from xrender branch
+  http://hg.openjdk.java.net/xrender/xrender/jdk
+
 Obsolete Patches
 ================
 
--- a/IcedTeaPlugin.cc	Fri Nov 21 10:29:58 2008 +0000
+++ b/IcedTeaPlugin.cc	Tue Dec 02 13:58:24 2008 +0000
@@ -194,6 +194,7 @@
 	return tv.tv_usec;
 }
 
+
 inline long get_time_in_s()
 {
 	time_t t;
@@ -342,15 +343,12 @@
 #include <queue>
 #include <nsCOMPtr.h>
 #include <nsIThread.h>
+#include <nspr.h>
 
 PRMonitor *jvmMsgQueuePRMonitor;
 std::queue<nsCString> jvmMsgQueue;
 nsCOMPtr<nsIThread> processThread;
 
-#include <nspr.h>
-
-#include <prtypes.h>
-
 // IcedTeaJNIEnv helpers.
 class JNIReference
 {
@@ -700,9 +698,10 @@
 //   printf ("RECEIVE_BOOLEAN: %s result: %x = %s\n",              \
 //           __func__, result, *result ? "true" : "false");
 
-#include <nscore.h>
 #include <nsISupports.h>
 #include <nsIFactory.h>
+#include <nscore.h>
+#include <prtypes.h>
 
 // Factory functions.
 extern "C" NS_EXPORT nsresult NSGetFactory (nsISupports* aServMgr,
@@ -901,7 +900,33 @@
 #include <nsILiveconnect.h>
 #include <nsICollection.h>
 #include <nsIProcess.h>
-#include <map>
+
+#ifndef __STDC_FORMAT_MACROS
+# define __STDC_FORMAT_MACROS
+#endif
+
+#include <inttypes.h>
+
+inline void js_id_to_string(char** str, PLUGIN_JAVASCRIPT_TYPE jsid)
+{
+	if (sizeof(PLUGIN_JAVASCRIPT_TYPE) == 4)
+		sprintf(*str, "%"PRId32, jsid);
+
+	if (sizeof(PLUGIN_JAVASCRIPT_TYPE) == 8)
+		sprintf(*str, "%"PRId64, jsid);
+}
+
+inline PLUGIN_JAVASCRIPT_TYPE string_to_js_id(nsCString str)
+{
+	if (sizeof(PLUGIN_JAVASCRIPT_TYPE) == sizeof(int))
+		return atoi(str.get());
+
+	if (sizeof(PLUGIN_JAVASCRIPT_TYPE) == sizeof(long))
+		return atol(str.get());
+
+	if (sizeof(PLUGIN_JAVASCRIPT_TYPE) == sizeof(long long))
+		return atoll(str.get());
+}
 
 class IcedTeaJNIEnv;
 
@@ -988,7 +1013,7 @@
   PRUint32 next_instance_identifier;
   PRUint32 object_identifier_return;
   PRUint32 instance_count;
-  int javascript_identifier;
+  PLUGIN_JAVASCRIPT_TYPE javascript_identifier;
   int name_identifier;
   int args_identifier;
   int string_identifier;
@@ -1334,7 +1359,6 @@
 #include <nsPIPluginInstancePeer.h>
 #include <nsIPluginInstanceOwner.h>
 #include <nsIRunnable.h>
-#include <iostream>
 
 class IcedTeaRunnable : public nsIRunnable
 {
@@ -2310,10 +2334,28 @@
   tagMessage += appletTag;
   tagMessage += "</embed>";
 
-  // remove newline characters from the message
-  tagMessage.StripChars("\r\n");
-
-  factory->SendMessageToAppletViewer (tagMessage);
+  PLUGIN_DEBUG_1ARG("TAG FROM BROWSER = %s\n", tagMessage.get());
+
+  // encode newline characters in the message
+  nsCString toSend("");
+  for (int i=0; i < tagMessage.Length(); i++)
+  {
+	  if (tagMessage.get()[i] == '\r')
+	  {
+		  toSend += "&#13;";
+		  continue;
+	  }
+
+	  if (tagMessage.get()[i] == '\n')
+	  {
+		  toSend += "&#10;";
+		  continue;
+	  }
+
+	  toSend += tagMessage.get()[i];
+  }
+
+  factory->SendMessageToAppletViewer (toSend);
 
   // Set back-pointer to peer instance.
   PLUGIN_DEBUG_1ARG ("SETTING PEER!!!: %p\n", aPeer);
@@ -2894,8 +2936,8 @@
           PLUGIN_DEBUG_0ARG ("POSTING GetMember\n");
           space = rest.FindChar (' ');
           nsDependentCSubstring javascriptID = Substring (rest, 0, space);
-          javascript_identifier = javascriptID.ToInteger (&conversionResult);
-          PLUGIN_CHECK ("parse javascript id", conversionResult);
+          javascript_identifier = string_to_js_id ((nsCString) javascriptID);
+          PLUGIN_DEBUG_1ARG ("parse javascript id %ld\n", javascript_identifier);
           nsDependentCSubstring nameID = Substring (rest, space + 1);
           name_identifier = nameID.ToInteger (&conversionResult);
           PLUGIN_CHECK ("parse name id", conversionResult);
@@ -2912,8 +2954,8 @@
           PLUGIN_DEBUG_0ARG ("POSTING SetMember\n");
           space = rest.FindChar (' ');
           nsDependentCSubstring javascriptID = Substring (rest, 0, space);
-          javascript_identifier = javascriptID.ToInteger (&conversionResult);
-          PLUGIN_CHECK ("parse javascript id", conversionResult);
+          javascript_identifier = string_to_js_id ((nsCString) javascriptID);
+          PLUGIN_DEBUG_1ARG ("parse javascript id %ld\n", javascript_identifier);
           nsDependentCSubstring nameAndValue = Substring (rest, space + 1);
           space = nameAndValue.FindChar (' ');
           nsDependentCSubstring nameID = Substring (nameAndValue, 0, space);
@@ -2936,8 +2978,8 @@
           PLUGIN_DEBUG_0ARG ("POSTING GetSlot\n");
           space = rest.FindChar (' ');
           nsDependentCSubstring javascriptID = Substring (rest, 0, space);
-          javascript_identifier = javascriptID.ToInteger (&conversionResult);
-          PLUGIN_CHECK ("parse javascript id", conversionResult);
+          javascript_identifier = string_to_js_id ((nsCString) javascriptID);
+          PLUGIN_DEBUG_1ARG ("parse javascript id %ld\n", javascript_identifier);
           nsDependentCSubstring indexStr = Substring (rest, space + 1);
           slot_index = indexStr.ToInteger (&conversionResult);
           PLUGIN_CHECK ("parse name id", conversionResult);
@@ -2954,8 +2996,8 @@
           PLUGIN_DEBUG_0ARG ("POSTING SetSlot\n");
           space = rest.FindChar (' ');
           nsDependentCSubstring javascriptID = Substring (rest, 0, space);
-          javascript_identifier = javascriptID.ToInteger (&conversionResult);
-          PLUGIN_CHECK ("parse javascript id", conversionResult);
+          javascript_identifier = string_to_js_id ((nsCString) javascriptID);
+          PLUGIN_DEBUG_1ARG ("parse javascript id %ld\n", javascript_identifier);
           nsDependentCSubstring nameAndValue = Substring (rest, space + 1);
           space = nameAndValue.FindChar (' ');
           nsDependentCSubstring indexStr = Substring (nameAndValue, 0, space);
@@ -2977,8 +3019,8 @@
           PLUGIN_DEBUG_0ARG ("POSTING Eval\n");
           space = rest.FindChar (' ');
           nsDependentCSubstring javascriptID = Substring (rest, 0, space);
-          javascript_identifier = javascriptID.ToInteger (&conversionResult);
-          PLUGIN_CHECK ("parse javascript id", conversionResult);
+          javascript_identifier = string_to_js_id ((nsCString) javascriptID);
+          PLUGIN_DEBUG_1ARG ("parse javascript id %ld\n", javascript_identifier);
           nsDependentCSubstring stringID = Substring (rest, space + 1);
           string_identifier = stringID.ToInteger (&conversionResult);
           PLUGIN_CHECK ("parse string id", conversionResult);
@@ -2995,8 +3037,8 @@
           PLUGIN_DEBUG_0ARG ("POSTING RemoveMember\n");
           space = rest.FindChar (' ');
           nsDependentCSubstring javascriptID = Substring (rest, 0, space);
-          javascript_identifier = javascriptID.ToInteger (&conversionResult);
-          PLUGIN_CHECK ("parse javascript id", conversionResult);
+          javascript_identifier = string_to_js_id ((nsCString) javascriptID);
+          PLUGIN_DEBUG_1ARG ("parse javascript id %ld\n", javascript_identifier);
           nsDependentCSubstring nameID = Substring (rest, space + 1);
           name_identifier = nameID.ToInteger (&conversionResult);
           PLUGIN_CHECK ("parse name id", conversionResult);
@@ -3013,8 +3055,8 @@
           PLUGIN_DEBUG_0ARG ("POSTING Call\n");
           space = rest.FindChar (' ');
           nsDependentCSubstring javascriptID = Substring (rest, 0, space);
-          javascript_identifier = javascriptID.ToInteger (&conversionResult);
-          PLUGIN_CHECK ("parse javascript id", conversionResult);
+          javascript_identifier = string_to_js_id ((nsCString) javascriptID);
+          PLUGIN_DEBUG_1ARG ("parse javascript id %ld\n", javascript_identifier);
           nsDependentCSubstring nameAndArgs = Substring (rest, space + 1);
           space = nameAndArgs.FindChar (' ');
           nsDependentCSubstring nameID = Substring (nameAndArgs, 0, space);
@@ -3034,9 +3076,8 @@
       else if (command == "Finalize")
         {
           PLUGIN_DEBUG_0ARG ("POSTING Finalize\n");
-          nsDependentCSubstring javascriptID = Substring (rest, 0, space);
-          javascript_identifier = rest.ToInteger (&conversionResult);
-          PLUGIN_CHECK ("parse javascript id", conversionResult);
+          javascript_identifier = string_to_js_id ((nsCString) rest);
+          PLUGIN_DEBUG_1ARG ("parse javascript id %ld\n", javascript_identifier);
 
           nsCOMPtr<nsIRunnable> event =
             new IcedTeaRunnableMethod<IcedTeaPluginFactory>
@@ -3048,8 +3089,8 @@
       else if (command == "ToString")
         {
           PLUGIN_DEBUG_0ARG ("POSTING ToString\n");
-          javascript_identifier = rest.ToInteger (&conversionResult);
-          PLUGIN_CHECK ("parse javascript id", conversionResult);
+          javascript_identifier = string_to_js_id ((nsCString) rest);
+          PLUGIN_DEBUG_1ARG ("parse javascript id %ld\n", javascript_identifier);
 
           nsCOMPtr<nsIRunnable> event =
             new IcedTeaRunnableMethod<IcedTeaPluginFactory>
@@ -3878,18 +3919,24 @@
                                                NULL, 0, NULL,
                                                &liveconnect_window);
       PLUGIN_CHECK ("get window", result);
-      PLUGIN_DEBUG_1ARG ("HERE 24: %d\n", liveconnect_window);
+      PLUGIN_DEBUG_1ARG ("HERE 24: %ld\n", liveconnect_window);
     }
 
-  PLUGIN_DEBUG_1ARG ("HERE 20: %d\n", liveconnect_window);
+  PLUGIN_DEBUG_1ARG ("HERE 20: %ld\n", liveconnect_window);
+
+  char *windowAddr;
+  windowAddr = (char*) malloc(20*sizeof(char));
+  js_id_to_string(&windowAddr, liveconnect_window);
 
   nsCString message ("context ");
   message.AppendInt (0);
   message += " ";
   message += "JavaScriptGetWindow";
   message += " ";
-  message.AppendInt ((PRUintn) liveconnect_window);
+  message += windowAddr;
   factory->SendMessageToAppletViewer (message);
+
+  free(windowAddr);
 }
 
 IcedTeaPluginInstance::~IcedTeaPluginInstance ()
@@ -4392,7 +4439,6 @@
 #include <nsITransport.h>
 #include <nsNetCID.h>
 #include <nsServiceManagerUtils.h>
-#include <iostream>
 #include <nsIPrincipal.h>
 #include <nsIScriptSecurityManager.h>
 #include <nsIURI.h>
@@ -4592,6 +4638,7 @@
   PLUGIN_TRACE_JNIENV ();
   nsCString retstr ("");
 
+  char* longVal = (char*) malloc(sizeof(char)*20);
   switch (type)
     {
     case jboolean_type:
@@ -4610,7 +4657,8 @@
       retstr.AppendInt (value.i);
       break;
     case jlong_type:
-      retstr.AppendInt ((PRUintn) value.j);
+      sprintf(longVal, "%"PRId64, value.j);
+      retstr += longVal;
       break;
     case jfloat_type:
       retstr += IcedTeaPrintfCString ("%f", value.f);
@@ -4627,6 +4675,8 @@
       break;
     }
 
+  free(longVal);
+
   // Freed by calling function.
   return strdup (retstr.get ());
 }
@@ -4716,6 +4766,7 @@
   // Method.
   int arg = 0;
   char* fl;
+  char* longVal = (char*) malloc(sizeof(char)*20);
   while (id->signature[i] != stopchar)
     {
       switch (id->signature[i])
@@ -4739,7 +4790,8 @@
           retstr.AppendInt (args[arg].i);
           break;
         case 'J':
-          retstr.AppendInt ((PRUintn) args[arg].j);
+          sprintf(longVal, "%"PRId64, args[arg].j);
+          retstr += longVal;
           break;
         case 'F':
           retstr += IcedTeaPrintfCString ("%f", args[arg].f);
@@ -4787,6 +4839,8 @@
 	  arg++;
     }
 
+  free(longVal);
+
   // Freed by calling function.
   return strdup (retstr.get ());
 }
--- a/Makefile.am	Fri Nov 21 10:29:58 2008 +0000
+++ b/Makefile.am	Tue Dec 02 13:58:24 2008 +0000
@@ -1842,6 +1842,7 @@
 	patches/icedtea-snmp.patch \
 	patches/icedtea-sound.patch \
 	patches/icedtea-tests-jdk.patch \
+	patches/icedtea-stroker-finish.patch \
 	patches/icedtea-alsa-default-device.patch \
 	patches/icedtea-linker-libs-order.patch \
 	patches/icedtea-f2i-overflow.patch \
@@ -1849,7 +1850,20 @@
 	patches/icedtea-6761856-freetypescaler.patch \
 	patches/icedtea-display-mode-changer.patch \
 	patches/icedtea-testenv.patch \
-	$(ZERO_PATCHES_COND)
+	$(ZERO_PATCHES_COND) \
+	patches/icedtea-samejvm-safe.patch \
+	patches/icedtea-6728542-epoll.patch \
+	patches/icedtea-4486841.patch \
+        patches/icedtea-6484091.patch \
+        patches/icedtea-6497740.patch \
+        patches/icedtea-6588160.patch \
+        patches/icedtea-6592792.patch \
+        patches/icedtea-6721753.patch \
+        patches/icedtea-6726779.patch \
+        patches/icedtea-6733959.patch \
+        patches/icedtea-6734167.patch \
+        patches/icedtea-6755943.patch \
+        patches/icedtea-6766136.patch
 
 if WITH_RHINO
 ICEDTEA_PATCHES += \
@@ -1868,6 +1882,11 @@
 	patches/icedtea-pulse-soundproperties.patch
 endif
 
+if ENABLE_XRENDER
+XRENDER_PATCHES = patches/icedtea-xrender-???.patch
+ICEDTEA_PATCHES += $(sort $(wildcard $(XRENDER_PATCHES)))
+endif
+
 if !USE_CVMI
 ICEDTEA_PATCHES += \
 	patches/icedtea-javafiles.patch
@@ -2137,7 +2156,8 @@
 # Patch OpenJDK for plug replacements and ecj.
 ICEDTEA_ECJ_PATCHES = patches/icedtea-ecj.patch \
 	patches/icedtea-ecj-spp.patch \
-	patches/icedtea-ecj-jopt.patch
+	patches/icedtea-ecj-jopt.patch \
+	patches/icedtea-ecj-pr261.patch
 
 stamps/patch-ecj.stamp: stamps/clone-ecj.stamp
 	mkdir -p stamps; \
@@ -2467,7 +2487,7 @@
 stamps/native-ecj.stamp:
 	mkdir -p stamps 
 if BUILD_NATIVE_ECJ
-	${GCJ} ${CFLAGS} -Wl,-Bsymbolic -o native-ecj \
+	${GCJ} ${CFLAGS} -Wl,-Bsymbolic -findirect-dispatch -o native-ecj \
 	    --main=org.eclipse.jdt.internal.compiler.batch.Main ${ECJ_JAR}
 endif
 	touch stamps/native-ecj.stamp
@@ -2926,7 +2946,7 @@
 	mkdir -p test/jdk/JTwork test/jdk/JTreport
 	$(ICEDTEA_BOOT_DIR)/bin/java -jar test/jtreg.jar -v1 -a -ignore:quiet \
 		-w:test/jdk/JTwork -r:test/jdk/JTreport \
-		-jdk:`pwd`/$(BUILD_OUTPUT_DIR)/j2sdk-image \
+		-s -jdk:`pwd`/$(BUILD_OUTPUT_DIR)/j2sdk-image \
 		-exclude:$(abs_top_srcdir)/test/jtreg/excludelist.jdk.jtx \
 		`pwd`/openjdk/jdk/test \
 	    | tee test/$@.log
@@ -2945,7 +2965,7 @@
 jtregcheck: jtreg check-hotspot check-langtools check-jdk
 	for i in hotspot langtools jdk; do \
 	  echo "--------------- jtreg console summary for $$i ---------------"; \
-	  egrep -v '^(Passed:|Directory)' test/check-$$i.log; \
+	  egrep -v '^(Passed:|Directory|Re[a-z]+\ written\ to)' test/check-$$i.log; \
 	done | tee test/jtreg-summary.log
 
 	: # kill testsuite processes still hanging
--- a/autogen.sh	Fri Nov 21 10:29:58 2008 +0000
+++ b/autogen.sh	Tue Dec 02 13:58:24 2008 +0000
@@ -11,7 +11,7 @@
         AUTOCONF_VERSION=`${AUTOCONF} --version | sed 's/^[^0-9]*\([0-9.][0-9.]*\).*/\1/'`
 #        echo ${AUTOCONF_VERSION}
         case ${AUTOCONF_VERSION} in
-            2.59* | 2.6[0-9]* )
+            2.6[1-9]* )
                 HAVE_AUTOCONF=true
                 break;
                 ;;
@@ -55,7 +55,7 @@
 
 if test ${HAVE_AUTOCONF} = false; then
     echo "No proper autoconf was found."
-    echo "You must have autoconf 2.59 or later installed."
+    echo "You must have autoconf 2.61 or later installed."
     exit 1
 fi
 
--- a/configure.ac	Fri Nov 21 10:29:58 2008 +0000
+++ b/configure.ac	Tue Dec 02 13:58:24 2008 +0000
@@ -1,4 +1,3 @@
-AC_PREREQ([2.61])
 AC_INIT([icedtea], [1.9-pre], [distro-pkg-dev@openjdk.java.net])
 AM_INIT_AUTOMAKE([1.10 tar-pax foreign])
 AC_CONFIG_FILES([Makefile])
@@ -152,6 +151,14 @@
 AM_CONDITIONAL([ENABLE_DOCS], [test x$ENABLE_DOCS = xyes])
 AC_MSG_RESULT(${ENABLE_DOCS})
 
+AC_MSG_CHECKING([whether to include the XRender pipeline])
+AC_ARG_ENABLE([xrender],
+	      [AS_HELP_STRING([--disable-xrender],
+	      		      [Disable inclusion of xrender pipeline])],
+	      [ENABLE_XRENDER="${enableval}"], [ENABLE_XRENDER='yes'])
+AM_CONDITIONAL([ENABLE_XRENDER], [test x$ENABLE_XRENDER = xyes])
+AC_MSG_RESULT(${ENABLE_XRENDER})
+
 AC_MSG_CHECKING([whether to build VisualVM])
 AC_ARG_ENABLE([visualvm],
               [AS_HELP_STRING([--enable-visualvm],
@@ -381,6 +388,16 @@
 AC_SUBST(XINERAMA_CFLAGS)
 AC_SUBST(XINERAMA_LIBS)
 
+if test "x${ENABLE_XRENDER}" = "xyes"
+then
+  PKG_CHECK_MODULES(XRENDER, xrender, [XRENDER_FOUND=yes], [XRENDER_FOUND=no])
+  if test "x${XRENDER_FOUND}" = xno
+  then
+    AC_MSG_ERROR([Could not find Xrender extension - \
+Try installing libXrender-devel or configure --disable-xrender.])
+  fi
+fi
+
 dnl Check for libpng headers and libraries.
 PKG_CHECK_MODULES(LIBPNG, libpng,[LIBPNG_FOUND=yes]
 	,[LIBPNG_FOUND=no])
--- a/javac.in	Fri Nov 21 10:29:58 2008 +0000
+++ b/javac.in	Tue Dec 02 13:58:24 2008 +0000
@@ -35,6 +35,10 @@
 {
     exec '@abs_top_builddir@/native-ecj', '-1.5', '-nowarn', @bcoption, @new_args ;
 }
+else if ( -e "@ECJ@" )
+{
+    exec '@ECJ@', '-1.5', '-nowarn', @bcoption, @new_args ;
+}
 else
 {
     exec '@JAVA@', 'org.eclipse.jdt.internal.compiler.batch.Main', '-1.5',
--- a/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/NetxPanel.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/NetxPanel.java	Tue Dec 02 13:58:24 2008 +0000
@@ -40,6 +40,7 @@
 {
     private PluginBridge bridge = null;
     private boolean exitOnFailure = true;
+    private AppletInstance appInst = null;
 
     public NetxPanel(URL documentURL, Hashtable atts)
     {
@@ -81,7 +82,7 @@
     		status = APPLET_LOAD;
 
     		Launcher l = new Launcher(exitOnFailure);
-    		AppletInstance appInst = null;
+    		
                 try {
                     appInst = (AppletInstance) l.launch(bridge, this);
                 } catch (LaunchException e) {
@@ -128,5 +129,9 @@
     	this.atts.put("height", Integer.toString(height));
     	this.atts.put("width", Integer.toString(width));
     }
+    
+    public ClassLoader getAppletClassLoader() {
+        return appInst.getClassLoader();
+    }
 }
 
--- a/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Tue Dec 02 13:58:24 2008 +0000
@@ -29,6 +29,7 @@
 import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.Permissions;
+import java.security.Policy;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Enumeration;
@@ -434,7 +435,7 @@
         // add in the permissions that the user granted.
         for (int i=0; i < runtimePermissions.size(); i++)
         	result.add(runtimePermissions.get(i));
-        
+
         return result;
     }
 
@@ -731,7 +732,7 @@
 
                         }
 
-                        // If it still fails, let it error out
+                        // If it still fails, let it error out                        
                         result = loadClassExt(name);
                     }
                 }
--- a/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPPolicy.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/runtime/JNLPPolicy.java	Tue Dec 02 13:58:24 2008 +0000
@@ -18,6 +18,7 @@
 package net.sourceforge.jnlp.runtime;
 
 import java.security.*;
+import java.util.Enumeration;
 
 /**
  * Policy for JNLP environment.  This class delegates to the
@@ -60,7 +61,15 @@
         if (JNLPRuntime.getApplication() != null) {
         	if (JNLPRuntime.getApplication().getClassLoader() instanceof JNLPClassLoader) {
         		JNLPClassLoader cl = (JNLPClassLoader) JNLPRuntime.getApplication().getClassLoader();
-        		return cl.getPermissions(source);
+        		
+        		PermissionCollection clPermissions = cl.getPermissions(source);
+        		
+        		// systempolicy permissions need to be accounted for as well
+        		Enumeration e = systemPolicy.getPermissions(source).elements();
+                while (e.hasMoreElements())
+                    clPermissions.add((Permission) e.nextElement());
+
+        		return clPermissions;
         	}
         }
 
--- a/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarSigner.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/overlays/openjdk/jdk/src/share/classes/net/sourceforge/jnlp/tools/JarSigner.java	Tue Dec 02 13:58:24 2008 +0000
@@ -189,7 +189,16 @@
             certs = new ArrayList<CertPath>();
 
             try {
-                String localFile = tracker.getCacheFile(jar.getLocation()).getAbsolutePath();
+                
+                File jarFile = tracker.getCacheFile(jar.getLocation());
+                
+                // some sort of resource download/cache error. Nothing to add 
+                // in that case ... but don't fail here
+                if (jarFile == null) {
+                    return;
+                }
+
+                String localFile = jarFile.getAbsolutePath();
                 boolean result = verifyJar(localFile);
                 checkTrustedCerts();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/EmergencySoundbank/TestCreateSoundbank.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,59 @@
+import java.io.File;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+
+import com.sun.media.sound.EmergencySoundbank;
+import com.sun.media.sound.ModelInstrument;
+import com.sun.media.sound.ModelPatch;
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ @summary Test EmergencySoundbank createSoundbank() method */
+
+public class TestCreateSoundbank {
+
+    public static void main(String[] args) throws Exception {
+        
+        Soundbank soundbank = EmergencySoundbank.createSoundbank();
+        for (int i = 0; i < 128; i++) {
+            Patch patch = new ModelPatch(0, i, false);
+            ModelInstrument ins = (ModelInstrument)soundbank.getInstrument(patch);
+            if(ins == null)
+                throw new Exception("Instrument " + i + " is missing!");
+            if(ins.getPerformers().length == 0)
+                throw new Exception("Instrument " + i + " doesn't have any performers!");
+        }
+        Patch patch = new ModelPatch(0, 0, true);
+        ModelInstrument ins = (ModelInstrument)soundbank.getInstrument(patch);
+        if(ins == null)
+            throw new Exception("Drumkit instrument is missing!");
+        if(ins.getPerformers().length == 0)
+            throw new Exception("Drumkit instrument doesn't have any performers!");
+    }   
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Available.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream available() method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Available {
+
+    static float[] testarray;
+    static byte[] test_byte_array;  
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }       
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }   
+    
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }           
+    
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+            
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+                
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {                                     
+                    int ret = is.available();
+                    if(ret != capacity)
+                        throw new RuntimeException("is.available() return unexpected value!");
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");                
+            }           
+        }
+        finally
+        {
+            tearDown();
+        }       
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Close.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream close method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Close {
+
+    static float[] testarray;
+    static byte[] test_byte_array;  
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }       
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }   
+    
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }           
+    
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+            
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+                
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {                    
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");
+            }           
+        }
+        finally
+        {
+            tearDown();
+        }       
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/MarkReset.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream mark and reset methods */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class MarkReset {
+
+    static float[] testarray;
+    static byte[] test_byte_array;  
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }       
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }   
+    
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }           
+    
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+            
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+                
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {                
+                    is.mark(1000);
+                    int ret = is.available();
+                    int a = is.read();
+                    is.skip(75);                          
+                    is.reset();
+                    if(is.available() != ret)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret)+") !");
+                    int b = is.read();
+                    if(a != b)
+                        throw new RuntimeException(
+                                "is doesn't return same value after reset ("
+                                + a + "!="+b+") !");
+                    
+                    is.skip(15);        
+                    ret = is.available();
+                    is.mark(1000);
+                    is.reset();
+                    if(is.available() != ret)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret)+") !");
+                   
+                    
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");                
+            }           
+        }
+        finally
+        {
+            tearDown();
+        }       
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/MarkSupported.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream markSupported() method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class MarkSupported {
+
+    static float[] testarray;
+    static byte[] test_byte_array;  
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }       
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }   
+    
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }           
+    
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+            
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+                
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {               
+                    if(!is.markSupported())
+                        throw new RuntimeException("InputStream doesn't support mark/reset!");
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");                
+            }           
+        }
+        finally
+        {
+            tearDown();
+        }       
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Read.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream read() method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Read {
+
+    static float[] testarray;
+    static byte[] test_byte_array;  
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }       
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }   
+    
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }           
+    
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+            
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+                
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {                 
+                    byte[] b = new byte[100];
+                    int ret = is.available();
+                    int n = is.read();
+                    if(n == -1)                    
+                        throw new RuntimeException("is.read shouldn't return -1!");
+                    if(is.available() != ret - 1)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - 1)+") !");
+                    is.skip(5000);
+                    if(is.read() != -1)
+                        throw new RuntimeException(
+                                "is.read() doesn't return -1!");
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");                
+            }           
+        }
+        finally
+        {
+            tearDown();
+        }       
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/ReadByte.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream read(byte[]) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadByte {
+
+    static float[] testarray;
+    static byte[] test_byte_array;  
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }       
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }   
+    
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }           
+    
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+            
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+                
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {                 
+                    byte[] b = new byte[100];
+                    int ret = is.available();
+                    int n = is.read(b);
+                    if(n == -1)                    
+                        throw new RuntimeException("is.read shouldn't return -1!");
+                    if(is.available() != ret - n)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - n)+") !");
+                    is.skip(5000);
+                    if(is.read(b) != -1)
+                        throw new RuntimeException(
+                                "is.read() doesn't return -1!");
+                    
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");                
+            }           
+        }
+        finally
+        {
+            tearDown();
+        }       
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/ReadByteIntInt.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream read(byte[], int, int) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class ReadByteIntInt {
+
+    static float[] testarray;
+    static byte[] test_byte_array;  
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }       
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }   
+    
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }           
+    
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+            
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+                
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {                 
+                    byte[] b = new byte[100];
+                    int ret = is.available();
+                    int n = is.read(b, 7, 50);
+                    if(n == -1)                    
+                        throw new RuntimeException("is.read shouldn't return -1!");
+                    if(is.available() != ret - n)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - n)+") !");
+                    is.skip(5000);
+                    if(is.read(b, 7, 50) != -1)
+                        throw new RuntimeException(
+                                "is.read() doesn't return -1!");
+                    
+                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");                
+            }           
+        }
+        finally
+        {
+            tearDown();
+        }       
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/ModelByteBuffer/RandomFileInputStream/Skip.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test ModelByteBuffer.RandomFileInputStream skip(long) method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class Skip {
+
+    static float[] testarray;
+    static byte[] test_byte_array;  
+    static File test_file;
+    static AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+    
+    static void setUp() throws Exception {
+        testarray = new float[1024];
+        for (int i = 0; i < 1024; i++) {
+            double ii = i / 1024.0;
+            ii = ii * ii;
+            testarray[i] = (float)Math.sin(10*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(1.731 + 2*ii*2*Math.PI);
+            testarray[i] += (float)Math.sin(0.231 + 6.3*ii*2*Math.PI);
+            testarray[i] *= 0.3;
+        }       
+        test_byte_array = new byte[testarray.length*2];
+        AudioFloatConverter.getConverter(format).toByteArray(testarray, test_byte_array);
+        test_file = File.createTempFile("test", ".raw");
+        FileOutputStream fos = new FileOutputStream(test_file);
+        fos.write(test_byte_array);
+    }   
+    
+    static void tearDown() throws Exception {
+        if(!test_file.delete())
+            test_file.deleteOnExit();
+    }           
+    
+    public static void main(String[] args) throws Exception {
+        try
+        {
+            setUp();
+            
+            for (int i = 0; i < 8; i++) {
+                ModelByteBuffer buff;
+                if(i % 2 == 0)
+                    buff = new ModelByteBuffer(test_file);
+                else
+                    buff = new ModelByteBuffer(test_byte_array);
+                if((i / 2) == 1)
+                    buff.subbuffer(5);
+                if((i / 2) == 2)
+                    buff.subbuffer(5,500);
+                if((i / 2) == 3)
+                    buff.subbuffer(5,600,true);
+                
+                long capacity = buff.capacity();
+                InputStream is = buff.getInputStream();
+                try
+                {                 
+                    int ret = is.available();
+                    long n = is.skip(75);
+                    if(n == -1)                    
+                        throw new RuntimeException("is.read shouldn't return -1!");
+                    if(is.available() != ret - n)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - n)+") !");
+                    
+                    ret = is.available();
+                    n = is.skip(-100);
+                    if(n != 0)                    
+                        throw new RuntimeException("is.skip(-100) shouldn't skip values!");
+                    if(is.available() != ret - n)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - n)+") !");
+
+                    ret = is.available();
+                    n = is.skip(5000);
+                    if(is.available() != ret - n)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(ret - n)+") !");
+                    if(is.available() != 0)
+                        throw new RuntimeException(
+                                "is.available() returns incorrect value ("
+                                + is.available() + "!="+(0)+") !");                }
+                finally
+                {
+                    is.close();
+                }
+                if(buff.capacity() != capacity)
+                    throw new RuntimeException("Capacity variable should not change!");                
+            }           
+        }
+        finally
+        {
+            tearDown();
+        }       
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/SoftAudioSynthesizer/DummySourceDataLine.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,207 @@
+import java.util.ArrayList;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Control;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.AudioFormat.Encoding;
+import javax.sound.sampled.Control.Type;
+
+import com.sun.media.sound.AudioFloatConverter;
+
+/**
+ * This is a SourceDataLine simulator used for testing SoftSynthesizer
+ * without using real SourceDataLine / Audio Device. 
+ * 
+ * @author Karl Helgason
+ */
+
+public class DummySourceDataLine implements SourceDataLine {
+
+    private int bufferSize = -1;
+
+    private AudioFormat format = new AudioFormat(44100.0f, 16, 2, true, false);
+    
+    private DataLine.Info sourceLineInfo;
+    
+    private boolean active = false;
+    
+    private long framepos = 0;
+    
+    private boolean opened = false;
+    
+    private int framesize = 0;
+    
+    public DummySourceDataLine()
+    {
+        ArrayList<AudioFormat> formats = new ArrayList<AudioFormat>();
+        for (int channels = 1; channels <= 2; channels++) {
+            formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,
+                    AudioSystem.NOT_SPECIFIED, false));
+            for (int bits = 16; bits < 32; bits += 8) {
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));
+                formats.add(new AudioFormat(Encoding.PCM_SIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,
+                        AudioSystem.NOT_SPECIFIED, bits, channels, channels
+                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));
+            }
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,
+                    AudioSystem.NOT_SPECIFIED, true));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, false));
+            formats.add(new AudioFormat(AudioFloatConverter.PCM_FLOAT,
+                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,
+                    AudioSystem.NOT_SPECIFIED, true));
+        }
+        AudioFormat[] formats_array = formats.toArray(new AudioFormat[formats
+                .size()]);
+        sourceLineInfo = new DataLine.Info(SourceDataLine.class,
+                formats_array, AudioSystem.NOT_SPECIFIED,
+                AudioSystem.NOT_SPECIFIED);
+        
+    }
+
+    public void open() throws LineUnavailableException {
+        open(format);
+    }
+
+    public void open(AudioFormat format) throws LineUnavailableException {
+        if (bufferSize == -1)
+            bufferSize = ((int) (format.getFrameRate() / 2))
+                    * format.getFrameSize();
+        open(format, bufferSize);
+    }
+
+    public void open(AudioFormat format, int bufferSize)
+            throws LineUnavailableException {
+        this.format = format;
+        this.bufferSize = bufferSize;
+        this.framesize = format.getFrameSize();        
+        opened = true;
+    }
+    
+    public boolean isOpen() {
+        return opened;
+    }
+
+    public int write(byte[] b, int off, int len) {
+        if (!isOpen())
+            return 0;
+        if (len % framesize != 0)
+            throw new IllegalArgumentException(
+                    "Number of bytes does not represent an integral number of sample frames.");
+
+
+        int flen = len / framesize;
+        framepos += flen;
+        
+        long time =  (long) (flen * (1000.0 / (double) getFormat()
+                .getSampleRate()));
+        try {
+            Thread.sleep(time);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            return 0;
+        }
+        
+        return len;
+    }
+
+    public int available() {
+        return 0;
+    }
+
+    public void drain() {
+    }
+
+    public void flush() {
+    }
+
+    public int getBufferSize() {
+        return bufferSize;
+    }
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public int getFramePosition() {
+        return (int) getLongFramePosition();
+    }
+
+    public float getLevel() {
+        return AudioSystem.NOT_SPECIFIED;
+    }
+
+    public long getLongFramePosition() {
+        return framepos;
+    }
+
+    public long getMicrosecondPosition() {
+        return (long) (getLongFramePosition() * (1000000.0 / (double) getFormat()
+                .getSampleRate()));
+    }
+
+    public boolean isActive() {
+        return active;
+    }
+
+    public boolean isRunning() {
+        return active;
+    }
+
+    public void start() {
+        active = true;
+    }
+
+    public void stop() {
+        active = false;
+    }
+
+    public void close() {
+        stop(); 
+    }
+
+    public Control getControl(Type control) {
+        throw new IllegalArgumentException("Unsupported control type : "
+                + control);
+    }
+
+    public Control[] getControls() {
+        return new Control[0];
+    }
+
+    public javax.sound.sampled.Line.Info getLineInfo() {
+        return sourceLineInfo;
+    }
+
+    public boolean isControlSupported(Type control) {
+        return false;
+    }
+    
+    public void addLineListener(LineListener listener) {
+    }
+
+    public void removeLineListener(LineListener listener) {
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/overlays/openjdk/jdk/test/com/sun/media/sound/SoftFilter/TestProcessAudio.java	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+   @summary Test SoftFilter processAudio method */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Random;
+
+import javax.sound.sampled.*;
+
+import com.sun.media.sound.*;
+
+public class TestProcessAudio {
+
+    public static void main(String[] args) throws Exception {
+        AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+        SoftAudioBuffer sbuffer = new SoftAudioBuffer(3600, format);
+        SoftFilter filter = new SoftFilter(format.getSampleRate());
+        Random random = new Random(42);
+
+        
+        for (int t = 0; t <= 6; t++)
+        {
+            if(t == 0) filter.setFilterType(SoftFilter.FILTERTYPE_BP12);
+            if(t == 1) filter.setFilterType(SoftFilter.FILTERTYPE_HP12);
+            if(t == 2) filter.setFilterType(SoftFilter.FILTERTYPE_HP24);
+            if(t == 3) filter.setFilterType(SoftFilter.FILTERTYPE_LP12);
+            if(t == 4) filter.setFilterType(SoftFilter.FILTERTYPE_LP24);
+            if(t == 5) filter.setFilterType(SoftFilter.FILTERTYPE_LP6);
+            if(t == 6) filter.setFilterType(SoftFilter.FILTERTYPE_NP12);
+            
+            
+            // Try first by reseting always
+            for (int f = 1200; f < 3600; f+=100) 
+                for (int r = 0; r <= 30; r+=5) {
+                    filter.reset();
+                    filter.setResonance(r);
+                    filter.setFrequency(f);
+                    float[] data = sbuffer.array();
+                    int len = sbuffer.getSize();
+                    for (int i = 0; i < len; i++) 
+                        data[i] = random.nextFloat() - 0.5f;            
+                    filter.processAudio(sbuffer);                    
+                }
+            
+            // Now we skip reseting
+            // to test how changing frequency and resonance
+            // affect active filter
+            for (int f = 100; f < 12800; f+=1200) 
+            for (int r = 0; r <= 30; r+=5) {                       
+                filter.setResonance(r);
+                filter.setFrequency(f);
+                float[] data = sbuffer.array();
+                int len = sbuffer.getSize();
+                for (int i = 0; i < len; i++) 
+                    data[i] = random.nextFloat() - 0.5f;            
+                filter.processAudio(sbuffer);
+            }
+            for (int f = 12800; f >= 100; f-=1200) 
+                for (int r = 30; r >= 0; r-=5) {                       
+                    filter.setResonance(r);
+                    filter.setFrequency(f);
+                    float[] data = sbuffer.array();
+                    int len = sbuffer.getSize();
+                    for (int i = 0; i < len; i++) 
+                        data[i] = random.nextFloat() - 0.5f;            
+                    filter.processAudio(sbuffer);
+                }
+            filter.reset();
+        }
+        
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-4486841.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,1234 @@
+--- old/src/share/classes/sun/nio/cs/UTF_8.java	Thu Oct  9 16:02:01 2008
++++ openjdk/jdk/src/share/classes/sun/nio/cs/UTF_8.java	Thu Oct  9 16:02:01 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -25,34 +25,36 @@
+ 
+ package sun.nio.cs;
+ 
++import java.nio.Buffer;
+ import java.nio.ByteBuffer;
+ import java.nio.CharBuffer;
+-import java.nio.BufferOverflowException;
+-import java.nio.BufferUnderflowException;
+ import java.nio.charset.Charset;
+ import java.nio.charset.CharsetDecoder;
+ import java.nio.charset.CharsetEncoder;
+ import java.nio.charset.CoderResult;
+-import java.nio.charset.CharacterCodingException;
+-import java.nio.charset.MalformedInputException;
+-import java.nio.charset.UnmappableCharacterException;
+ 
+-
+-/*
+- * # Bits   Bit pattern
+- * 1    7   0xxxxxxx
+- * 2   11   110xxxxx 10xxxxxx
+- * 3   16   1110xxxx 10xxxxxx 10xxxxxx
+- * 4   21   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+- * 5   26   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+- * 6   31   1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
++/* Legal UTF-8 Byte Sequences
+  *
+- * UCS-2 uses 1-3, UTF-16 uses 1-4, UCS-4 uses 1-6
++ * #    Code Points      Bits   Bit/Byte pattern
++ * 1                     7      0xxxxxxx
++ *      U+0000..U+007F          00..7F
++ *
++ * 2                     11     110xxxxx    10xxxxxx
++ *      U+0080..U+07FF          C2..DF      80..BF
++ *
++ * 3                     16     1110xxxx    10xxxxxx    10xxxxxx
++ *      U+0800..U+0FFF          E0          A0..BF      80..BF
++ *      U+1000..U+FFFF          E1..EF      80..BF      80..BF
++ *
++ * 4                     21     11110xxx    10xxxxxx    10xxxxxx    10xxxxxx
++ *     U+10000..U+3FFFF         F0          90..BF      80..BF      80..BF
++ *     U+40000..U+FFFFF         F1..F3      80..BF      80..BF      80..BF
++ *    U+100000..U10FFFF         F4          80..8F      80..BF      80..BF
++ *
+  */
+ 
+ class UTF_8 extends Unicode
+ {
+-
+     public UTF_8() {
+         super("UTF-8", StandardCharsets.aliases_UTF_8);
+     }
+@@ -69,6 +71,11 @@
+         return new Encoder(this);
+     }
+ 
++    static final void updatePositions(Buffer src, int sp,
++                                      Buffer dst, int dp) {
++        src.position(sp - src.arrayOffset());
++        dst.position(dp - dst.arrayOffset());
++    }
+ 
+     private static class Decoder extends CharsetDecoder {
+         private Decoder(Charset cs) {
+@@ -75,161 +82,182 @@
+             super(cs, 1.0f, 1.0f);
+         }
+ 
+-        private boolean isContinuation(int b) {
+-            return ((b & 0xc0) == 0x80);
++        private static boolean isNotContinuation(int b) {
++            return (b & 0xc0) != 0x80;
+         }
+ 
+-        private final Surrogate.Generator sgg = new Surrogate.Generator();
++        //  [C2..DF] [80..BF]
++        private static boolean isMalformed2(int b1, int b2) {
++            return (b1 & 0x1e) == 0x0 || (b2 & 0xc0) != 0x80;
++        }
+ 
++        //  [E0]     [A0..BF] [80..BF]
++        //  [E1..EF] [80..BF] [80..BF]
++        private static boolean isMalformed3(int b1, int b2, int b3) {
++            return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
++                   (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80;
++        }
++
++        //  [F0]     [90..BF] [80..BF] [80..BF]
++        //  [F1..F3] [80..BF] [80..BF] [80..BF]
++        //  [F4]     [80..8F] [80..BF] [80..BF]
++        //  only check 80-be range here, the [0xf0,0x80...] and [0xf4,0x90-...]
++        //  will be checked by Surrogate.neededFor(uc)
++        private static boolean isMalformed4(int b2, int b3, int b4) {
++            return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 ||
++                   (b4 & 0xc0) != 0x80;
++        }
++
++        private static CoderResult lookupN(ByteBuffer src, int n)
++        {
++            for (int i = 1; i < n; i++) {
++               if (isNotContinuation(src.get()))
++                   return CoderResult.malformedForLength(i);
++            }
++            return CoderResult.malformedForLength(n);
++        }
++
++        private static CoderResult malformedN(ByteBuffer src, int nb) {
++            switch (nb) {
++            case 1:
++                int b1 = src.get();
++                if ((b1 >> 2) == -2) {
++                    // 5 bytes 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
++                    if (src.remaining() < 4)
++                        return CoderResult.UNDERFLOW;
++                    return lookupN(src, 5);
++                }
++                if ((b1 >> 1) == -2) {
++                    // 6 bytes 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
++                    if (src.remaining() < 5)
++                        return CoderResult.UNDERFLOW;
++                    return lookupN(src, 6);
++                }
++                return CoderResult.malformedForLength(1);
++            case 2:                    // always 1
++                return CoderResult.malformedForLength(1);
++            case 3:
++                b1 = src.get();
++                int b2 = src.get();    // no need to lookup b3
++                return CoderResult.malformedForLength(
++                    ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
++                     isNotContinuation(b2))?1:2);
++            case 4:  // we don't care the speed here
++                b1 = src.get() & 0xff;
++                b2 = src.get() & 0xff;
++                if (b1 > 0xf4 ||
++                    (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) ||
++                    (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
++                    isNotContinuation(b2))
++                    return CoderResult.malformedForLength(1);
++                if (isNotContinuation(src.get()))
++                    return CoderResult.malformedForLength(2);
++                return CoderResult.malformedForLength(3);
++            default:
++                assert false;
++                return null;
++            }
++        }
++
++        private static CoderResult malformed(ByteBuffer src, int sp,
++                                             CharBuffer dst, int dp,
++                                             int nb)
++        {
++            src.position(sp - src.arrayOffset());
++            CoderResult cr = malformedN(src, nb);
++            updatePositions(src, sp, dst, dp);
++            return cr;
++        }
++
++        private static CoderResult malformed(ByteBuffer src,
++                                             int mark, int nb)
++        {
++            src.position(mark);
++            CoderResult cr = malformedN(src, nb);
++            src.position(mark);
++            return cr;
++        }
++
++        private static CoderResult xflow(Buffer src, int sp, int sl,
++                                         Buffer dst, int dp, int nb) {
++            updatePositions(src, sp, dst, dp);
++            return (nb == 0 || sl - sp < nb)
++                   ?CoderResult.UNDERFLOW:CoderResult.OVERFLOW;
++        }
++
++        private static CoderResult xflow(Buffer src, int mark, int nb) {
++            CoderResult cr = (nb == 0 || src.remaining() < (nb - 1))
++                             ?CoderResult.UNDERFLOW:CoderResult.OVERFLOW;
++            src.position(mark);
++            return cr;
++        }
++
+         private CoderResult decodeArrayLoop(ByteBuffer src,
+                                             CharBuffer dst)
+         {
++            // This method is optimized for ASCII input.
+             byte[] sa = src.array();
+             int sp = src.arrayOffset() + src.position();
+             int sl = src.arrayOffset() + src.limit();
+-            assert (sp <= sl);
+-            sp = (sp <= sl ? sp : sl);
++
+             char[] da = dst.array();
+             int dp = dst.arrayOffset() + dst.position();
+             int dl = dst.arrayOffset() + dst.limit();
+-            assert (dp <= dl);
+-            dp = (dp <= dl ? dp : dl);
++            int dlASCII = dp + Math.min(sl - sp, dl - dp);
+ 
+-            try {
+-                while (sp < sl) {
+-                    int b1 = sa[sp];
+-                    int b2, b3;
+-                    switch ((b1 >> 4) & 0x0f) {
++            // ASCII only loop
++            while (dp < dlASCII && sa[sp] >= 0)
++                da[dp++] = (char)sa[sp++];
+ 
+-                    case 0: case 1: case 2: case 3:
+-                    case 4: case 5: case 6: case 7:
+-                        // 1 byte, 7 bits: 0xxxxxxx
+-                        if (dl - dp < 1)
+-                            return CoderResult.OVERFLOW;
+-                        da[dp++] = (char)(b1 & 0x7f);
+-                        sp++;
+-                        continue;
+-
+-                    case 12: case 13:
+-                        // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
+-                        if (sl - sp < 2)
+-                            return CoderResult.UNDERFLOW;
+-                        if (dl - dp < 1)
+-                            return CoderResult.OVERFLOW;
+-                        if (!isContinuation(b2 = sa[sp + 1]))
+-                            return CoderResult.malformedForLength(1);
+-                        da[dp++] = ((char)(((b1 & 0x1f) << 6) |
+-                                           ((b2 & 0x3f) << 0)));
+-                        sp += 2;
+-                        continue;
+-
+-                    case 14:
+-                        // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
+-                        if (sl - sp < 3)
+-                            return CoderResult.UNDERFLOW;
+-                        if (dl - dp < 1)
+-                            return CoderResult.OVERFLOW;
+-                        if (!isContinuation(b2 = sa[sp + 1]))
+-                            return CoderResult.malformedForLength(1);
+-                        if (!isContinuation(b3 = sa[sp + 2]))
+-                            return CoderResult.malformedForLength(2);
+-                        da[dp++] = ((char)(((b1 & 0x0f) << 12) |
+-                                           ((b2 & 0x3f) << 06) |
+-                                           ((b3 & 0x3f) << 0)));
+-                        sp += 3;
+-                        continue;
+-
+-                    case 15:
+-                        // 4, 5, or 6 bytes
+-
+-                        int b4, b5, b6, uc, n;
+-                        switch (b1 & 0x0f) {
+-
+-                        case 0: case 1: case 2: case 3:
+-                        case 4: case 5: case 6: case 7:
+-                            // 4 bytes, 21 bits
+-                            if (sl - sp < 4)
+-                                return CoderResult.UNDERFLOW;
+-                            if (!isContinuation(b2 = sa[sp + 1]))
+-                                return CoderResult.malformedForLength(1);
+-                            if (!isContinuation(b3 = sa[sp + 2]))
+-                                return CoderResult.malformedForLength(2);
+-                            if (!isContinuation(b4 = sa[sp + 3]))
+-                                return CoderResult.malformedForLength(3);
+-                            uc = (((b1 & 0x07) << 18) |
+-                                  ((b2 & 0x3f) << 12) |
+-                                  ((b3 & 0x3f) << 06) |
+-                                  ((b4 & 0x3f) << 00));
+-                            n = 4;
+-                            break;
+-
+-                        case 8: case 9: case 10: case 11:
+-                            // 5 bytes, 26 bits
+-                            if (sl - sp < 5)
+-                                return CoderResult.UNDERFLOW;
+-                            if (!isContinuation(b2 = sa[sp + 1]))
+-                                return CoderResult.malformedForLength(1);
+-                            if (!isContinuation(b3 = sa[sp + 2]))
+-                                return CoderResult.malformedForLength(2);
+-                            if (!isContinuation(b4 = sa[sp + 3]))
+-                                return CoderResult.malformedForLength(3);
+-                            if (!isContinuation(b5 = sa[sp + 4]))
+-                                return CoderResult.malformedForLength(4);
+-                            uc = (((b1 & 0x03) << 24) |
+-                                  ((b2 & 0x3f) << 18) |
+-                                  ((b3 & 0x3f) << 12) |
+-                                  ((b4 & 0x3f) << 06) |
+-                                  ((b5 & 0x3f) << 00));
+-                            n = 5;
+-                            break;
+-
+-                        case 12: case 13:
+-                            // 6 bytes, 31 bits
+-                            if (sl - sp < 6)
+-                                return CoderResult.UNDERFLOW;
+-                            if (!isContinuation(b2 = sa[sp + 1]))
+-                                return CoderResult.malformedForLength(1);
+-                            if (!isContinuation(b3 = sa[sp + 2]))
+-                                return CoderResult.malformedForLength(2);
+-                            if (!isContinuation(b4 = sa[sp + 3]))
+-                                return CoderResult.malformedForLength(3);
+-                            if (!isContinuation(b5 = sa[sp + 4]))
+-                                return CoderResult.malformedForLength(4);
+-                            if (!isContinuation(b6 = sa[sp + 5]))
+-                                return CoderResult.malformedForLength(5);
+-                            uc = (((b1 & 0x01) << 30) |
+-                                  ((b2 & 0x3f) << 24) |
+-                                  ((b3 & 0x3f) << 18) |
+-                                  ((b4 & 0x3f) << 12) |
+-                                  ((b5 & 0x3f) << 06) |
+-                                  ((b6 & 0x3f)));
+-                            n = 6;
+-                            break;
+-
+-                        default:
+-                            return CoderResult.malformedForLength(1);
+-
+-                        }
+-
+-                        int gn = sgg.generate(uc, n, da, dp, dl);
+-                        if (gn < 0)
+-                            return sgg.error();
+-                        dp += gn;
+-                        sp += n;
+-                        continue;
+-
+-                    default:
+-                        return CoderResult.malformedForLength(1);
+-
++            while (sp < sl) {
++                int b1 = sa[sp];
++                if (b1  >= 0) {
++                    // 1 byte, 7 bits: 0xxxxxxx
++                    if (dp >= dl)
++                        return xflow(src, sp, sl, dst, dp, 1);
++                    da[dp++] = (char)b1;
++                    sp++;
++                } else if ((b1 >> 5) == -2) {
++                    // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
++                    if (sl - sp < 2 || dp >= dl)
++                        return xflow(src, sp, sl, dst, dp, 2);
++                    int b2 = sa[sp + 1];
++                    if (isMalformed2(b1, b2))
++                        return malformed(src, sp, dst, dp, 2);
++                    da[dp++] = (char) (((b1 << 6) ^ b2) ^ 0x0f80);
++                    sp += 2;
++                } else if ((b1 >> 4) == -2) {
++                    // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
++                    if (sl - sp < 3 || dp >= dl)
++                        return xflow(src, sp, sl, dst, dp, 3);
++                    int b2 = sa[sp + 1];
++                    int b3 = sa[sp + 2];
++                    if (isMalformed3(b1, b2, b3))
++                        return malformed(src, sp, dst, dp, 3);
++                    da[dp++] = (char) (((b1 << 12) ^ (b2 << 6) ^ b3) ^ 0x1f80);
++                    sp += 3;
++                } else if ((b1 >> 3) == -2) {
++                    // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
++                    if (sl - sp < 4 || dl - dp < 2)
++                        return xflow(src, sp, sl, dst, dp, 4);
++                    int b2 = sa[sp + 1];
++                    int b3 = sa[sp + 2];
++                    int b4 = sa[sp + 3];
++                    int uc = ((b1 & 0x07) << 18) |
++                             ((b2 & 0x3f) << 12) |
++                             ((b3 & 0x3f) << 06) |
++                             (b4 & 0x3f);
++                    if (isMalformed4(b2, b3, b4) ||
++                        !Surrogate.neededFor(uc)) {
++                        return malformed(src, sp, dst, dp, 4);
+                     }
+-
+-                }
+-
+-                return CoderResult.UNDERFLOW;
+-            } finally {
+-                src.position(sp - src.arrayOffset());
+-                dst.position(dp - dst.arrayOffset());
++                    da[dp++] = Surrogate.high(uc);
++                    da[dp++] = Surrogate.low(uc);
++                    sp += 4;
++                } else
++                    return malformed(src, sp, dst, dp, 1);
+             }
++            return xflow(src, sp, sl, dst, dp, 0);
+         }
+ 
+         private CoderResult decodeBufferLoop(ByteBuffer src,
+@@ -236,137 +264,57 @@
+                                              CharBuffer dst)
+         {
+             int mark = src.position();
+-            try {
+-                while (src.hasRemaining()) {
+-                    int b1 = src.get();
+-                    int b2, b3;
+-                    switch ((b1 >> 4) & 0x0f) {
+-
+-                    case 0: case 1: case 2: case 3:
+-                    case 4: case 5: case 6: case 7:
+-                        // 1 byte, 7 bits: 0xxxxxxx
+-                        if (dst.remaining() < 1)
+-                            return CoderResult.OVERFLOW;
+-                        dst.put((char)b1);
+-                        mark++;
+-                        continue;
+-
+-                    case 12: case 13:
+-                        // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
+-                        if (src.remaining() < 1)
+-                            return CoderResult.UNDERFLOW;
+-                        if (dst.remaining() < 1)
+-                            return CoderResult.OVERFLOW;
+-                        if (!isContinuation(b2 = src.get()))
+-                            return CoderResult.malformedForLength(1);
+-                        dst.put((char)(((b1 & 0x1f) << 6) |
+-                                       ((b2 & 0x3f) << 0)));
+-                        mark += 2;
+-                        continue;
+-
+-                    case 14:
+-                        // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
+-                        if (src.remaining() < 2)
+-                            return CoderResult.UNDERFLOW;
+-                        if (dst.remaining() < 1)
+-                            return CoderResult.OVERFLOW;
+-                        if (!isContinuation(b2 = src.get()))
+-                            return CoderResult.malformedForLength(1);
+-                        if (!isContinuation(b3 = src.get()))
+-                            return CoderResult.malformedForLength(2);
+-                        dst.put((char)(((b1 & 0x0f) << 12) |
+-                                       ((b2 & 0x3f) << 06) |
+-                                       ((b3 & 0x3f) << 0)));
+-                        mark += 3;
+-                        continue;
+-
+-                    case 15:
+-                        // 4, 5, or 6 bytes
+-
+-                        int b4, b5, b6, uc, n;
+-                        switch (b1 & 0x0f) {
+-
+-                        case 0: case 1: case 2: case 3:
+-                        case 4: case 5: case 6: case 7:
+-                            // 4 bytes, 21 bits
+-                            if (src.remaining() < 3)
+-                                return CoderResult.UNDERFLOW;
+-                            if (!isContinuation(b2 = src.get()))
+-                                return CoderResult.malformedForLength(1);
+-                            if (!isContinuation(b3 = src.get()))
+-                                return CoderResult.malformedForLength(2);
+-                            if (!isContinuation(b4 = src.get()))
+-                                return CoderResult.malformedForLength(3);
+-                            uc = (((b1 & 0x07) << 18) |
+-                                  ((b2 & 0x3f) << 12) |
+-                                  ((b3 & 0x3f) << 06) |
+-                                  ((b4 & 0x3f) << 00));
+-                            n = 4;
+-                            break;
+-
+-                        case 8: case 9: case 10: case 11:
+-                            // 5 bytes, 26 bits
+-                            if (src.remaining() < 4)
+-                                return CoderResult.UNDERFLOW;
+-                            if (!isContinuation(b2 = src.get()))
+-                                return CoderResult.malformedForLength(1);
+-                            if (!isContinuation(b3 = src.get()))
+-                                return CoderResult.malformedForLength(2);
+-                            if (!isContinuation(b4 = src.get()))
+-                                return CoderResult.malformedForLength(3);
+-                            if (!isContinuation(b5 = src.get()))
+-                                return CoderResult.malformedForLength(4);
+-                            uc = (((b1 & 0x03) << 24) |
+-                                  ((b2 & 0x3f) << 18) |
+-                                  ((b3 & 0x3f) << 12) |
+-                                  ((b4 & 0x3f) << 06) |
+-                                  ((b5 & 0x3f) << 00));
+-                            n = 5;
+-                            break;
+-
+-                        case 12: case 13:
+-                            // 6 bytes, 31 bits
+-                            if (src.remaining() < 4)
+-                                return CoderResult.UNDERFLOW;
+-                            if (!isContinuation(b2 = src.get()))
+-                                return CoderResult.malformedForLength(1);
+-                            if (!isContinuation(b3 = src.get()))
+-                                return CoderResult.malformedForLength(2);
+-                            if (!isContinuation(b4 = src.get()))
+-                                return CoderResult.malformedForLength(3);
+-                            if (!isContinuation(b5 = src.get()))
+-                                return CoderResult.malformedForLength(4);
+-                            if (!isContinuation(b6 = src.get()))
+-                                return CoderResult.malformedForLength(5);
+-                            uc = (((b1 & 0x01) << 30) |
+-                                  ((b2 & 0x3f) << 24) |
+-                                  ((b3 & 0x3f) << 18) |
+-                                  ((b4 & 0x3f) << 12) |
+-                                  ((b5 & 0x3f) << 06) |
+-                                  ((b6 & 0x3f)));
+-                            n = 6;
+-                            break;
+-
+-                        default:
+-                            return CoderResult.malformedForLength(1);
+-
+-                        }
+-
+-                        if (sgg.generate(uc, n, dst) < 0)
+-                            return sgg.error();
+-                        mark += n;
+-                        continue;
+-
+-                    default:
+-                        return CoderResult.malformedForLength(1);
+-
++            int limit = src.limit();
++            while (mark < limit) {
++                int b1 = src.get();
++                if (b1 >= 0) {
++                    // 1 byte, 7 bits: 0xxxxxxx
++                    if (dst.remaining() < 1)
++                        return xflow(src, mark, 1);  //overflow
++                    dst.put((char)b1);
++                    mark++;
++                } else if ((b1 >> 5) == -2) {
++                    // 2 bytes, 11 bits: 110xxxxx 10xxxxxx
++                    if (limit - mark < 2|| dst.remaining() < 1)
++                        return xflow(src, mark, 2);
++                    int b2 = src.get();
++                    if (isMalformed2(b1, b2))
++                        return malformed(src, mark, 2);
++                    dst.put((char) (((b1 << 6) ^ b2) ^ 0x0f80));
++                    mark += 2;
++                } else if ((b1 >> 4) == -2) {
++                    // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx
++                    if (limit - mark < 3 || dst.remaining() < 1)
++                        return xflow(src, mark, 3);
++                    int b2 = src.get();
++                    int b3 = src.get();
++                    if (isMalformed3(b1, b2, b3))
++                        return malformed(src, mark, 3);
++                    dst.put((char) (((b1 << 12) ^ (b2 << 6) ^ b3) ^ 0x1f80));
++                    mark += 3;
++                } else if ((b1 >> 3) == -2) {
++                    // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
++                    if (limit - mark < 4 || dst.remaining() < 2)
++                        return xflow(src, mark, 4);
++                    int b2 = src.get();
++                    int b3 = src.get();
++                    int b4 = src.get();
++                    int uc = ((b1 & 0x07) << 18) |
++                             ((b2 & 0x3f) << 12) |
++                             ((b3 & 0x3f) << 06) |
++                             (b4 & 0x3f);
++                    if (isMalformed4(b2, b3, b4) ||
++                        !Surrogate.neededFor(uc)) { // shortest form check
++                        return malformed(src, mark, 4);
+                     }
+-
++                    dst.put(Surrogate.high(uc));
++                    dst.put(Surrogate.low(uc));
++                    mark += 4;
++                } else {
++                    return malformed(src, mark, 1);
+                 }
+-                return CoderResult.UNDERFLOW;
+-            } finally {
+-                src.position(mark);
+             }
++            return xflow(src, mark, 0);
+         }
+ 
+         protected CoderResult decodeLoop(ByteBuffer src,
+@@ -377,10 +325,8 @@
+             else
+                 return decodeBufferLoop(src, dst);
+         }
+-
+     }
+ 
+-
+     private static class Encoder extends CharsetEncoder {
+ 
+         private Encoder(Charset cs) {
+@@ -391,8 +337,23 @@
+             return !Surrogate.is(c);
+         }
+ 
+-        private final Surrogate.Parser sgp = new Surrogate.Parser();
++        public boolean isLegalReplacement(byte[] repl) {
++            return ((repl.length == 1 && repl[0] >= 0) ||
++                    super.isLegalReplacement(repl));
++        }
+ 
++        private static CoderResult overflow(CharBuffer src, int sp,
++                                            ByteBuffer dst, int dp) {
++            updatePositions(src, sp, dst, dp);
++            return CoderResult.OVERFLOW;
++        }
++
++        private static CoderResult overflow(CharBuffer src, int mark) {
++            src.position(mark);
++            return CoderResult.OVERFLOW;
++        }
++
++        private Surrogate.Parser sgp;
+         private CoderResult encodeArrayLoop(CharBuffer src,
+                                             ByteBuffer dst)
+         {
+@@ -399,71 +360,56 @@
+             char[] sa = src.array();
+             int sp = src.arrayOffset() + src.position();
+             int sl = src.arrayOffset() + src.limit();
+-            assert (sp <= sl);
+-            sp = (sp <= sl ? sp : sl);
++
+             byte[] da = dst.array();
+             int dp = dst.arrayOffset() + dst.position();
+             int dl = dst.arrayOffset() + dst.limit();
+-            assert (dp <= dl);
+-            dp = (dp <= dl ? dp : dl);
++            int dlASCII = dp + Math.min(sl - sp, dl - dp);
+ 
+-            try {
+-                while (sp < sl) {
+-                    char c = sa[sp];
+-
+-                    if (c < 0x80) {
+-                        // Have at most seven bits
+-                        if (dp >= dl)
+-                            return CoderResult.OVERFLOW;
+-                        da[dp++] = (byte)c;
+-                        sp++;
+-                        continue;
+-                    }
+-
+-                    if (!Surrogate.is(c)) {
+-                        // 2 bytes, 11 bits
+-                        if (c < 0x800) {
+-                            if (dl - dp < 2)
+-                                return CoderResult.OVERFLOW;
+-                            da[dp++] = (byte)(0xc0 | ((c >> 06)));
+-                            da[dp++] = (byte)(0x80 | ((c >> 00) & 0x3f));
+-                            sp++;
+-                            continue;
+-                        }
+-                        if (c <= '\uFFFF') {
+-                            // 3 bytes, 16 bits
+-                            if (dl - dp < 3)
+-                                return CoderResult.OVERFLOW;
+-                            da[dp++] = (byte)(0xe0 | ((c >> 12)));
+-                            da[dp++] = (byte)(0x80 | ((c >> 06) & 0x3f));
+-                            da[dp++] = (byte)(0x80 | ((c >> 00) & 0x3f));
+-                            sp++;
+-                            continue;
+-                        }
+-                    }
+-
++            //ASCII only loop
++            while (dp < dlASCII && sa[sp] < '\u0080')
++                da[dp++] = (byte) sa[sp++];
++            while (sp < sl) {
++                int c = sa[sp];
++                if (c < 0x80) {
++                    // Have at most seven bits
++                    if (dp >= dl)
++                        return overflow(src, sp, dst, dp);
++                    da[dp++] = (byte)c;
++                } else if (c < 0x800) {
++                    // 2 bytes, 11 bits
++                    if (dl - dp < 2)
++                        return overflow(src, sp, dst, dp);
++                    da[dp++] = (byte)(0xc0 | ((c >> 06)));
++                    da[dp++] = (byte)(0x80 | (c & 0x3f));
++                } else if (Surrogate.is(c)) {
+                     // Have a surrogate pair
+-                    int uc = sgp.parse(c, sa, sp, sl);
+-                    if (uc < 0)
++                    if (sgp == null)
++                        sgp = new Surrogate.Parser();
++                    int uc = sgp.parse((char)c, sa, sp, sl);
++                    if (uc < 0) {
++                        updatePositions(src, sp, dst, dp);
+                         return sgp.error();
+-                    if (uc < 0x200000) {
+-                        if (dl - dp < 4)
+-                            return CoderResult.OVERFLOW;
+-                        da[dp++] = (byte)(0xf0 | ((uc >> 18)));
+-                        da[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f));
+-                        da[dp++] = (byte)(0x80 | ((uc >> 06) & 0x3f));
+-                        da[dp++] = (byte)(0x80 | ((uc >> 00) & 0x3f));
+-                        sp += sgp.increment();
+-                        continue;
+                     }
+-                    assert false;
+-
++                    if (dl - dp < 4)
++                        return overflow(src, sp, dst, dp);
++                    da[dp++] = (byte)(0xf0 | ((uc >> 18)));
++                    da[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f));
++                    da[dp++] = (byte)(0x80 | ((uc >> 06) & 0x3f));
++                    da[dp++] = (byte)(0x80 | (uc & 0x3f));
++                    sp++;  // 2 chars
++                } else {
++                    // 3 bytes, 16 bits
++                    if (dl - dp < 3)
++                        return overflow(src, sp, dst, dp);
++                    da[dp++] = (byte)(0xe0 | ((c >> 12)));
++                    da[dp++] = (byte)(0x80 | ((c >> 06) & 0x3f));
++                    da[dp++] = (byte)(0x80 | (c & 0x3f));
+                 }
+-                return CoderResult.UNDERFLOW;
+-            } finally {
+-                src.position(sp - src.arrayOffset());
+-                dst.position(dp - dst.arrayOffset());
++                sp++;
+             }
++            updatePositions(src, sp, dst, dp);
++            return CoderResult.UNDERFLOW;
+         }
+ 
+         private CoderResult encodeBufferLoop(CharBuffer src,
+@@ -470,62 +416,47 @@
+                                              ByteBuffer dst)
+         {
+             int mark = src.position();
+-            try {
+-                while (src.hasRemaining()) {
+-                    char c = src.get();
+-
+-                    if (c < 0x80) {
+-                        // Have at most seven bits
+-                        if (!dst.hasRemaining())
+-                            return CoderResult.OVERFLOW;
+-                        dst.put((byte)c);
+-                        mark++;
+-                        continue;
+-                    }
+-
+-                    if (!Surrogate.is(c)) {
+-                        if (c < 0x800) {
+-                            // 2 bytes, 11 bits
+-                            if (dst.remaining() < 2)
+-                                return CoderResult.OVERFLOW;
+-                            dst.put((byte)(0xc0 | ((c >> 06))));
+-                            dst.put((byte)(0x80 | ((c >> 00) & 0x3f)));
+-                            mark++;
+-                            continue;
+-                        }
+-                        if (c <= '\uFFFF') {
+-                            // 3 bytes, 16 bits
+-                            if (dst.remaining() < 3)
+-                                return CoderResult.OVERFLOW;
+-                            dst.put((byte)(0xe0 | ((c >> 12))));
+-                            dst.put((byte)(0x80 | ((c >> 06) & 0x3f)));
+-                            dst.put((byte)(0x80 | ((c >> 00) & 0x3f)));
+-                            mark++;
+-                            continue;
+-                        }
+-                    }
+-
++            while (src.hasRemaining()) {
++                int c = src.get();
++                if (c < 0x80) {
++                    // Have at most seven bits
++                    if (!dst.hasRemaining())
++                        return overflow(src, mark);
++                    dst.put((byte)c);
++                } else if (c < 0x800) {
++                    // 2 bytes, 11 bits
++                    if (dst.remaining() < 2)
++                        return overflow(src, mark);
++                    dst.put((byte)(0xc0 | ((c >> 06))));
++                    dst.put((byte)(0x80 | (c & 0x3f)));
++                } else if (Surrogate.is(c)) {
+                     // Have a surrogate pair
+-                    int uc = sgp.parse(c, src);
+-                    if (uc < 0)
++                    if (sgp == null)
++                        sgp = new Surrogate.Parser();
++                    int uc = sgp.parse((char)c, src);
++                    if (uc < 0) {
++                        src.position(mark);
+                         return sgp.error();
+-                    if (uc < 0x200000) {
+-                        if (dst.remaining() < 4)
+-                            return CoderResult.OVERFLOW;
+-                        dst.put((byte)(0xf0 | ((uc >> 18))));
+-                        dst.put((byte)(0x80 | ((uc >> 12) & 0x3f)));
+-                        dst.put((byte)(0x80 | ((uc >> 06) & 0x3f)));
+-                        dst.put((byte)(0x80 | ((uc >> 00) & 0x3f)));
+-                        mark += sgp.increment();
+-                        continue;
+                     }
+-                    assert false;
+-
++                    if (dst.remaining() < 4)
++                        return overflow(src, mark);
++                    dst.put((byte)(0xf0 | ((uc >> 18))));
++                    dst.put((byte)(0x80 | ((uc >> 12) & 0x3f)));
++                    dst.put((byte)(0x80 | ((uc >> 06) & 0x3f)));
++                    dst.put((byte)(0x80 | (uc & 0x3f)));
++                    mark++;  //2 chars
++                } else {
++                    // 3 bytes, 16 bits
++                    if (dst.remaining() < 3)
++                        return overflow(src, mark);
++                    dst.put((byte)(0xe0 | ((c >> 12))));
++                    dst.put((byte)(0x80 | ((c >> 06) & 0x3f)));
++                    dst.put((byte)(0x80 | (c & 0x3f)));
+                 }
+-                return CoderResult.UNDERFLOW;
+-            } finally {
+-                src.position(mark);
++                mark++;
+             }
++            src.position(mark);
++            return CoderResult.UNDERFLOW;
+         }
+ 
+         protected final CoderResult encodeLoop(CharBuffer src,
+@@ -536,7 +467,5 @@
+             else
+                 return encodeBufferLoop(src, dst);
+         }
+-
+     }
+-
+ }
+--- /dev/null	Thu Oct  9 16:02:14 2008
++++ openjdk/jdk/test/sun/nio/cs/TestUTF8.java	Thu Oct  9 16:02:14 2008
+@@ -0,0 +1,393 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++/*
++ * @test
++ * @bug 4486841
++ * @summary Test UTF-8 charset
++ */
++
++import java.nio.charset.*;
++import java.nio.*;
++import java.util.*;
++
++public class TestUTF8 {
++    static char[] decode(byte[] bb, String csn, boolean testDirect)
++        throws Exception {
++        CharsetDecoder dec = Charset.forName(csn).newDecoder();
++        ByteBuffer bbf;
++        CharBuffer cbf;
++        if (testDirect) {
++            bbf = ByteBuffer.allocateDirect(bb.length);
++            cbf = ByteBuffer.allocateDirect(bb.length*2).asCharBuffer();
++            bbf.put(bb).flip();
++        } else {
++            bbf = ByteBuffer.wrap(bb);
++            cbf = CharBuffer.allocate(bb.length);
++        }
++        CoderResult cr = dec.decode(bbf, cbf, true);
++        if (cr != CoderResult.UNDERFLOW)
++            throw new RuntimeException("Decoding err: " + csn);
++        char[] cc = new char[cbf.position()];
++        cbf.flip(); cbf.get(cc);
++        return cc;
++
++    }
++
++    static CoderResult decodeCR(byte[] bb, String csn, boolean testDirect)
++        throws Exception {
++        CharsetDecoder dec = Charset.forName(csn).newDecoder();
++        ByteBuffer bbf;
++        CharBuffer cbf;
++        if (testDirect) {
++            bbf = ByteBuffer.allocateDirect(bb.length);
++            cbf = ByteBuffer.allocateDirect(bb.length*2).asCharBuffer();
++            bbf.put(bb).flip();
++        } else {
++            bbf = ByteBuffer.wrap(bb);
++            cbf = CharBuffer.allocate(bb.length);
++        }
++        return dec.decode(bbf, cbf, true);
++    }
++
++    static byte[] encode(char[] cc, String csn, boolean testDirect)
++        throws Exception {
++        ByteBuffer bbf;
++        CharBuffer cbf;
++        CharsetEncoder enc = Charset.forName(csn).newEncoder();
++        if (testDirect) {
++            bbf = ByteBuffer.allocateDirect(cc.length * 4);
++            cbf = ByteBuffer.allocateDirect(cc.length * 2).asCharBuffer();
++            cbf.put(cc).flip();
++        } else {
++            bbf = ByteBuffer.allocate(cc.length * 4);
++            cbf = CharBuffer.wrap(cc);
++        }
++
++        CoderResult cr = enc.encode(cbf, bbf, true);
++        if (cr != CoderResult.UNDERFLOW)
++            throw new RuntimeException("Encoding err: " + csn);
++        byte[] bb = new byte[bbf.position()];
++        bbf.flip(); bbf.get(bb);
++        return bb;
++    }
++
++    static CoderResult encodeCR(char[] cc, String csn, boolean testDirect)
++        throws Exception {
++        ByteBuffer bbf;
++        CharBuffer cbf;
++        CharsetEncoder enc = Charset.forName(csn).newEncoder();
++        if (testDirect) {
++            bbf = ByteBuffer.allocateDirect(cc.length * 4);
++            cbf = ByteBuffer.allocateDirect(cc.length * 2).asCharBuffer();
++            cbf.put(cc).flip();
++        } else {
++            bbf = ByteBuffer.allocate(cc.length * 4);
++            cbf = CharBuffer.wrap(cc);
++        }
++        return enc.encode(cbf, bbf, true);
++    }
++
++    static char[] getUTFChars() {
++        char[] cc = new char[0x10000 - 0xe000 + 0xd800 + //bmp
++                             (0x110000 - 0x10000) * 2];    //supp
++        int pos = 0;
++        int i = 0;
++        for (i = 0; i < 0xd800; i++)
++            cc[pos++] = (char)i;
++        for (i = 0xe000; i < 0x10000; i++)
++            cc[pos++] = (char)i;
++        for (i = 0x10000; i < 0x110000; i++) {
++            pos += Character.toChars(i, cc, pos);
++        }
++        return cc;
++    }
++
++    static int to3ByteUTF8(char c, byte[] bb, int pos) {
++        bb[pos++] = (byte)(0xe0 | ((c >> 12)));
++        bb[pos++] = (byte)(0x80 | ((c >> 06) & 0x3f));
++        bb[pos++] = (byte)(0x80 | ((c >> 00) & 0x3f));
++        return 3;
++    }
++
++    static void checkRoundtrip(String csn) throws Exception {
++        System.out.printf("    Check roundtrip <%s>...", csn);
++        char[] cc = getUTFChars();
++        byte[] bb = encode(cc, csn, false);
++        char[] ccO = decode(bb, csn, false);
++
++        if (!Arrays.equals(cc, ccO)) {
++            System.out.printf("    non-direct failed");
++        }
++        bb = encode(cc, csn, true);
++        ccO = decode(bb, csn, true);
++        if (!Arrays.equals(cc, ccO)) {
++            System.out.printf("    (direct) failed");
++        }
++        System.out.println();
++    }
++
++    static void check6ByteSurrs(String csn) throws Exception {
++        System.out.printf("    Check 6-byte Surrogates <%s>...%n", csn);
++        byte[] bb = new byte[(0x110000 - 0x10000) * 6];
++        char[] cc = new char[(0x110000 - 0x10000) * 2];
++        int bpos = 0;
++        int cpos = 0;
++        for (int i = 0x10000; i < 0x110000; i++) {
++            Character.toChars(i, cc, cpos);
++            bpos += to3ByteUTF8(cc[cpos], bb, bpos);
++            bpos += to3ByteUTF8(cc[cpos + 1], bb, bpos);
++            cpos += 2;
++        }
++
++        char[] ccO = decode(bb, csn, false);
++        if (!Arrays.equals(cc, ccO)) {
++            System.out.printf("    decoding failed%n");
++        }
++        ccO = decode(bb, csn, true);
++        if (!Arrays.equals(cc, ccO)) {
++            System.out.printf("    decoding(direct) failed%n");
++        }
++    }
++
++    static void compare(String csn1, String csn2) throws Exception {
++        System.out.printf("    Diff <%s> <%s>...%n", csn1, csn2);
++        char[] cc = getUTFChars();
++
++        byte[] bb1 = encode(cc, csn1, false);
++        byte[] bb2 = encode(cc, csn2, false);
++        if (!Arrays.equals(bb1, bb2))
++            System.out.printf("        encoding failed%n");
++        char[] cc1 = decode(bb1, csn1, false);
++        char[] cc2 = decode(bb1, csn2, false);
++        if (!Arrays.equals(cc1, cc2)) {
++            System.out.printf("        decoding failed%n");
++        }
++
++        bb1 = encode(cc, csn1, true);
++        bb2 = encode(cc, csn2, true);
++        if (!Arrays.equals(bb1, bb2))
++            System.out.printf("        encoding (direct) failed%n");
++        cc1 = decode(bb1, csn1, true);
++        cc2 = decode(bb1, csn2, true);
++        if (!Arrays.equals(cc1, cc2)) {
++            System.out.printf("        decoding (direct) failed%n");
++        }
++    }
++
++    // The first byte is the length of malformed bytes
++    static byte[][] malformed = {
++        // One-byte sequences:
++        {1, (byte)0xFF },
++        {1, (byte)0xC0 },
++        {1, (byte)0x80 },
++
++        {1, (byte)0xFF, (byte)0xFF}, // all ones
++        {1, (byte)0xA0, (byte)0x80}, // 101x first byte first nibble
++
++        // Two-byte sequences:
++        {1, (byte)0xC0, (byte)0x80}, // invalid first byte
++        {1, (byte)0xC1, (byte)0xBF}, // invalid first byte
++        {1, (byte)0xC2, (byte)0x00}, // invalid second byte
++        {1, (byte)0xC2, (byte)0xC0}, // invalid second byte
++        {1, (byte)0xD0, (byte)0x00}, // invalid second byte
++        {1, (byte)0xD0, (byte)0xC0}, // invalid second byte
++        {1, (byte)0xDF, (byte)0x00}, // invalid second byte
++        {1, (byte)0xDF, (byte)0xC0}, // invalid second byte
++
++        // Three-byte sequences
++        {1, (byte)0xE0, (byte)0x80, (byte)0x80},  // 111x first byte first nibble
++        {1, (byte)0xE0, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded
++        {1, (byte)0xE0, (byte)0x81, (byte)0xBF }, // U+007F zero-padded
++        {1, (byte)0xE0, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded
++
++        {1, (byte)0xE0, (byte)0xC0, (byte)0xBF }, // invalid second byte
++        {2, (byte)0xE0, (byte)0xA0, (byte)0x7F }, // invalid third byte
++        {2, (byte)0xE0, (byte)0xA0, (byte)0xC0 }, // invalid third byte
++        {1, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones
++        {1, (byte)0xE0, (byte)0xC0, (byte)0x80 }, // invalid second byte
++        {1, (byte)0xE0, (byte)0x80, (byte)0xC0 }, // invalid first byte
++
++        // Four-byte sequences
++        {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded
++        {1, (byte)0xF0, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded
++        {1, (byte)0xF0, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+007F zero-padded
++        {1, (byte)0xF0, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+07FF zero-padded
++
++        {1, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF }, // all ones
++        {1, (byte)0xF0, (byte)0x80, (byte)0x80, (byte)0x80},  // invalid second byte
++        {1, (byte)0xF0, (byte)0xC0, (byte)0x80, (byte)0x80 }, // invalid second byte
++        {2, (byte)0xF0, (byte)0x90, (byte)0xC0, (byte)0x80 }, // invalid third byte
++        {3, (byte)0xF0, (byte)0x90, (byte)0x80, (byte)0xC0 }, // invalid third byte
++
++        {1, (byte)0xF1, (byte)0xC0, (byte)0x80, (byte)0x80 }, // invalid second byte
++        {2, (byte)0xF1, (byte)0x80, (byte)0xC0, (byte)0x80 }, // invalid third byte
++        {3, (byte)0xF1, (byte)0x80, (byte)0x80, (byte)0xC0 }, // invalid forth byte
++        {1, (byte)0xF4, (byte)0x90, (byte)0x80, (byte)0xC0 }, // out-range 4-byte
++        {1, (byte)0xF4, (byte)0xC0, (byte)0x80, (byte)0xC0 }, // out-range 4-byte
++        {1, (byte)0xF5, (byte)0x80, (byte)0x80, (byte)0xC0 }, // out-range 4-byte
++
++        // Five-byte sequences
++        {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80},  // invalid first byte
++        {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded
++        {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded
++        {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded
++        {5, (byte)0xF8, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded
++
++        {1, (byte)0xF8, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80},
++        {2, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80 },
++        {3, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF },
++        {4, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0 },
++
++        // Six-byte sequences
++        {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 }, // U+0000 zero-padded
++        {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x81, (byte)0xBF }, // U+007F zero-padded
++        {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xBF }, // U+07FF zero-padded
++        {6, (byte)0xFC, (byte)0x80, (byte)0x80, (byte)0x8F, (byte)0xBF, (byte)0xBF }, // U+FFFF zero-padded
++        {1, (byte)0xF8, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80 },
++        {2, (byte)0xF8, (byte)0x80, (byte)0xC0, (byte)0x80, (byte)0x80, (byte)0x80 },
++        {3, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0xC1, (byte)0xBF, (byte)0x80 },
++        {4, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0xC0, (byte)0x80 },
++        {5, (byte)0xF8, (byte)0x80, (byte)0x80, (byte)0x9F, (byte)0x80, (byte)0xC0 },
++    };
++
++    static void checkMalformed(String csn) throws Exception {
++        boolean failed = false;
++        System.out.printf("    Check malformed <%s>...%n", csn);
++        for (boolean direct: new boolean[] {false, true}) {
++            for (byte[] bins : malformed) {
++                int mlen = bins[0];
++                byte[] bin = Arrays.copyOfRange(bins, 1, bins.length);
++                CoderResult cr = decodeCR(bin, csn, direct);
++                String ashex = "";
++                for (int i = 0; i < bin.length; i++) {
++                    if (i > 0) ashex += " ";
++                        ashex += Integer.toBinaryString((int)bin[i] & 0xff);
++                }
++                if (!cr.isMalformed()) {
++                    System.out.printf("        FAIL(direct=%b): [%s] not malformed.\n", direct, ashex);
++                    failed = true;
++                } else if (cr.length() != mlen) {
++                    System.out.printf("        FAIL(direct=%b): [%s] malformed[len=%d].\n", direct, ashex, cr.length());
++                    failed = true;
++                }
++            }
++        }
++        if (failed)
++            throw new RuntimeException("Check malformed failed " + csn);
++    }
++
++    static boolean check(CharsetDecoder dec, byte[] utf8s, boolean direct, int[] flow) {
++        int inPos = flow[0];
++        int inLen = flow[1];
++        int outPos = flow[2];
++        int outLen = flow[3];
++        int expedInPos = flow[4];
++        int expedOutPos = flow[5];
++        CoderResult expedCR = (flow[6]==0)?CoderResult.UNDERFLOW
++                                          :CoderResult.OVERFLOW;
++        ByteBuffer bbf;
++        CharBuffer cbf;
++        if (direct) {
++            bbf = ByteBuffer.allocateDirect(inPos + utf8s.length);
++            cbf = ByteBuffer.allocateDirect((outPos + outLen)*2).asCharBuffer();
++        } else {
++            bbf = ByteBuffer.allocate(inPos + utf8s.length);
++            cbf = CharBuffer.allocate(outPos + outLen);
++        }
++        bbf.position(inPos);
++        bbf.put(utf8s).flip().position(inPos).limit(inPos + inLen);
++        cbf.position(outPos);
++        dec.reset();
++        CoderResult cr = dec.decode(bbf, cbf, false);
++        if (cr != expedCR ||
++            bbf.position() != expedInPos ||
++            cbf.position() != expedOutPos) {
++            System.out.printf("Expected(direct=%5b): [", direct);
++            for (int i:flow) System.out.print(" " + i);
++            System.out.println("]  CR=" + cr +
++                               ", inPos=" + bbf.position() +
++                               ", outPos=" + cbf.position());
++            return false;
++        }
++        return true;
++    }
++
++    static void checkUnderOverflow(String csn) throws Exception {
++        System.out.printf("    Check under/overflow <%s>...%n", csn);
++        CharsetDecoder dec = Charset.forName(csn).newDecoder();
++        boolean failed = false;
++        byte[] utf8s = new String("\u007f\u07ff\ue000\ud800\udc00").getBytes("UTF-8");
++        int    inlen = utf8s.length;
++
++        for (int inoff = 0; inoff < 20; inoff++) {
++            for (int outoff = 0; outoff < 20; outoff++) {
++        int[][] Flows = {
++            //inpos, inLen, outPos,  outLen, inPosEP,   outposEP,   under(0)/over(1)
++            {inoff,  inlen, outoff,  1,      inoff + 1, outoff + 1, 1},
++            {inoff,  inlen, outoff,  2,      inoff + 3, outoff + 2, 1},
++            {inoff,  inlen, outoff,  3,      inoff + 6, outoff + 3, 1},
++            {inoff,  inlen, outoff,  4,      inoff + 6, outoff + 3, 1},
++            {inoff,  inlen, outoff,  5,      inoff + 10,outoff + 5, 0},
++             // underflow
++            {inoff,  1,     outoff,  5,      inoff + 1, outoff + 1, 0},
++            {inoff,  2,     outoff,  5,      inoff + 1, outoff + 1, 0},
++            {inoff,  3,     outoff,  5,      inoff + 3, outoff + 2, 0},
++            {inoff,  4,     outoff,  5,      inoff + 3, outoff + 2, 0},
++            {inoff,  5,     outoff,  5,      inoff + 3, outoff + 2, 0},
++            {inoff,  6,     outoff,  5,      inoff + 6, outoff + 3, 0},
++            {inoff,  7,     outoff,  5,      inoff + 6, outoff + 3, 0},
++            {inoff,  8,     outoff,  5,      inoff + 6, outoff + 3, 0},
++            {inoff,  9,     outoff,  5,      inoff + 6, outoff + 3, 0},
++            {inoff,  10,    outoff,  5,      inoff + 10,outoff + 5, 0},
++             // 2-byte underflow/overflow
++            {inoff,  2,     outoff,  1,      inoff + 1, outoff + 1, 0},
++            {inoff,  3,     outoff,  1,      inoff + 1, outoff + 1, 1},
++             // 3-byte underflow/overflow
++            {inoff,  4,     outoff,  2,      inoff + 3, outoff + 2, 0},
++            {inoff,  5,     outoff,  2,      inoff + 3, outoff + 2, 0},
++            {inoff,  6,     outoff,  2,      inoff + 3, outoff + 2, 1},
++             // 4-byte underflow/overflow
++            {inoff,  7,     outoff,  4,      inoff + 6, outoff + 3, 0},
++            {inoff,  8,     outoff,  4,      inoff + 6, outoff + 3, 0},
++            {inoff,  9,     outoff,  4,      inoff + 6, outoff + 3, 0},
++            {inoff,  10,    outoff,  4,      inoff + 6, outoff + 3, 1},
++        };
++        for (boolean direct: new boolean[] {false, true}) {
++            for (int[] flow: Flows) {
++                if (!check(dec, utf8s, direct, flow))
++                    failed = true;
++            }
++        }}}
++        if (failed)
++            throw new RuntimeException("Check under/overflow failed " + csn);
++    }
++
++    public static void main(String[] args) throws Exception {
++        checkRoundtrip("UTF-8");
++        check6ByteSurrs("UTF-8");
++        //compare("UTF-8", "UTF-8-OLD");
++        checkMalformed("UTF-8");
++        checkUnderOverflow("UTF-8");
++    }
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6484091.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,129 @@
+--- old/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java	Tue Nov 18 10:35:29 2008
++++ openjdk/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java	Tue Nov 18 10:35:29 2008
+@@ -38,6 +38,8 @@
+ import java.io.FileNotFoundException;
+ import java.io.IOException;
+ import java.util.*;
++import java.security.AccessController;
++import java.security.PrivilegedAction;
+ import javax.accessibility.*;
+ 
+ import sun.awt.shell.ShellFolder;
+@@ -957,7 +959,11 @@
+ 
+             File[] baseFolders;
+             if (useShellFolder) {
+-                baseFolders = (File[])ShellFolder.get("fileChooserComboBoxFolders");
++                baseFolders = AccessController.doPrivileged(new PrivilegedAction<File[]>() {
++                    public File[] run() {
++                        return (File[]) ShellFolder.get("fileChooserComboBoxFolders");
++                    }
++                });
+             } else {
+                 baseFolders = fsv.getRoots();
+             }
+--- old/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java	Tue Nov 18 10:35:30 2008
++++ openjdk/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java	Tue Nov 18 10:35:30 2008
+@@ -29,6 +29,8 @@
+ import java.beans.*;
+ import java.io.*;
+ import java.util.*;
++import java.security.AccessController;
++import java.security.PrivilegedAction;
+ 
+ import javax.swing.*;
+ import javax.swing.event.*;
+@@ -769,7 +771,11 @@
+ 
+             File[] baseFolders;
+             if (useShellFolder) {
+-                baseFolders = (File[])ShellFolder.get("fileChooserComboBoxFolders");
++                baseFolders = AccessController.doPrivileged(new PrivilegedAction<File[]>() {
++                    public File[] run() {
++                        return (File[]) ShellFolder.get("fileChooserComboBoxFolders");
++                    }
++                });
+             } else {
+                 baseFolders = fsv.getRoots();
+             }
+--- old/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java	Tue Nov 18 10:35:31 2008
++++ openjdk/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java	Tue Nov 18 10:35:31 2008
+@@ -39,6 +39,8 @@
+ import java.io.FileNotFoundException;
+ import java.io.IOException;
+ import java.util.*;
++import java.security.AccessController;
++import java.security.PrivilegedAction;
+ 
+ import sun.awt.shell.ShellFolder;
+ import sun.awt.OSInfo;
+@@ -1165,7 +1167,11 @@
+ 
+             File[] baseFolders;
+             if (useShellFolder) {
+-                baseFolders = (File[])ShellFolder.get("fileChooserComboBoxFolders");
++                baseFolders = AccessController.doPrivileged(new PrivilegedAction<File[]>() {
++                    public File[] run() {
++                        return (File[]) ShellFolder.get("fileChooserComboBoxFolders");
++                    }
++                });
+             } else {
+                 baseFolders = fsv.getRoots();
+             }
+--- old/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java	Tue Nov 18 10:35:32 2008
++++ openjdk/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java	Tue Nov 18 10:35:32 2008
+
+@@ -657,6 +657,10 @@
+      *         <code>null</code> if this shellfolder does not denote a directory.
+      */
+     public File[] listFiles(final boolean includeHiddenFiles) {
++        SecurityManager security = System.getSecurityManager();
++        if (security != null) {
++            security.checkRead(getPath());
++        }
+ 
+         return new ComTask<File[]>() {
+             public File[] call() throws Exception {
+--- /dev/null	Tue Nov 18 10:35:33 2008
++++ openjdk/jdk/test/javax/swing/JFileChooser/6484091/bug6484091.java	Tue Nov 18 10:35:33 2008
+@@ -0,0 +1,40 @@
++/* @test @(#)bug6484091.java	1.1 08/11/18
++ * @bug 6484091
++ * @summary FileSystemView leaks directory info
++ * @author Pavel Porvatov
++   @run main bug6484091
++ */
++
++import java.io.*;
++import java.security.AccessControlException;
++import javax.swing.filechooser.FileSystemView;
++import javax.swing.*;
++
++import sun.awt.shell.ShellFolder;
++
++public class bug6484091 {
++    public static void main(String[] args) {
++        ShellFolder dir = (ShellFolder) FileSystemView.getFileSystemView().getDefaultDirectory();
++
++        printDirContent(dir);
++
++        System.setSecurityManager(new SecurityManager());
++
++        // The next test cases use 'dir' obtained without SecurityManager
++        try {
++            printDirContent(dir);
++
++            throw new RuntimeException("Dir content was derived bypass SecurityManager");
++        } catch (AccessControlException e) {
++            // It's a successful situation
++        }
++    }
++
++    private static void printDirContent(File dir) {
++        System.out.println("Files in " + dir.getAbsolutePath() + ":");
++
++        for (File file : dir.listFiles()) {
++            System.out.println(file.getName());
++        }
++    }
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6497740.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,1589 @@
+--- old/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Fri Aug 22 18:58:20 2008
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Fri Aug 22 18:58:20 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -38,6 +38,8 @@
+ import sun.security.pkcs11.wrapper.*;
+ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+ 
++import sun.security.rsa.RSAKeyFactory;
++
+ /**
+  * KeyPairGenerator implementation class. This class currently supports
+  * RSA, DSA, DH, and EC.
+@@ -66,7 +68,7 @@
+     private AlgorithmParameterSpec params;
+ 
+     // for RSA, selected or default value of public exponent, always valid
+-    private BigInteger rsaPublicExponent;
++    private BigInteger rsaPublicExponent = RSAKeyGenParameterSpec.F4;
+ 
+     // SecureRandom instance, if specified in init
+     private SecureRandom random;
+@@ -88,7 +90,7 @@
+     public void initialize(int keySize, SecureRandom random) {
+         token.ensureValid();
+         try {
+-            checkKeySize(keySize);
++            checkKeySize(keySize, null);
+         } catch (InvalidAlgorithmParameterException e) {
+             throw new InvalidParameterException(e.getMessage());
+         }
+@@ -95,12 +97,12 @@
+         this.keySize = keySize;
+         this.params = null;
+         this.random = random;
+-        this.rsaPublicExponent = RSAKeyGenParameterSpec.F4;
+         if (algorithm.equals("EC")) {
+             params = P11ECKeyFactory.getECParameterSpec(keySize);
+             if (params == null) {
+-                throw new InvalidParameterException
+-                ("No EC parameters available for key size " + keySize + " bits");
++                throw new InvalidParameterException(
++                    "No EC parameters available for key size "
++                    + keySize + " bits");
+             }
+         }
+     }
+@@ -115,8 +117,10 @@
+                         ("DHParameterSpec required for Diffie-Hellman");
+             }
+             DHParameterSpec dhParams = (DHParameterSpec)params;
+-            this.keySize = dhParams.getP().bitLength();
+-            this.params = params;
++            int tmpKeySize = dhParams.getP().bitLength();
++            checkKeySize(tmpKeySize, dhParams);
++            this.keySize = tmpKeySize;
++            this.params = dhParams;
+             // XXX sanity check params
+         } else if (algorithm.equals("RSA")) {
+             if (params instanceof RSAKeyGenParameterSpec == false) {
+@@ -124,7 +128,9 @@
+                         ("RSAKeyGenParameterSpec required for RSA");
+             }
+             RSAKeyGenParameterSpec rsaParams = (RSAKeyGenParameterSpec)params;
+-            this.keySize = rsaParams.getKeysize();
++            int tmpKeySize = rsaParams.getKeysize();
++            checkKeySize(tmpKeySize, rsaParams);
++            this.keySize = tmpKeySize;
+             this.params = null;
+             this.rsaPublicExponent = rsaParams.getPublicExponent();
+             // XXX sanity check params
+@@ -134,13 +140,16 @@
+                         ("DSAParameterSpec required for DSA");
+             }
+             DSAParameterSpec dsaParams = (DSAParameterSpec)params;
+-            this.keySize = dsaParams.getP().bitLength();
+-            this.params = params;
++            int tmpKeySize = dsaParams.getP().bitLength();
++            checkKeySize(tmpKeySize, dsaParams);
++            this.keySize = tmpKeySize;
++            this.params = dsaParams;
+             // XXX sanity check params
+         } else if (algorithm.equals("EC")) {
+             ECParameterSpec ecParams;
+             if (params instanceof ECParameterSpec) {
+-                ecParams = P11ECKeyFactory.getECParameterSpec((ECParameterSpec)params);
++                ecParams = P11ECKeyFactory.getECParameterSpec(
++                    (ECParameterSpec)params);
+                 if (ecParams == null) {
+                     throw new InvalidAlgorithmParameterException
+                         ("Unsupported curve: " + params);
+@@ -156,16 +165,17 @@
+                 throw new InvalidAlgorithmParameterException
+                     ("ECParameterSpec or ECGenParameterSpec required for EC");
+             }
+-            this.keySize = ecParams.getCurve().getField().getFieldSize();
++            int tmpKeySize = ecParams.getCurve().getField().getFieldSize();
++            checkKeySize(tmpKeySize, ecParams);
++            this.keySize = tmpKeySize;
+             this.params = ecParams;
+         } else {
+             throw new ProviderException("Unknown algorithm: " + algorithm);
+         }
+         this.random = random;
+-        checkKeySize(keySize);
+     }
+ 
+-    private void checkKeySize(int keySize)
++    private void checkKeySize(int keySize, AlgorithmParameterSpec params)
+             throws InvalidAlgorithmParameterException {
+         if (algorithm.equals("EC")) {
+             if (keySize < 112) {
+@@ -178,13 +188,28 @@
+                     ("Key size must be at most 2048 bit");
+             }
+             return;
++        } else if (algorithm.equals("RSA")) {
++            BigInteger tmpExponent = rsaPublicExponent;
++            if (params != null) {
++                // Already tested for instanceof RSAKeyGenParameterSpec above
++                tmpExponent =
++                    ((RSAKeyGenParameterSpec)params).getPublicExponent();
++            }
++            try {
++                // This provider supports 64K or less.
++                RSAKeyFactory.checkKeyLengths(keySize, tmpExponent,
++                    512, 64 * 1024);
++            } catch (InvalidKeyException e) {
++                throw new InvalidAlgorithmParameterException(e.getMessage());
++            }
++            return;
+         }
++
+         if (keySize < 512) {
+             throw new InvalidAlgorithmParameterException
+                 ("Key size must be at least 512 bit");
+         }
+-        if (algorithm.equals("RSA") ||
+-                (algorithm.equals("DH") && (params != null))) {
++        if (algorithm.equals("DH") && (params != null)) {
+             // sanity check, nobody really wants keys this large
+             if (keySize > 64 * 1024) {
+                 throw new InvalidAlgorithmParameterException
+--- old/src/share/classes/sun/security/pkcs11/P11KeyStore.java	Fri Aug 22 18:58:29 2008
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11KeyStore.java	Fri Aug 22 18:58:29 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -80,6 +80,8 @@
+ import sun.security.pkcs11.wrapper.*;
+ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+ 
++import sun.security.rsa.RSAKeyFactory;
++
+ final class P11KeyStore extends KeyStoreSpi {
+ 
+     private static final CK_ATTRIBUTE ATTR_CLASS_CERT =
+@@ -1335,6 +1337,15 @@
+             BigInteger modulus = attrs[0].getBigInteger();
+             keyLength = modulus.bitLength();
+ 
++            // This check will combine our "don't care" values here
++            // with the system-wide min/max values.
++            try {
++                RSAKeyFactory.checkKeyLengths(keyLength, null,
++                    -1, Integer.MAX_VALUE);
++            } catch (InvalidKeyException e) {
++                throw new KeyStoreException(e.getMessage());
++            }
++
+             return P11Key.privateKey(session,
+                                 oHandle,
+                                 keyType,
+--- old/src/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java	Fri Aug 22 18:58:37 2008
++++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java	Fri Aug 22 18:58:37 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -35,6 +35,8 @@
+ import sun.security.pkcs11.wrapper.*;
+ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+ 
++import sun.security.rsa.RSAKeyFactory;
++
+ /**
+  * RSA KeyFactory implemenation.
+  *
+@@ -131,6 +133,9 @@
+         } catch (PKCS11Exception e) {
+             throw new InvalidKeySpecException
+                 ("Could not create RSA public key", e);
++        } catch (InvalidKeyException e) {
++            throw new InvalidKeySpecException
++                ("Could not create RSA public key", e);
+         }
+     }
+ 
+@@ -175,11 +180,15 @@
+         } catch (PKCS11Exception e) {
+             throw new InvalidKeySpecException
+                 ("Could not create RSA private key", e);
++        } catch (InvalidKeyException e) {
++            throw new InvalidKeySpecException
++                ("Could not create RSA private key", e);
+         }
+     }
+ 
+     private PublicKey generatePublic(BigInteger n, BigInteger e)
+-            throws PKCS11Exception {
++            throws PKCS11Exception, InvalidKeyException {
++        RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
+         CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+             new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
+             new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
+@@ -200,7 +209,8 @@
+     }
+ 
+     private PrivateKey generatePrivate(BigInteger n, BigInteger d)
+-            throws PKCS11Exception {
++            throws PKCS11Exception, InvalidKeyException {
++        RSAKeyFactory.checkKeyLengths(n.bitLength(), null, -1, 64 * 1024);
+         CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+             new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
+             new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
+@@ -222,7 +232,9 @@
+ 
+     private PrivateKey generatePrivate(BigInteger n, BigInteger e,
+             BigInteger d, BigInteger p, BigInteger q, BigInteger pe,
+-            BigInteger qe, BigInteger coeff) throws PKCS11Exception {
++            BigInteger qe, BigInteger coeff) throws PKCS11Exception,
++            InvalidKeyException {
++        RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
+         CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+             new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
+             new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
+--- old/src/share/classes/sun/security/rsa/RSAKeyFactory.java	Fri Aug 22 18:58:44 2008
++++ openjdk/jdk/src/share/classes/sun/security/rsa/RSAKeyFactory.java	Fri Aug 22 18:58:43 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -31,6 +31,8 @@
+ import java.security.interfaces.*;
+ import java.security.spec.*;
+ 
++import sun.security.action.GetPropertyAction;
++
+ /**
+  * KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey
+  * and getAlgorithm() must return "RSA". For such keys, it supports conversion
+@@ -68,6 +70,24 @@
+     private final static Class<?> x509KeySpecClass  = X509EncodedKeySpec.class;
+     private final static Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class;
+ 
++    public final static int MIN_MODLEN = 512;
++    public final static int MAX_MODLEN = 16384;
++
++    /*
++     * If the modulus length is above this value, restrict the size of
++     * the exponent to something that can be reasonably computed.  We
++     * could simply hardcode the exp len to something like 64 bits, but
++     * this approach allows flexibility in case impls would like to use
++     * larger module and exponent values.
++     */
++    public final static int MAX_MODLEN_RESTRICT_EXP = 3072;
++    public final static int MAX_RESTRICTED_EXPLEN = 64;
++
++    private static final boolean restrictExpLen =
++        "true".equalsIgnoreCase(AccessController.doPrivileged(
++            new GetPropertyAction(
++                "sun.security.rsa.restrictRSAExponent", "true")));
++
+     // instance used for static translateKey();
+     private final static RSAKeyFactory INSTANCE = new RSAKeyFactory();
+ 
+@@ -76,75 +96,80 @@
+     }
+ 
+     /**
+-     * Static method to convert Key into a useable instance of
+-     * RSAPublicKey or RSAPrivate(Crt)Key. Check the key and convert it
+-     * to a SunRsaSign key if necessary. If the key is not an RSA key
+-     * or cannot be used, throw an InvalidKeyException.
++     * Static method to convert Key into an instance of RSAPublicKeyImpl
++     * or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be
++     * used, throw an InvalidKeyException.
+      *
+-     * The difference between this method and engineTranslateKey() is that
+-     * we do not convert keys of other providers that are already an
+-     * instance of RSAPublicKey or RSAPrivate(Crt)Key.
+-     *
+      * Used by RSASignature and RSACipher.
+      */
+     public static RSAKey toRSAKey(Key key) throws InvalidKeyException {
+-        if (key instanceof RSAKey) {
+-            RSAKey rsaKey = (RSAKey)key;
+-            checkKey(rsaKey);
+-            return rsaKey;
++        if ((key instanceof RSAPrivateKeyImpl) ||
++            (key instanceof RSAPrivateCrtKeyImpl) ||
++            (key instanceof RSAPublicKeyImpl)) {
++            return (RSAKey)key;
+         } else {
+             return (RSAKey)INSTANCE.engineTranslateKey(key);
+         }
+     }
+ 
+-    /**
+-     * Check that the given RSA key is valid.
++    /*
++     * Single test entry point for all of the mechanisms in the SunRsaSign
++     * provider (RSA*KeyImpls).  All of the tests are the same.
++     *
++     * For compatibility, we round up to the nearest byte here:
++     * some Key impls might pass in a value within a byte of the
++     * real value.
+      */
+-    private static void checkKey(RSAKey key) throws InvalidKeyException {
+-        // check for subinterfaces, omit additional checks for our keys
+-        if (key instanceof RSAPublicKey) {
+-            if (key instanceof RSAPublicKeyImpl) {
+-                return;
+-            }
+-        } else if (key instanceof RSAPrivateKey) {
+-            if ((key instanceof RSAPrivateCrtKeyImpl)
+-                    || (key instanceof RSAPrivateKeyImpl)) {
+-                return;
+-            }
+-        } else {
+-            throw new InvalidKeyException("Neither a public nor a private key");
+-        }
+-        // RSAKey does not extend Key, so we need to do a cast
+-        String keyAlg = ((Key)key).getAlgorithm();
+-        if (keyAlg.equals("RSA") == false) {
+-            throw new InvalidKeyException("Not an RSA key: " + keyAlg);
+-        }
+-        BigInteger modulus;
+-        // some providers implement RSAKey for keys where the values are
+-        // not accessible (although they should). Detect those here
+-        // for a more graceful failure.
+-        try {
+-            modulus = key.getModulus();
+-            if (modulus == null) {
+-                throw new InvalidKeyException("Modulus is missing");
+-            }
+-        } catch (RuntimeException e) {
+-            throw new InvalidKeyException(e);
+-        }
+-        checkKeyLength(modulus);
++    static void checkRSAProviderKeyLengths(int modulusLen, BigInteger exponent)
++            throws InvalidKeyException {
++        checkKeyLengths(((modulusLen + 7) & ~7), exponent,
++            RSAKeyFactory.MIN_MODLEN, Integer.MAX_VALUE);
+     }
+ 
+     /**
+-     * Check the length of the modulus of an RSA key. We only support keys
+-     * at least 505 bits long.
++     * Check the length of an RSA key modulus/exponent to make sure it
++     * is not too short or long.  Some impls have their own min and
++     * max key sizes that may or may not match with a system defined value.
++     *
++     * @param modulusLen the bit length of the RSA modulus.
++     * @param exponent the RSA exponent
++     * @param minModulusLen if > 0, check to see if modulusLen is at
++     *        least this long, otherwise unused.
++     * @param maxModulusLen caller will allow this max number of bits.
++     *        Allow the smaller of the system-defined maximum and this param.
++     *
++     * @throws InvalidKeyException if any of the values are unacceptable.
+      */
+-    static void checkKeyLength(BigInteger modulus) throws InvalidKeyException {
+-        if (modulus.bitLength() < 505) {
+-            // some providers may generate slightly shorter keys
+-            // accept them if the encoding is at least 64 bytes long
+-            throw new InvalidKeyException
+-                ("RSA keys must be at least 512 bits long");
++     public static void checkKeyLengths(int modulusLen, BigInteger exponent,
++            int minModulusLen, int maxModulusLen) throws InvalidKeyException {
++
++        if ((minModulusLen > 0) && (modulusLen < (minModulusLen))) {
++            throw new InvalidKeyException( "RSA keys must be at least " +
++                minModulusLen + " bits long");
+         }
++
++        // Even though our policy file may allow this, we don't want
++        // either value (mod/exp) to be too big.
++
++        int maxLen = Math.min(maxModulusLen, MAX_MODLEN);
++
++        // If a RSAPrivateKey/RSAPublicKey, make sure the
++        // modulus len isn't too big.
++        if (modulusLen > maxLen) {
++            throw new InvalidKeyException(
++                "RSA keys must be no longer than " + maxLen + " bits");
++        }
++
++        // If a RSAPublicKey, make sure the exponent isn't too big.
++        if (restrictExpLen && (exponent != null) &&
++                (modulusLen > MAX_MODLEN_RESTRICT_EXP) &&
++                (exponent.bitLength() > MAX_RESTRICTED_EXPLEN)) {
++            throw new InvalidKeyException(
++                "RSA exponents can be no longer than " +
++                MAX_RESTRICTED_EXPLEN + " bits " +
++                " if modulus is greater than " +
++                MAX_MODLEN_RESTRICT_EXP + " bits");
++        }
+     }
+ 
+     /**
+--- old/src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java	Fri Aug 22 18:58:50 2008
++++ openjdk/jdk/src/share/classes/sun/security/rsa/RSAKeyPairGenerator.java	Fri Aug 22 18:58:49 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -47,7 +47,7 @@
+     // public exponent to use
+     private BigInteger publicExponent;
+ 
+-    // size of the key to generate, >= 512
++    // size of the key to generate, >= RSAKeyFactory.MIN_MODLEN
+     private int keySize;
+ 
+     // PRNG to use
+@@ -60,15 +60,16 @@
+ 
+     // initialize the generator. See JCA doc
+     public void initialize(int keySize, SecureRandom random) {
+-        if (keySize < 512) {
+-            throw new InvalidParameterException
+-                ("Key size must be at least 512 bits");
++
++        // do not allow unreasonably small or large key sizes,
++        // probably user error
++        try {
++            RSAKeyFactory.checkKeyLengths(keySize, RSAKeyGenParameterSpec.F4,
++                512, 64 * 1024);
++        } catch (InvalidKeyException e) {
++            throw new InvalidParameterException(e.getMessage());
+         }
+-        if (keySize > 64 * 1024) {
+-            // do not allow unreasonably large key sizes, probably user error
+-            throw new InvalidParameterException
+-                ("Key size must be 65536 bits or less");
+-        }
++
+         this.keySize = keySize;
+         this.random = random;
+         this.publicExponent = RSAKeyGenParameterSpec.F4;
+@@ -77,35 +78,41 @@
+     // second initialize method. See JCA doc.
+     public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+             throws InvalidAlgorithmParameterException {
++
+         if (params instanceof RSAKeyGenParameterSpec == false) {
+             throw new InvalidAlgorithmParameterException
+                 ("Params must be instance of RSAKeyGenParameterSpec");
+         }
++
+         RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
+-        keySize = rsaSpec.getKeysize();
+-        publicExponent = rsaSpec.getPublicExponent();
+-        this.random = random;
+-        if (keySize < 512) {
+-            throw new InvalidAlgorithmParameterException
+-                ("Key size must be at least 512 bits");
+-        }
+-        if (keySize > 64 * 1024) {
+-            // do not allow unreasonably large key sizes, probably user error
+-            throw new InvalidAlgorithmParameterException
+-                ("Key size must be 65536 bits or less");
+-        }
+-        if (publicExponent == null) {
+-            publicExponent = RSAKeyGenParameterSpec.F4;
++        int tmpKeySize = rsaSpec.getKeysize();
++        BigInteger tmpPublicExponent = rsaSpec.getPublicExponent();
++
++        if (tmpPublicExponent == null) {
++            tmpPublicExponent = RSAKeyGenParameterSpec.F4;
+         } else {
+-            if (publicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) {
++            if (tmpPublicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) {
+                 throw new InvalidAlgorithmParameterException
+                         ("Public exponent must be 3 or larger");
+             }
+-            if (publicExponent.bitLength() > keySize) {
++            if (tmpPublicExponent.bitLength() > tmpKeySize) {
+                 throw new InvalidAlgorithmParameterException
+                         ("Public exponent must be smaller than key size");
+             }
+         }
++
++        // do not allow unreasonably large key sizes, probably user error
++        try {
++            RSAKeyFactory.checkKeyLengths(tmpKeySize, tmpPublicExponent,
++                512, 64 * 1024);
++        } catch (InvalidKeyException e) {
++            throw new InvalidAlgorithmParameterException(
++                "Invalid key sizes", e);
++        }
++
++        this.keySize = tmpKeySize;
++        this.publicExponent = tmpPublicExponent;
++        this.random = random;
+     }
+ 
+     // generate the keypair. See JCA doc
+--- old/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java	Fri Aug 22 18:58:56 2008
++++ openjdk/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java	Fri Aug 22 18:58:56 2008
+
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -89,7 +89,7 @@
+      */
+     RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
+         decode(encoded);
+-        RSAKeyFactory.checkKeyLength(n);
++        RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
+     }
+ 
+     /**
+@@ -107,7 +107,8 @@
+         this.pe = pe;
+         this.qe = qe;
+         this.coeff = coeff;
+-        RSAKeyFactory.checkKeyLength(n);
++        RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
++
+         // generate the encoding
+         algid = rsaId;
+         try {
+--- old/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java	Fri Aug 22 18:59:02 2008
++++ openjdk/jdk/src/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java	Fri Aug 22 18:59:01 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -61,7 +61,7 @@
+     RSAPrivateKeyImpl(BigInteger n, BigInteger d) throws InvalidKeyException {
+         this.n = n;
+         this.d = d;
+-        RSAKeyFactory.checkKeyLength(n);
++        RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null);
+         // generate the encoding
+         algid = RSAPrivateCrtKeyImpl.rsaId;
+         try {
+--- old/src/share/classes/sun/security/rsa/RSAPublicKeyImpl.java	Fri Aug 22 18:59:07 2008
++++ openjdk/jdk/src/share/classes/sun/security/rsa/RSAPublicKeyImpl.java	Fri Aug 22 18:59:07 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -56,10 +56,11 @@
+      * Construct a key from its components. Used by the
+      * RSAKeyFactory and the RSAKeyPairGenerator.
+      */
+-    public RSAPublicKeyImpl(BigInteger n, BigInteger e) throws InvalidKeyException {
++    public RSAPublicKeyImpl(BigInteger n, BigInteger e)
++            throws InvalidKeyException {
+         this.n = n;
+         this.e = e;
+-        RSAKeyFactory.checkKeyLength(n);
++        RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
+         // generate the encoding
+         algid = RSAPrivateCrtKeyImpl.rsaId;
+         try {
+@@ -80,7 +81,7 @@
+      */
+     public RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
+         decode(encoded);
+-        RSAKeyFactory.checkKeyLength(n);
++        RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
+     }
+ 
+     // see JCA doc
+--- old/src/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java	Fri Aug 22 18:59:11 2008
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java	Fri Aug 22 18:59:11 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -31,6 +31,7 @@
+ import java.security.spec.RSAKeyGenParameterSpec;
+ 
+ import sun.security.jca.JCAUtil;
++import sun.security.rsa.RSAKeyFactory;
+ 
+ /**
+  * RSA keypair generator.
+@@ -43,8 +44,8 @@
+ public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
+ 
+     // Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
+-    private static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
+-    private static final int KEY_SIZE_MAX = 16384;
++    static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
++    static final int KEY_SIZE_MAX = 16384;
+     private static final int KEY_SIZE_DEFAULT = 1024;
+ 
+     // size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
+@@ -59,7 +60,14 @@
+     // random is always ignored
+     public void initialize(int keySize, SecureRandom random) {
+ 
+-        checkKeySize(keySize);
++        try {
++            RSAKeyFactory.checkKeyLengths(keySize, null,
++                KEY_SIZE_MIN, KEY_SIZE_MAX);
++        } catch (InvalidKeyException e) {
++            throw new InvalidParameterException(e.getMessage());
++        }
++
++        this.keySize = keySize;
+     }
+ 
+     // second initialize method. See JCA doc
+@@ -67,9 +75,9 @@
+     public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+             throws InvalidAlgorithmParameterException {
+ 
++        int tmpSize;
+         if (params == null) {
+-            checkKeySize(KEY_SIZE_DEFAULT);
+-
++            tmpSize = KEY_SIZE_DEFAULT;
+         } else if (params instanceof RSAKeyGenParameterSpec) {
+ 
+             if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
+@@ -76,12 +84,22 @@
+                 throw new InvalidAlgorithmParameterException
+                     ("Exponent parameter is not supported");
+             }
+-            checkKeySize(((RSAKeyGenParameterSpec) params).getKeysize());
++            tmpSize = ((RSAKeyGenParameterSpec) params).getKeysize();
+ 
+         } else {
+             throw new InvalidAlgorithmParameterException
+                 ("Params must be an instance of RSAKeyGenParameterSpec");
+         }
++
++        try {
++            RSAKeyFactory.checkKeyLengths(tmpSize, null,
++                KEY_SIZE_MIN, KEY_SIZE_MAX);
++        } catch (InvalidKeyException e) {
++            throw new InvalidAlgorithmParameterException(
++                "Invalid Key sizes", e);
++        }
++
++        this.keySize = tmpSize;
+     }
+ 
+     // generate the keypair. See JCA doc
+@@ -95,18 +113,6 @@
+         return new KeyPair(keys.getPublic(), keys.getPrivate());
+     }
+ 
+-    private void checkKeySize(int keySize) throws InvalidParameterException {
+-        if (keySize < KEY_SIZE_MIN) {
+-            throw new InvalidParameterException
+-                ("Key size must be at least " + KEY_SIZE_MIN + " bits");
+-        }
+-        if (keySize > KEY_SIZE_MAX) {
+-            throw new InvalidParameterException
+-                ("Key size must be " + KEY_SIZE_MAX + " bits or less");
+-        }
+-        this.keySize = keySize;
+-    }
+-
+     private static native RSAKeyPair generateRSAKeyPair(int keySize,
+         String keyContainerName);
+ }
+--- old/src/windows/classes/sun/security/mscapi/RSASignature.java	Fri Aug 22 18:59:18 2008
++++ openjdk/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java	Fri Aug 22 18:59:17 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -38,7 +38,10 @@
+ import java.security.Signature;
+ import java.security.SignatureSpi;
+ import java.security.SignatureException;
++import java.math.BigInteger;
+ 
++import sun.security.rsa.RSAKeyFactory;
++
+ /**
+  * RSA signature implementation. Supports RSA signing using PKCS#1 v1.5 padding.
+  *
+@@ -124,8 +127,17 @@
+ 
+             // convert key to MSCAPI format
+ 
+-            byte[] modulusBytes = rsaKey.getModulus().toByteArray();
++            BigInteger modulus = rsaKey.getModulus();
++            BigInteger exponent =  rsaKey.getPublicExponent();
+ 
++            // Check against the local and global values to make sure
++            // the sizes are ok.  Round up to the nearest byte.
++            RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
++                exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX);
++
++            byte[] modulusBytes = modulus.toByteArray();
++            byte[] exponentBytes = exponent.toByteArray();
++
+             // Adjust key length due to sign bit
+             int keyBitLength = (modulusBytes[0] == 0)
+                 ? (modulusBytes.length - 1) * 8
+@@ -132,8 +144,7 @@
+                 : modulusBytes.length * 8;
+ 
+             byte[] keyBlob = generatePublicKeyBlob(
+-                keyBitLength, modulusBytes,
+-                rsaKey.getPublicExponent().toByteArray());
++                keyBitLength, modulusBytes, exponentBytes);
+ 
+             publicKey = importPublicKey(keyBlob, keyBitLength);
+ 
+@@ -166,13 +177,12 @@
+         }
+         privateKey = (sun.security.mscapi.RSAPrivateKey) key;
+ 
+-        // Determine byte length from bit length
+-        int keySize = (privateKey.bitLength() + 7) >> 3;
++        // Check against the local and global values to make sure
++        // the sizes are ok.  Round up to nearest byte.
++        RSAKeyFactory.checkKeyLengths(((privateKey.bitLength() + 7) & ~7),
++            null, RSAKeyPairGenerator.KEY_SIZE_MIN,
++            RSAKeyPairGenerator.KEY_SIZE_MAX);
+ 
+-        if (keySize < 64)
+-            throw new InvalidKeyException(
+-                "RSA keys must be at least 512 bits long");
+-
+         if (needsReset) {
+             messageDigest.reset();
+             needsReset = false;
+--- /dev/null	Fri Aug 22 18:59:23 2008
++++ openjdk/jdk/test/closed/sun/security/rsa/TestLimits.java	Fri Aug 22 18:59:22 2008
+@@ -0,0 +1,772 @@
++/**
++ * @test
++ * @bug 6497740
++ * @summary Limit the size of RSA public keys
++ * @author Brad R. Wetmore
++ */
++
++/**
++ * Test the long RSA key restrictions.
++ *
++ * In many of the tests, I am not creating valid key or keyspecs,
++ * because they would take too long to generate, especially for the longer
++ * ones.  Instead I'm just using values that will trigger the appropriate
++ * checks.
++ *
++ * This test uses two prebuilt keystores, one containing a 16385 bit key,
++ * which would take forever to generate during automatic testing.
++ *
++ * keytool -genkeypair -alias duke1 -keyalg RSA -keysize 1024 \
++ *     -validity 3650 -keystore keystore.good
++ *
++ * keytool -genkeypair -alias duke1 -keyalg RSA -keysize 16385 \
++ *     -validity 3650 -keystore keystore.bad
++ */
++
++import java.math.BigInteger;
++import java.util.Random;
++import java.security.*;
++import java.security.spec.*;
++import java.security.interfaces.*;
++import java.io.*;
++
++// Obtain the current length values.
++import sun.security.rsa.RSAKeyFactory;
++
++public class TestLimits {
++
++    private final static String BASE = System.getProperty("test.src", ".");
++
++    private static SecureRandom random = new SecureRandom();
++
++    private static final String SunRSA = "SunRsaSign";
++    private static final String MSCAPI = "SunMSCAPI";
++    private static final String P11 = "SunPKCS11-Solaris";
++
++    /*
++     * Helper method which generates simple keys of length len.
++     */
++    private static BigInteger getBigInteger(int len) {
++        return BigInteger.ZERO.setBit(len - 1);
++    }
++
++    /*
++     * Tests the RSAKeyPairGenerator.initialize(len) returns
++     * the right results.
++     */
++    private static void testRSAKeyPairGeneratorLen(String provider, boolean b,
++            int len) throws Exception {
++
++        System.out.println("testRSAKeyPairGeneratorLen.initialize: " +
++            len + " " + b + " " + provider);
++
++        KeyPairGenerator kpg =
++            KeyPairGenerator.getInstance("RSA", provider);
++        try {
++            kpg.initialize(len);
++            if (!b) {
++                throw new Exception("Should have failed");
++            }
++        } catch (InvalidParameterException e) {
++            if (b) {
++                throw new Exception("Should have passed", e);
++            }
++        }
++        kpg = KeyPairGenerator.getInstance("RSA", provider);
++        try {
++            kpg.initialize(len, random);
++            if (!b) {
++                throw new Exception("Should have failed");
++            }
++        } catch (InvalidParameterException e) {
++            if (b) {
++                throw new Exception("Should have passed", e);
++            }
++        }
++    }
++
++    /*
++     * Tests the RSAKeyPairGenerator.initialize(KeySpec) returns
++     * the right results.  If expLen > 0, then create a
++     * corresponding value, otherwise, leave null.
++     */
++    private static void testRSAKeyPairGeneratorSpec(String provider,
++            boolean b, int modLen, int expLen) throws Exception {
++
++        System.out.println(
++            "testRSAKeyPairGeneratorSpec.initialize: " +
++            modLen + " " + expLen + " " + b + " " + provider);
++
++        RSAKeyGenParameterSpec keySpec = new RSAKeyGenParameterSpec(
++            modLen, (expLen > 0) ? getBigInteger(expLen) : null);
++
++        KeyPairGenerator kpg =
++            KeyPairGenerator.getInstance("RSA", provider);
++        try {
++            kpg.initialize(keySpec);
++            if (!b) {
++                throw new Exception("Should have failed");
++            }
++        } catch (InvalidParameterException e) {
++            if (b) {
++                throw new Exception("Should have passed", e);
++            }
++        } catch (InvalidAlgorithmParameterException e) {
++            if (b) {
++                throw new Exception("Should have passed", e);
++            }
++        }
++        kpg = KeyPairGenerator.getInstance("RSA", provider);
++        try {
++            kpg.initialize(keySpec, random);
++            if (!b) {
++                throw new Exception("Should have failed");
++            }
++        } catch (InvalidParameterException e) {
++            if (b) {
++                throw new Exception("Should have passed", e);
++            }
++        } catch (InvalidAlgorithmParameterException e) {
++            if (b) {
++                throw new Exception("Should have passed", e);
++            }
++        }
++    }
++
++    /*
++     * Driver for the above two tests.  Tests most of the cases.
++     * Other tests below are subsets of this.
++     */
++    private static void testRSAKeyPairGenerator() throws Exception {
++
++        // Start with the small, medium, and large modulus values only.
++        testRSAKeyPairGeneratorLen(SunRSA, false,
++            RSAKeyFactory.MIN_MODLEN - 1);
++        testRSAKeyPairGeneratorLen(SunRSA, true,
++            RSAKeyFactory.MIN_MODLEN);
++        testRSAKeyPairGeneratorLen(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP);
++        testRSAKeyPairGeneratorLen(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN);
++        testRSAKeyPairGeneratorLen(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            2048, 2049);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MIN_MODLEN - 1, -1);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MIN_MODLEN - 1,
++            RSAKeyGenParameterSpec.F0.intValue() - 1);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MIN_MODLEN - 1,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MIN_MODLEN - 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MIN_MODLEN - 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MIN_MODLEN, -1);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MIN_MODLEN,
++            RSAKeyGenParameterSpec.F0.intValue() - 1);
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MIN_MODLEN,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MIN_MODLEN,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MIN_MODLEN,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP, -1);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP,
++            RSAKeyGenParameterSpec.F0.intValue() - 1);
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP + 1,
++            -1);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP + 1,
++            RSAKeyGenParameterSpec.F0.intValue() - 1);
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP + 1,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP + 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP + 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN,
++            -1);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN,
++            RSAKeyGenParameterSpec.F0.intValue() - 1);
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(SunRSA, true,
++            RSAKeyFactory.MAX_MODLEN,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN + 1,
++            -1);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN + 1,
++            RSAKeyGenParameterSpec.F0.intValue() - 1);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN + 1,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN + 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(SunRSA, false,
++            RSAKeyFactory.MAX_MODLEN + 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++    }
++
++    /*
++     * Driver for the above two tests.  Tests most of the cases.
++     * Other tests below are subsets of this.
++     */
++    private static void testP11KeyPairGenerator() throws Exception {
++
++        // Start with the small, medium, and large modulus values only.
++        testRSAKeyPairGeneratorLen(P11, false,
++            RSAKeyFactory.MIN_MODLEN - 1);
++        testRSAKeyPairGeneratorLen(P11, true,
++            RSAKeyFactory.MIN_MODLEN);
++        testRSAKeyPairGeneratorLen(P11, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP);
++        testRSAKeyPairGeneratorLen(P11, true,
++            RSAKeyFactory.MAX_MODLEN);
++        testRSAKeyPairGeneratorLen(P11, false,
++            RSAKeyFactory.MAX_MODLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MIN_MODLEN - 1, -1);
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MIN_MODLEN - 1,
++            RSAKeyGenParameterSpec.F0.intValue() - 1);
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MIN_MODLEN - 1,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MIN_MODLEN - 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MIN_MODLEN - 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MIN_MODLEN, -1);
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MIN_MODLEN,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MIN_MODLEN,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MIN_MODLEN,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP, -1);
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP + 1, -1);
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP + 1,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP + 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP + 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MAX_MODLEN, -1);
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MAX_MODLEN,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(P11, true,
++            RSAKeyFactory.MAX_MODLEN,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MAX_MODLEN,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MAX_MODLEN + 1, -1);
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MAX_MODLEN + 1,
++            RSAKeyGenParameterSpec.F0.intValue() - 1);
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MAX_MODLEN + 1,
++            RSAKeyGenParameterSpec.F0.intValue());
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MAX_MODLEN + 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN);
++        testRSAKeyPairGeneratorSpec(P11, false,
++            RSAKeyFactory.MAX_MODLEN + 1,
++            RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1);
++    }
++
++    /*
++     * Test the KeyFactory translations.
++     */
++    private static void testTranslateKey(String provider, boolean b, Key key)
++            throws Exception {
++        System.out.println("testTranslateKey: " + b + " " + key + " " +
++            provider);
++
++        KeyFactory kf = KeyFactory.getInstance("RSA", provider);
++
++        try {
++            kf.translateKey(key);
++            if (!b) {
++                throw new Exception("Should have failed");
++            }
++        } catch (InvalidKeyException e) {
++            if (b) {
++                throw new Exception("Should have passed", e);
++            }
++        }
++    }
++
++    /*
++     * Test the KeyFactory's translation code.
++     *
++     * This also checks the KeyImpl's constructors.
++     *
++     * We've already tested all the corner cases above, just making
++     * sure that the others are correctly doing their checks.
++     */
++    private static void testRSAKeyFactory() throws Exception {
++        testTranslateKey(SunRSA, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP),
++            RSAKeyGenParameterSpec.F4));
++        testTranslateKey(SunRSA, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN)));
++        testTranslateKey(SunRSA, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1)));
++        testTranslateKey(SunRSA, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN + 1),
++            RSAKeyGenParameterSpec.F4));
++        testTranslateKey(SunRSA, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 8),
++            RSAKeyGenParameterSpec.F4));
++        testTranslateKey(SunRSA, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 7),
++            RSAKeyGenParameterSpec.F4));
++
++        // Private keys don't have the same restriction
++        testTranslateKey(SunRSA, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP),
++            RSAKeyGenParameterSpec.F4));
++        testTranslateKey(SunRSA, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN)));
++        testTranslateKey(SunRSA, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1)));
++        testTranslateKey(SunRSA, false, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN + 1),
++            RSAKeyGenParameterSpec.F4));
++        testTranslateKey(SunRSA, false, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 8),
++            RSAKeyGenParameterSpec.F4));
++        testTranslateKey(SunRSA, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 7),
++            RSAKeyGenParameterSpec.F4));
++    }
++
++    private static void testP11KeyFactory() throws Exception {
++        testTranslateKey(P11, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP),
++            RSAKeyGenParameterSpec.F4));
++        testTranslateKey(P11, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN)));
++        testTranslateKey(P11, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1)));
++        testTranslateKey(P11, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN + 1),
++            RSAKeyGenParameterSpec.F4));
++        testTranslateKey(P11, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 8),
++            RSAKeyGenParameterSpec.F4));
++
++        // Private keys don't have the same restriction
++        testTranslateKey(P11, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP),
++            RSAKeyGenParameterSpec.F4));
++        testTranslateKey(P11, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN)));
++        testTranslateKey(P11, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1)));
++        testTranslateKey(P11, false, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN + 1),
++            RSAKeyGenParameterSpec.F4));
++        testTranslateKey(P11, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 8),
++            RSAKeyGenParameterSpec.F4));
++    }
++
++    /*
++     * Tests that that Signature's are working properly for both public
++     * and private keys.
++     */
++    private static void testInitSign(String provider,
++            boolean b, PrivateKey key) throws Exception {
++        System.out.println("testInitSign: " + b + " " + key + " " + provider);
++
++        Signature kf = Signature.getInstance("SHA1withRSA", provider);
++
++        try {
++            kf.initSign(key);
++            if (!b) {
++                throw new Exception("Should have failed");
++            }
++        } catch (InvalidKeyException e) {
++            if (b) {
++                throw new Exception("Should have passed", e);
++            }
++        } catch (ProviderException e) {
++            // The Solaris PKCS11 softtoken doesn't currently allow
++            // keys larger than 4K.  Throws a ProviderException.
++            if (!b) {
++                throw new Exception("Should have failed", e);
++            } else {
++                System.out.println("Large Keys excpetion, passing...");
++            }
++        }
++    }
++
++    private static void testInitVerify(String provider,
++            boolean b, PublicKey key) throws Exception {
++        System.out.println("testInitVerify: " + b + " " + key + " " +
++            provider);
++
++        Signature kf = Signature.getInstance("SHA1withRSA", provider);
++
++        try {
++            kf.initVerify(key);
++            if (!b) {
++                throw new Exception("Should have failed");
++            }
++        } catch (InvalidKeyException e) {
++            if (b) {
++                throw new Exception("Should have passed", e);
++            }
++        } catch (ProviderException e) {
++            // The Solaris PKCS11 softtoken doesn't currently allow
++            // keys larger than 4K.  Throws a ProviderException.
++            if (!b) {
++                throw new Exception("Should have failed", e);
++            } else {
++                System.out.println("Large Keys excpetion, passing...");
++            }
++        }
++    }
++
++    private static void testRSASignature() throws Exception {
++        testInitSign(SunRSA, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP),
++            RSAKeyGenParameterSpec.F4));
++        testInitSign(SunRSA, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN)));
++        testInitSign(SunRSA, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1)));
++        testInitSign(SunRSA, false, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN + 1),
++            RSAKeyGenParameterSpec.F4));
++        testInitSign(SunRSA, false, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 8),
++            RSAKeyGenParameterSpec.F4));
++        testInitSign(SunRSA, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 7),
++            RSAKeyGenParameterSpec.F4));
++
++        testInitVerify(SunRSA, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP),
++            RSAKeyGenParameterSpec.F4));
++        testInitVerify(SunRSA, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN)));
++        testInitVerify(SunRSA, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1)));
++        testInitVerify(SunRSA, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN + 1),
++            RSAKeyGenParameterSpec.F4));
++        testInitVerify(SunRSA, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 8),
++            RSAKeyGenParameterSpec.F4));
++        testInitVerify(SunRSA, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 7),
++            RSAKeyGenParameterSpec.F4));
++    }
++
++    private static void testP11Signature() throws Exception {
++        testInitSign(P11, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP),
++            RSAKeyGenParameterSpec.F4));
++        testInitSign(P11, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN)));
++        testInitSign(P11, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1)));
++        testInitSign(P11, false, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN + 1),
++            RSAKeyGenParameterSpec.F4));
++        testInitSign(P11, true, new MyRSAPrivateKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 8),
++            RSAKeyGenParameterSpec.F4));
++
++        testInitVerify(P11, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP),
++            RSAKeyGenParameterSpec.F4));
++        testInitVerify(P11, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN)));
++        testInitVerify(P11, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1)));
++        testInitVerify(P11, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN + 1),
++            RSAKeyGenParameterSpec.F4));
++        testInitVerify(P11, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 8),
++            RSAKeyGenParameterSpec.F4));
++    }
++
++    /*
++     * There are a couple test files, one with big keys.  Make sure that
++     * they are caught correctly.
++     */
++    private static void testStore(String file) throws Exception {
++
++        KeyStore ks = KeyStore.getInstance("JKS");
++        FileInputStream fis = new FileInputStream(new File(BASE, file));
++        ks.load(fis, "changeit".toCharArray());
++
++        java.security.cert.Certificate cert = ks.getCertificate("duke1");
++
++        Signature kf = Signature.getInstance("SHA1withRSA", SunRSA);
++        kf.initVerify(cert);
++    }
++
++    private static void testKeyStore() throws Exception {
++        System.out.println("testKeyStore with good key:");
++        testStore("keystore.good");
++
++        System.out.println("testKeyStore with bad key:");
++        try {
++            testStore("keystore.bad");
++            throw new Exception("Didn't throw expected IOException");
++        } catch (java.security.cert.CertificateParsingException e) {
++            System.out.println("Got proper CertificateParsingException");
++        }
++    }
++
++    /*
++     * We'll hard code the solaris p11 file for now.  If we
++     * ever add another one by default, this test will fail
++     * and we'll need to adjust the logic here.
++     */
++    private static void testP11() throws Exception {
++
++        // Replace the existing P11 provider with one that
++        // uses the local configuration file.
++        Provider p = Security.getProvider(P11);
++        if (p == null) {
++            System.out.println("Skipping " + P11 + " tests");
++            return;
++        }
++
++        Security.removeProvider(P11);
++        String config = BASE + "/sunpkcs11-solaris_enableSHA1withRSAsig.cfg";
++        System.out.println("Using config: " + config);
++        p = new sun.security.pkcs11.SunPKCS11(config);
++        Security.insertProviderAt(p, 1);
++
++        testP11KeyPairGenerator();
++        testP11KeyFactory();
++        testP11Signature();
++    }
++
++    /*
++     * Run a few tests with the MSCAPI provider.
++     */
++    private static void testMSCAPI() throws Exception {
++        if (Security.getProvider(MSCAPI) == null) {
++            System.out.println("Skipping " + MSCAPI + " tests");
++            return;
++        }
++
++        testRSAKeyPairGeneratorLen(MSCAPI, false,
++            RSAKeyFactory.MIN_MODLEN - 7);
++        testRSAKeyPairGeneratorLen(MSCAPI, true,
++            RSAKeyFactory.MIN_MODLEN);
++        testRSAKeyPairGeneratorLen(MSCAPI, true,
++            RSAKeyFactory.MAX_MODLEN);
++        testRSAKeyPairGeneratorLen(MSCAPI, false,
++            RSAKeyFactory.MAX_MODLEN + 1);
++
++        testRSAKeyPairGeneratorSpec(MSCAPI, false,
++            RSAKeyFactory.MIN_MODLEN - 1, -1);
++        testRSAKeyPairGeneratorSpec(MSCAPI, true,
++            RSAKeyFactory.MIN_MODLEN, -1);
++        testRSAKeyPairGeneratorSpec(MSCAPI, true,
++            RSAKeyFactory.MAX_MODLEN, -1);
++        testRSAKeyPairGeneratorSpec(MSCAPI, false,
++            RSAKeyFactory.MAX_MODLEN + 1, -1);
++
++        // This will fail because the SunMSCAPI provider itself
++        // won't allow Specs to contain actual exponents.
++        testRSAKeyPairGeneratorSpec(MSCAPI, false,
++            RSAKeyFactory.MAX_MODLEN, 64);
++
++        // Stock XP's MSCAPI won't allow exponents >= 32 bits,
++        // so we'll fudge a bit here.
++        testInitVerify(MSCAPI, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN_RESTRICT_EXP),
++            RSAKeyGenParameterSpec.F4));
++        testInitVerify(MSCAPI, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(24)));
++        testInitVerify(MSCAPI, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN),
++            getBigInteger(RSAKeyFactory.MAX_RESTRICTED_EXPLEN + 1)));
++        testInitVerify(MSCAPI, false, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MAX_MODLEN + 1),
++            RSAKeyGenParameterSpec.F4));
++        testInitVerify(MSCAPI, true, new MyRSAPublicKey(
++            getBigInteger(RSAKeyFactory.MIN_MODLEN - 1),
++            RSAKeyGenParameterSpec.F4));
++    }
++
++    public static void main(String args[]) throws Exception {
++
++        testRSAKeyPairGenerator();
++
++        testRSAKeyFactory();
++
++        testRSASignature();
++
++        testKeyStore();
++
++        testMSCAPI();
++
++        testP11();
++    }
++
++    /*
++     * Helper PublicKey class.  Create these with no restrictions.
++     */
++    private static class MyRSAPublicKey implements RSAPublicKey {
++
++        private final BigInteger n;
++        private final BigInteger e;
++
++        MyRSAPublicKey(BigInteger n, BigInteger e) {
++            this.n = n;
++            this.e = e;
++        }
++
++        public BigInteger getModulus() {
++            return n;
++        }
++
++        public BigInteger getPublicExponent() {
++            return e;
++        }
++
++        public String getAlgorithm() {
++             return "RSA";
++         }
++
++        public String getFormat() {
++            return "PKCS#8";
++        }
++
++        public byte [] getEncoded() {
++            return null;
++        }
++    }
++
++    /*
++     * Helper PrivateKey class.  Create these with no restrictions.
++     */
++    private static class MyRSAPrivateKey implements RSAPrivateKey {
++
++        private final BigInteger n;
++        private final BigInteger d;
++
++        MyRSAPrivateKey(BigInteger n, BigInteger d) {
++            this.n = n;
++            this.d = d;
++        }
++
++        public BigInteger getModulus() {
++            return n;
++        }
++
++        public BigInteger getPrivateExponent() {
++            return d;
++        }
++
++        public String getAlgorithm() {
++            return "RSA";
++        }
++
++        public String getFormat() {
++            return "PKCS#8";
++        }
++
++        public byte [] getEncoded() {
++            return null;
++        }
++    }
++}
+Binary files /tmp/dnlaqOr and new/test/closed/sun/security/rsa/keystore.bad differ
+Binary files /tmp/dxQaGis and new/test/closed/sun/security/rsa/keystore.good differ
+--- /dev/null	Fri Aug 22 18:59:31 2008
++++ openjdk/jdk/test/closed/sun/security/rsa/sunpkcs11-solaris_enableSHA1withRSAsig.cfg	Fri Aug 22 18:59:29 2008
+@@ -0,0 +1,36 @@
++#
++# Configuration file to allow the SunPKCS11 provider to utilize
++# the Solaris Cryptographic Framework, if it is available
++#
++
++name = Solaris
++
++description = SunPKCS11 accessing Solaris Cryptographic Framework
++
++library = /usr/lib/$ISA/libpkcs11.so
++
++handleStartupErrors = ignoreAll
++
++attributes = compatibility
++
++disabledMechanisms = {
++  CKM_MD2
++  CKM_MD5
++  CKM_SHA_1
++  CKM_SHA256
++  CKM_SHA384
++  CKM_SHA512
++  CKM_DSA_KEY_PAIR_GEN
++# KEY_AND_MAC_DERIVE disabled due to Solaris bug 6306708
++  CKM_SSL3_KEY_AND_MAC_DERIVE
++  CKM_TLS_KEY_AND_MAC_DERIVE
++# the following mechanisms are disabled due to performance issues (Solaris bug 6337157)
++  CKM_DSA_SHA1
++  CKM_MD5_RSA_PKCS
++# For testing purposes, we'll reenable this suite.
++#  CKM_SHA1_RSA_PKCS
++  CKM_SHA256_RSA_PKCS
++  CKM_SHA384_RSA_PKCS
++  CKM_SHA512_RSA_PKCS
++}
++
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6588160.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,42 @@
+--- /export/home/max/ws/jdk6-open/jdk/webrev/src/share/classes/sun/security/krb5/KrbKdcReq.java-        Sun Aug 31 20:04:55 2008
++++ openjdk/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java      Sun Aug 31 19:33:19 2008
+@@ -271,10 +271,11 @@
+                                +  port +  ", timeout="
+                                + timeout
+                                + ",Attempt =" + i
+                                + ", #bytes=" + obuf.length);
+                     }
++                    try {
+                     /*
+                      * Send the data to the kdc.
+                      */
+ 
+                     kdcClient.send(obuf);
+@@ -293,11 +294,14 @@
+                         if (i == DEFAULT_KDC_RETRY_LIMIT) {
+                             ibuf = null;
+                             throw se;
+                         }
+                     }
++                    } finally {
++                        kdcClient.close();
+                 }
++                }
+             }
+             return ibuf;
+         }
+     }
+ 
+--- /export/home/max/ws/jdk6-open/jdk/webrev/src/share/classes/sun/security/krb5/internal/UDPClient.java-       Sun Aug 31 20:04:55 2008
++++ openjdk/jdk/src/share/classes/sun/security/krb5/internal/UDPClient.java      Sun Aug 31 20:02:07 2008
+@@ -90,6 +90,9 @@
+         System.arraycopy(dgPacketIn.getData(), 0, data, 0,
+                          dgPacketIn.getLength());
+         return data;
+     }
+ 
++    public void close() {
++        dgSocket.close();
++    }
+ }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6592792.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,360 @@
+--- old/src/share/classes/com/sun/xml/internal/ws/spi/ProviderImpl.java	Tue Oct 21 15:06:46 2008
++++ openjdk/jaxws/src/share/classes/com/sun/xml/internal/ws/spi/ProviderImpl.java	Tue Oct 21 15:06:46 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -56,6 +56,8 @@
+ import javax.xml.ws.spi.ServiceDelegate;
+ import javax.xml.ws.wsaddressing.W3CEndpointReference;
+ import java.net.URL;
++import java.security.AccessController;
++import java.security.PrivilegedAction;
+ import java.util.List;
+ 
+ /**
+@@ -94,14 +96,20 @@
+         return endpoint;
+     }
+ 
+-    public EndpointReference readEndpointReference(Source eprInfoset) {
+-        Unmarshaller unmarshaller;
+-        try {
+-            unmarshaller = eprjc.createUnmarshaller();
+-            return (EndpointReference) unmarshaller.unmarshal(eprInfoset);
+-        } catch (JAXBException e) {
+-            throw new WebServiceException("Error creating Marshaller or marshalling.", e);
+-        }
++    public EndpointReference readEndpointReference(final Source eprInfoset) {
++        // EPR constructors are private, so we need privilege escalation.
++        // this unmarshalling can only access instances of a fixed, known set of classes,
++        // so doing that shouldn't introduce security vulnerability.
++        return AccessController.doPrivileged(new PrivilegedAction<EndpointReference>() {
++            public EndpointReference run() {
++                try {
++                    Unmarshaller unmarshaller = eprjc.createUnmarshaller();
++                    return (EndpointReference) unmarshaller.unmarshal(eprInfoset);
++                } catch (JAXBException e) {
++                    throw new WebServiceException("Error creating Marshaller or marshalling.", e);
++                }
++            }
++        });
+     }
+ 
+     public <T> T getPort(EndpointReference endpointReference, Class<T> clazz, WebServiceFeature... webServiceFeatures) {
+@@ -185,10 +193,17 @@
+     }
+ 
+     private static JAXBContext getEPRJaxbContext() {
+-        try {
+-            return JAXBContext.newInstance(MemberSubmissionEndpointReference.class, W3CEndpointReference.class);
+-        } catch (JAXBException e) {
+-            throw new WebServiceException("Error creating JAXBContext for W3CEndpointReference. ", e);
+-        }
++        // EPRs have package and private fields, so we need privilege escalation.
++        // this access only fixed, known set of classes, so doing that
++        // shouldn't introduce security vulnerability.
++        return AccessController.doPrivileged(new PrivilegedAction<JAXBContext>() {
++            public JAXBContext run() {
++                try {
++                    return JAXBContext.newInstance(MemberSubmissionEndpointReference.class, W3CEndpointReference.class);
++                } catch (JAXBException e) {
++                    throw new WebServiceException("Error creating JAXBContext for W3CEndpointReference. ", e);
++                }
++            }
++        });
+     }
+ }
+--- old/src/share/classes/javax/xml/bind/ContextFinder.java	Tue Oct 21 15:06:50 2008
++++ openjdk/jaxws/src/share/classes/javax/xml/bind/ContextFinder.java	Tue Oct 21 15:06:49 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -130,12 +130,7 @@
+         throws JAXBException
+     {
+         try {
+-            Class spiClass;
+-            if (classLoader == null) {
+-                spiClass = Class.forName(className);
+-            } else {
+-                spiClass = classLoader.loadClass(className);
+-            }
++            Class spiClass = safeLoadClass(className,classLoader);
+ 
+             /*
+              * javax.xml.bind.context.factory points to a class which has a
+@@ -207,11 +202,7 @@
+         ClassLoader cl = Thread.currentThread().getContextClassLoader();
+         Class spi;
+         try {
+-            logger.fine("Trying to load "+className);
+-            if (cl != null)
+-                spi = cl.loadClass(className);
+-            else
+-                spi = Class.forName(className);
++            spi = safeLoadClass(className,cl);
+         } catch (ClassNotFoundException e) {
+             throw new JAXBException(e);
+         }
+@@ -488,4 +479,31 @@
+      * For this reason, we have to hard-code the class name into the API.
+      */
+     private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory";
++
++    /**
++     * Loads the class, provided that the calling thread has an access to the class being loaded.
++     */
++    private static Class safeLoadClass(String className, ClassLoader classLoader) throws ClassNotFoundException {
++        logger.fine("Trying to load "+className);
++        try {
++            // make sure that the current thread has an access to the package of the given name.
++            SecurityManager s = System.getSecurityManager();
++            if (s != null) {
++                int i = className.lastIndexOf('.');
++                if (i != -1) {
++                    s.checkPackageAccess(className.substring(0,i));
++                }
++            }
++
++            if (classLoader == null)
++                return Class.forName(className);
++            else
++                return classLoader.loadClass(className);
++        } catch (SecurityException se) {
++            // anyone can access the platform default factory class without permission
++            if (PLATFORM_DEFAULT_FACTORY_CLASS.equals(className))
++                return Class.forName(className);
++            throw se;
++        }
++    }
+ }
+--- old/src/share/classes/javax/xml/ws/spi/FactoryFinder.java	Tue Oct 21 15:06:52 2008
++++ openjdk/jaxws/src/share/classes/javax/xml/ws/spi/FactoryFinder.java	Tue Oct 21 15:06:52 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -47,12 +47,7 @@
+                                       ClassLoader classLoader)
+     {
+         try {
+-            Class spiClass;
+-            if (classLoader == null) {
+-                spiClass = Class.forName(className);
+-            } else {
+-                spiClass = classLoader.loadClass(className);
+-            }
++            Class spiClass = safeLoadClass(className, classLoader);
+             return spiClass.newInstance();
+         } catch (ClassNotFoundException x) {
+             throw new WebServiceException(
+@@ -152,4 +147,33 @@
+ 
+         return newInstance(fallbackClassName, classLoader);
+     }
++
++
++    private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.ws.spi.ProviderImpl";
++
++    /**
++     * Loads the class, provided that the calling thread has an access to the class being loaded.
++     */
++    private static Class safeLoadClass(String className, ClassLoader classLoader) throws ClassNotFoundException {
++        try {
++            // make sure that the current thread has an access to the package of the given name.
++            SecurityManager s = System.getSecurityManager();
++            if (s != null) {
++                int i = className.lastIndexOf('.');
++                if (i != -1) {
++                    s.checkPackageAccess(className.substring(0,i));
++                }
++            }
++
++            if (classLoader == null)
++                return Class.forName(className);
++            else
++                return classLoader.loadClass(className);
++        } catch (SecurityException se) {
++            // anyone can access the platform default factory class without permission
++            if (PLATFORM_DEFAULT_FACTORY_CLASS.equals(className))
++                return Class.forName(className);
++            throw se;
++        }
++    }
+ }
+--- old/src/share/lib/security/java.security	Tue Oct 21 15:09:46 2008
++++ openjdk/jdk/src/share/lib/security/java.security	Tue Oct 21 15:09:46 2008
+@@ -127,7 +127,7 @@
+ # passed to checkPackageAccess unless the
+ # corresponding RuntimePermission ("accessClassInPackage."+package) has
+ # been granted.
+-package.access=sun.
++package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.
+ 
+ #
+ # List of comma-separated packages that start with or equal this string
+--- old/src/share/lib/security/java.security-solaris	Tue Oct 21 15:09:49 2008
++++ openjdk/jdk/src/share/lib/security/java.security-solaris	Tue Oct 21 15:09:49 2008
+@@ -128,7 +128,7 @@
+ # passed to checkPackageAccess unless the
+ # corresponding RuntimePermission ("accessClassInPackage."+package) has
+ # been granted.
+-package.access=sun.
++package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.
+ 
+ #
+ # List of comma-separated packages that start with or equal this string
+--- old/src/share/lib/security/java.security-windows	Tue Oct 21 15:09:52 2008
++++ openjdk/jdk/src/share/lib/security/java.security-windows	Tue Oct 21 15:09:52 2008
+@@ -128,7 +128,7 @@
+ # passed to checkPackageAccess unless the
+ # corresponding RuntimePermission ("accessClassInPackage."+package) has
+ # been granted.
+-package.access=sun.
++package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.
+ 
+ #
+ # List of comma-separated packages that start with or equal this string
+--- /dev/null	Tue Oct 21 15:09:20 2008
++++ openjdk/jdk/test/com/sun/org/apache/xml/internal/ws/server/Test.java	Tue Oct 21 15:09:56 2008
+@@ -0,0 +1,65 @@
++/*
++ *  @test
++ *  @bug 6592792
++ *  @summary Add com.sun.xml.internal to the "package.access" property in $JAVA_HOME/lib/security/java.security
++ *  @run shell Test6592792.sh
++ */
++
++import java.lang.*;
++import java.lang.reflect.*;
++import com.sun.xml.internal.ws.server.*;
++import com.sun.xml.internal.ws.server.SingletonResolver;
++import com.sun.xml.internal.ws.api.server.*;
++
++public class Test {
++
++  public static void main(String[] args) throws Exception{
++      // Enable the security manager
++      SecurityManager sm = new SecurityManager();
++      System.setSecurityManager(sm);
++      new Test();
++  }
++
++  Object invokeMethod(Object target,Method m,Object args[]) throws Exception {
++      SingletonResolver r = new SingletonResolver(target);
++      Invoker invoker = r.createInvoker();
++      return invoker.invoke(null, m, args);
++  }
++
++  public Test() throws Exception{
++      try {
++          Class c=Class.forName("java.lang.Class");
++
++          Class ctab[]=new Class[1];
++          ctab[0]=Class.forName("java.lang.String");
++          Method forName=c.getMethod("forName",ctab);
++
++          Class gtab[]=new Class[2];
++          gtab[0]=Class.forName("java.lang.String");
++          gtab[1]=Class[].class;
++          Method getMethod=c.getMethod("getMethod",gtab);
++
++          Method newInstance=c.getMethod("newInstance",(Class[])null);
++
++          Object otab[]=new Object[1];
++          otab[0]="sun.misc.Unsafe";
++
++          Object o=invokeMethod(null,forName,otab);
++          c = (Class)o;		// sun.misc.Unsafe class
++          // Test FAILED: Should n't have got the reference.   
++          throw new RuntimeException("Test Failed: Got reference to: "+o);
++
++
++          //o=invokeMethod(c,getMethod, new Object[]{"getUnsafe", (Class[])null});
++          //System.out.println("Got reference to: "+o);
++          //throw new RuntimeException("Got reference to: "+o);
++          //o=invokeMethod(c,(Method)o,null);
++          //System.out.println("Got reference to: "+o);
++          //throw new RuntimeException("Got reference to: "+o);
++   
++      } catch(java.security.AccessControlException e) {
++          System.out.println("Test passed");
++          //e.printStackTrace();
++      } 
++   }
++}
+--- /dev/null	Tue Oct 21 15:09:21 2008
++++ openjdk/jdk/test/com/sun/org/apache/xml/internal/ws/server/Test6592792.sh	Tue Oct 21 15:09:56 2008
+@@ -0,0 +1,61 @@
++#!/bin/sh
++
++if [ "${TESTSRC}" = "" ]
++then TESTSRC=.
++fi
++
++if [ "${TESTJAVA}" = "" ]
++then
++  PARENT=`dirname \`which java\``
++  TESTJAVA=`dirname ${PARENT}`
++  echo "TESTJAVA not set, selecting " ${TESTJAVA}
++  echo "If this is incorrect, try setting the variable manually."
++fi
++
++if [ "${TESTCLASSES}" = "" ]
++then
++  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
++  exit 1
++fi
++
++BIT_FLAG=""
++
++# set platform-dependent variables
++OS=`uname -s`
++case "$OS" in
++  SunOS | Linux )
++    NULL=/dev/null
++    PS=":"
++    FS="/"
++    ## for solaris, linux it's HOME
++    FILE_LOCATION=$HOME
++    if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ]
++    then
++        BIT_FLAG=`cat ${FILE_LOCATION}${FS}JDK64BIT`
++    fi
++    ;;
++  Windows_* )
++    NULL=NUL
++    PS=";"
++    FS="\\"
++    ;;
++  * )
++    echo "Unrecognized system!"
++    exit 1;
++    ;;
++esac
++
++JEMMYPATH=${CPAPPEND}
++CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH
++
++THIS_DIR=`pwd`
++
++${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -version
++
++${TESTJAVA}${FS}bin${FS}javac ${BIT_FLAG} -d . -cp ${TESTJAVA}${FS}jre${FS}lib${FS}rt.jar ${TESTSRC}${FS}Test.java
++
++${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -cp . Test
++
++STATUS=$?
++
++exit $STATUS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6721753.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,117 @@
+--- old/src/share/classes/java/io/File.java	Thu Oct  9 16:11:01 2008
++++ openjdk/jdk/src/share/classes/java/io/File.java	Thu Oct  9 16:10:51 2008
+@@ -32,9 +32,9 @@
+ import java.util.ArrayList;
+ import java.util.Map;
+ import java.util.Hashtable;
+-import java.util.Random;
+ import java.security.AccessController;
+ import java.security.AccessControlException;
++import java.security.SecureRandom;
+ import sun.security.action.GetPropertyAction;
+ 
+ 
+@@ -1676,30 +1676,30 @@
+ 
+     /* -- Temporary files -- */
+ 
+-    private static final Object tmpFileLock = new Object();
++    // lazy initialization of SecureRandom and temporary file directory
++    private static class LazyInitialization {
++        static final SecureRandom random = new SecureRandom();
+ 
+-    private static int counter = -1; /* Protected by tmpFileLock */
++        static final String temporaryDirectory = temporaryDirectory();
++        static String temporaryDirectory() {
++            return fs.normalize(
++                AccessController.doPrivileged(
++                    new GetPropertyAction("java.io.tmpdir")));
++        }
++    }
+ 
+     private static File generateFile(String prefix, String suffix, File dir)
+         throws IOException
+     {
+-        if (counter == -1) {
+-            counter = new Random().nextInt() & 0xffff;
++        long n = LazyInitialization.random.nextLong();
++        if (n == Long.MIN_VALUE) {
++            n = 0;      // corner case
++        } else {
++            n = Math.abs(n);
+         }
+-        counter++;
+-        return new File(dir, prefix + Integer.toString(counter) + suffix);
++        return new File(dir, prefix + Long.toString(n) + suffix);
+     }
+ 
+-    private static String tmpdir; /* Protected by tmpFileLock */
+-
+-    private static String getTempDir() {
+-        if (tmpdir == null)
+-            tmpdir = fs.normalize(
+-                AccessController.doPrivileged(
+-                    new GetPropertyAction("java.io.tmpdir")));
+-        return tmpdir;
+-    }
+-
+     private static boolean checkAndCreate(String filename, SecurityManager sm)
+         throws IOException
+     {
+@@ -1793,18 +1793,16 @@
+         if (prefix.length() < 3)
+             throw new IllegalArgumentException("Prefix string too short");
+         String s = (suffix == null) ? ".tmp" : suffix;
+-        synchronized (tmpFileLock) {
+-            if (directory == null) {
+-                String tmpDir = getTempDir();
+-                directory = new File(tmpDir, fs.prefixLength(tmpDir));
+-            }
+-            SecurityManager sm = System.getSecurityManager();
+-            File f;
+-            do {
+-                f = generateFile(prefix, s, directory);
+-            } while (!checkAndCreate(f.getPath(), sm));
+-            return f;
++        if (directory == null) {
++            String tmpDir = LazyInitialization.temporaryDirectory();
++            directory = new File(tmpDir, fs.prefixLength(tmpDir));
+         }
++        SecurityManager sm = System.getSecurityManager();
++        File f;
++        do {
++            f = generateFile(prefix, s, directory);
++        } while (!checkAndCreate(f.getPath(), sm));
++        return f;
+     }
+ 
+     /**
+--- /dev/null	Thu Oct  9 16:12:28 2008
++++ openjdk/jdk/test/closed/java/io/File/createTempFile/GuessNext.java	Thu Oct  9 16:12:25 2008
+@@ -0,0 +1,26 @@
++/* @test
++ * @bug 6721753
++ * @key closed-security
++ * @summary Test that temporary files don't use incrementing counter
++ */
++
++import java.io.File;
++import java.io.IOException;
++import java.util.regex.*;
++
++public class GuessNext {
++    public static void main (String[] args) throws IOException {
++        String name = File.createTempFile("blah", null).getName();
++
++        // assume name is blahNNNNNN
++        Matcher matcher = Pattern.compile("([0-9]+)").matcher(name);
++        if (matcher.find()) {
++            long next = Long.parseLong(matcher.group(1)) + 1;
++            String guess = "blah" + next + ".tmp";
++
++            name = File.createTempFile("blah", null).getName();
++            if (name.equals(guess))
++                throw new RuntimeException("Incrementing number");
++        }
++    }
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6726779.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,142 @@
+--- old/src/share/native/sun/awt/medialib/awt_ImagingLib.c	Thu Aug  7 10:06:12 2008
++++ openjdk/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c	Thu Aug  7 10:06:12 2008
+@@ -216,6 +216,16 @@
+ 
+ #endif /* ! DEBUG */
+ 
++static int
++getMlibEdgeHint(jint edgeHint) {
++    switch (edgeHint) {
++    case java_awt_image_ConvolveOp_EDGE_NO_OP:
++        return MLIB_EDGE_DST_COPY_SRC;
++    case java_awt_image_ConvolveOp_EDGE_ZERO_FILL:
++    default:
++        return MLIB_EDGE_DST_FILL_ZERO;
++    }
++}
+ 
+ /***************************************************************************
+  *                          External Functions                             *
+@@ -400,22 +410,10 @@
+         }
+     }
+ 
+-    if (edgeHint == java_awt_image_ConvolveOp_EDGE_NO_OP) {
+-        int kw2 = kwidth>>1;
+-        int kh2 = kheight>>1;
+-        int bsize = mlib_ImageGetChannels(src)*
+-            (mlib_ImageGetType(src) == MLIB_BYTE ? 1 : 2);
+-
+-        void *dstDataP = mlib_ImageGetData(dst);
+-        void *srcDataP = mlib_ImageGetData(src);
+-        /* REMIND: Copy a smaller area */
+-        memcpy(dstDataP, srcDataP, dst->width*dst->height*bsize);
+-    }
+-
+     cmask = (1<<src->channels)-1;
+     status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
+                                (w-1)/2, (h-1)/2, scale, cmask,
+-                               MLIB_EDGE_DST_NO_WRITE);
++                               getMlibEdgeHint(edgeHint));
+ 
+     if (status != MLIB_SUCCESS) {
+         printMedialibError(status);
+@@ -660,22 +658,10 @@
+         }
+     }
+ 
+-    if (edgeHint == java_awt_image_ConvolveOp_EDGE_NO_OP) {
+-        int kw2 = kwidth>>1;
+-        int kh2 = kheight>>1;
+-        int bsize = mlib_ImageGetChannels(src)*
+-            (mlib_ImageGetType(src) == MLIB_BYTE ? 1 : 2);
+-
+-        void *dstDataP = mlib_ImageGetData(dst);
+-        void *srcDataP = mlib_ImageGetData(src);
+-        /* REMIND: Copy a smaller area */
+-        memcpy(dstDataP, srcDataP, dst->width*dst->height*bsize);
+-    }
+-
+     cmask = (1<<src->channels)-1;
+     status = (*sMlibFns[MLIB_CONVMxN].fptr)(dst, src, kdata, w, h,
+                                (w-1)/2, (h-1)/2, scale, cmask,
+-                               MLIB_EDGE_DST_NO_WRITE);
++                               getMlibEdgeHint(edgeHint));
+ 
+     if (status != MLIB_SUCCESS) {
+         printMedialibError(status);
+--- /dev/null	Thu Aug  7 10:06:15 2008
++++ openjdk/jdk/test/java/awt/image/ConvolveOp/EdgeNoOpCrash.java	Thu Aug  7 10:06:14 2008
+@@ -0,0 +1,72 @@
++/*
++ * @test    @(#)EdgeNoOpCrash.java	1.1 08/08/07
++ * @bug     6726779
++ * @summary Test verifies that ConvolveOp with the EDGE_NO_OP edge condition
++ *          does not cause JVM crash if size of source raster elements is
++ *          greather than size of the destination raster element.
++ *
++ * @run     main EdgeNoOpCrash
++ */
++import java.awt.Point;
++import java.awt.image.ConvolveOp;
++import java.awt.image.DataBuffer;
++import java.awt.image.ImagingOpException;
++import java.awt.image.Kernel;
++import java.awt.image.Raster;
++import java.awt.image.WritableRaster;
++import java.util.Arrays;
++
++public class EdgeNoOpCrash {
++    private static final int w = 3000;
++    private static final int h = 200;
++    
++    public static void main(String[] args) {
++        crashTest();
++    }
++    
++    private static void crashTest() {
++        Raster src = createSrcRaster();
++        WritableRaster dst = createDstRaster();
++        ConvolveOp op = createConvolveOp(ConvolveOp.EDGE_NO_OP);
++        try {
++            op.filter(src, dst);
++        } catch (ImagingOpException e) {
++            /* 
++             * The test pair of source and destination rasters
++             * may cause failure of the medialib convolution routine,
++             * so this exception is expected.
++             * 
++             * The JVM crash is the only manifestation of this
++             * test failure.
++             */
++        }
++        System.out.println("Test PASSED.");
++    }
++    
++    private static Raster createSrcRaster() {
++        WritableRaster r = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT,
++                w, h, 4, new Point(0, 0));
++        
++        return r;
++    }
++    
++    private static WritableRaster createDstRaster() {
++        WritableRaster r = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
++                w, h, 4, new Point(0, 0));
++
++        return r;
++    }
++    
++    private static ConvolveOp createConvolveOp(int edgeHint) {
++        final int kw = 3;
++        final int kh = 3;
++        float[] kdata = new float[kw * kh];
++        float v = 1f / kdata.length;
++        Arrays.fill(kdata, v);
++        
++        Kernel k = new Kernel(kw, kh, kdata);
++        ConvolveOp op = new ConvolveOp(k, edgeHint, null);
++        
++        return op;
++    }
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6728542-epoll.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,90 @@
+
+# HG changeset patch
+# User alanb
+# Date 1219738992 -3600
+# Node ID 2a5377a6492e1738b4310c400d041a0f94071abf
+# Parent 872241636752db4f3c8401242a2dfe9f4ee38615
+6728542: (se) epoll based SelectorProvider should be portable to platforms other than x86 and x64
+Reviewed-by: sherman
+
+--- openjdk/jdk/make/java/nio/mapfile-linux	Mon Aug 25 08:11:08 2008 -0700
++++ openjdk/jdk/make/java/nio/mapfile-linux	Tue Aug 26 09:23:12 2008 +0100
+@@ -18,6 +18,8 @@ SUNWprivate_1.1 {
+ 		Java_sun_nio_ch_EPollArrayWrapper_fdLimit;
+ 		Java_sun_nio_ch_EPollArrayWrapper_init;
+ 		Java_sun_nio_ch_EPollArrayWrapper_interrupt;
++		Java_sun_nio_ch_EPollArrayWrapper_offsetofData;
++		Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent;
+                 Java_sun_nio_ch_FileChannelImpl_close0;
+                 Java_sun_nio_ch_FileChannelImpl_force0;
+                 Java_sun_nio_ch_FileChannelImpl_initIDs;
+--- openjdk/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java	Mon Aug 25 08:11:08 2008 -0700
++++ openjdk/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java	Tue Aug 26 09:23:12 2008 +0100
+@@ -69,11 +69,11 @@ class EPollArrayWrapper {
+     static final int EPOLL_CTL_MOD      = 3;
+ 
+     // Miscellaneous constants
+-    static final short SIZE_EPOLLEVENT  = 12;
+-    static final short EVENT_OFFSET     = 0;
+-    static final short DATA_OFFSET      = 4;
+-    static final short FD_OFFSET        = 4;
+-    static final int   NUM_EPOLLEVENTS  = Math.min(fdLimit(), 8192);
++    static final int SIZE_EPOLLEVENT  = sizeofEPollEvent();
++    static final int EVENT_OFFSET     = 0;
++    static final int DATA_OFFSET      = offsetofData();
++    static final int FD_OFFSET        = DATA_OFFSET;
++    static final int NUM_EPOLLEVENTS  = Math.min(fdLimit(), 8192);
+ 
+     // Base address of the native pollArray
+     private final long pollArrayAddress;
+@@ -280,6 +280,8 @@ class EPollArrayWrapper {
+     private native void epollCtl(int epfd, int opcode, int fd, int events);
+     private native int epollWait(long pollAddress, int numfds, long timeout,
+                                  int epfd) throws IOException;
++    private static native int sizeofEPollEvent();
++    private static native int offsetofData();
+     private static native int fdLimit();
+     private static native void interrupt(int fd);
+     private static native void init();
+--- openjdk/jdk/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c	Mon Aug 25 08:11:08 2008 -0700
++++ openjdk/jdk/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c	Tue Aug 26 09:23:12 2008 +0100
+@@ -48,10 +48,18 @@ typedef union epoll_data {
+     __uint64_t u64;
+ } epoll_data_t;
+ 
++
++/* x86-64 has same alignment as 32-bit */
++#ifdef __x86_64__
++#define EPOLL_PACKED __attribute__((packed))
++#else
++#define EPOLL_PACKED
++#endif
++
+ struct epoll_event {
+     __uint32_t events;  /* Epoll events */
+     epoll_data_t data;  /* User data variable */
+-} __attribute__ ((__packed__));
++} EPOLL_PACKED;
+ 
+ #ifdef  __cplusplus
+ }
+@@ -143,6 +151,18 @@ Java_sun_nio_ch_EPollArrayWrapper_fdLimi
+     return (jint)rlp.rlim_max;
+ }
+ 
++JNIEXPORT jint JNICALL
++Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent(JNIEnv* env, jclass this)
++{
++    return sizeof(struct epoll_event);
++}
++
++JNIEXPORT jint JNICALL
++Java_sun_nio_ch_EPollArrayWrapper_offsetofData(JNIEnv* env, jclass this)
++{
++    return offsetof(struct epoll_event, data);
++}
++
+ JNIEXPORT void JNICALL
+ Java_sun_nio_ch_EPollArrayWrapper_epollCtl(JNIEnv *env, jobject this, jint epfd,
+                                            jint opcode, jint fd, jint events)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6733959.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,223 @@
+--- old/src/share/bin/java.c	Tue Sep 30 13:28:32 2008
++++ openjdk/jdk/src/share/bin/java.c	Tue Sep 30 13:28:32 2008
+@@ -1056,8 +1056,14 @@
+      * to avoid locating, expanding and parsing the manifest extra
+      * times.
+      */
+-    if (info.main_class != NULL)
+-	(void)strcat(env_entry, info.main_class);
++    if (info.main_class != NULL) {
++        if (strlen(info.main_class) <= MAXNAMELEN) {
++            (void)strcat(env_entry, info.main_class);
++        } else {
++            ReportErrorMessage("Error: main-class: attribute exceeds system limits\n", JNI_TRUE);
++	    exit(1);
++        }
++    }
+     (void)putenv(env_entry);
+     ExecJRE(jre, new_argv);
+     JLI_FreeManifest();
+--- /dev/null	Tue Sep 30 13:28:33 2008
++++ openjdk/jdk/test/tools/launcher/ZipMeUp.java	Tue Sep 30 13:28:33 2008
+@@ -0,0 +1,90 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++/**
++ * A simple class to create our erring Jar with a very long Main-Class
++ * attribute in the manifest.
++ */
++import java.io.ByteArrayOutputStream;
++import java.io.FileOutputStream;
++import java.io.IOException;
++import java.io.PrintStream;
++import java.util.zip.CRC32;
++import java.util.zip.CheckedOutputStream;
++import java.util.zip.ZipEntry;
++import java.util.zip.ZipOutputStream;
++public class ZipMeUp {
++    
++    static final CRC32 crc = new CRC32();
++    
++    private static String SOME_KLASS = ".Some";
++    
++    static byte[] getManifestAsBytes(int nchars) throws IOException {
++        crc.reset();
++        ByteArrayOutputStream baos = new ByteArrayOutputStream();
++        CheckedOutputStream cos = new CheckedOutputStream(baos, crc);
++        PrintStream ps = new PrintStream(cos);
++        ps.println("Manifest-Version: 1.0");
++        ps.print("Main-Class: ");
++        for (int i = 0 ; i < nchars - SOME_KLASS.length(); i++) {
++            ps.print(i%10);
++        }
++        ps.println(SOME_KLASS);
++        cos.flush();
++        cos.close();
++        ps.close();
++        return baos.toByteArray();
++    }
++    /**
++     * The arguments are: filename_to_create length
++     * @param args
++     * @throws java.lang.Exception
++     */
++    public static void main(String...args) throws Exception  {
++        FileOutputStream fos = new FileOutputStream(args[0]);
++        ZipOutputStream zos = new ZipOutputStream(fos);
++        byte[] manifest = getManifestAsBytes(Integer.parseInt(args[1]));
++        ZipEntry ze = new ZipEntry("META-INF/MANIFEST.MF");
++        ze.setMethod(ZipEntry.STORED);
++        ze.setSize(manifest.length);
++        ze.setCompressedSize(manifest.length);
++        ze.setCrc(crc.getValue());
++        ze.setTime(System.currentTimeMillis());
++        zos.putNextEntry(ze);
++        zos.write(manifest);
++        zos.flush();
++        
++        // add a zero length class
++        ze = new ZipEntry(SOME_KLASS + ".class");
++        ze.setMethod(ZipEntry.STORED);
++        ze.setSize(0);
++        ze.setCompressedSize(0);
++        ze.setCrc(0);
++        ze.setTime(System.currentTimeMillis());
++        zos.putNextEntry(ze);
++        zos.flush();
++        zos.closeEntry();
++        zos.close();
++        System.exit(0);
++    }
++}
+--- MultipleJRE.sh	2008-11-21 14:18:54.000000000 -0500
++++ openjdk/jdk/test/tools/launcher/MultipleJRE.sh	2008-11-21 14:23:48.000000000 -0500
+@@ -48,10 +48,23 @@
+   exit 1
+ fi
+ 
++JAVAEXE="$TESTJAVA/bin/java"
+ JAVA="$TESTJAVA/bin/java -classpath $TESTCLASSES"
+ JAR="$TESTJAVA/bin/jar"
+ OS=`uname -s`;
+ 
++# Tests whether we are on windows (true) or not.
++IsWindows() {
++    case "$OS" in
++        Windows* | CYGWIN* )
++            printf "true"
++        ;;
++        * )
++            printf "false"
++        ;;
++    esac
++}
++
+ #
+ # Shell routine to test for the proper rejection of syntactically incorrect
+ # version specifications.
+@@ -261,6 +274,29 @@
+ 	fi
+ }
+ 
++# Tests very long Main-Class attribute in the jar.
++TestLongMainClass() {
++    JVER=$1
++    if [ "$JVER" = "mklink" ]; then
++        JVER=XX
++        JDKXX=jdk/j2re$JVER
++        rm -rf jdk
++        mkdir jdk
++        ln -s $TESTJAVA $JDKXX
++        JAVA_VERSION_PATH="`pwd`/jdk"
++        export JAVA_VERSION_PATH
++    fi
++    $JAVAEXE -cp $TESTCLASSES ZipMeUp UglyBetty.jar 4097 
++    message="`$JAVAEXE -version:$JVER -jar UglyBetty.jar 2>&1`"
++    echo $message | grep "Error: main-class: attribute exceeds system limits" > /dev/null 2>&1
++    if [ $? -ne 0 ]; then
++        printf "Long manifest test did not get expected error"
++        exit 1
++    fi
++    unset JAVA_VERSION_PATH
++    rm -rf jdk
++}
++
+ #
+ # Main test sequence starts here
+ #
+@@ -279,14 +315,12 @@
+ LaunchVM "" "${RELEASE}"
+ CreateJar "" "0"
+ LaunchVM "" "${RELEASE}"
+-case "$OS" in
+-	Windows* | CYGWIN* )
+-		MAXIMUM_PATH=255;
+-	;;
+-	*)
+-		MAXIMUM_PATH=1024;
+-	;;
+-esac
++if [ `IsWindows` = "true" ]; then
++    MAXIMUM_PATH=115;  # 115 = 255 - 140
++else
++    MAXIMUM_PATH=884;  # 884 = 1024 - 140
++fi
++
+ 
+ PATH_LENGTH=`printf "%s" "$UGLYCLASS" | wc -c`
+ if [ ${PATH_LENGTH} -lt ${MAXIMUM_PATH} ]; then
+@@ -356,15 +390,28 @@
+ TestSyntax "1.2+.3"				# Embedded modifier
+ TestSyntax "1.2.4+&1.2*&1++"			# Long and invalid
+ 
++# On windows we see if there is another jre installed, usually
++# there is, then we test using that, otherwise links are created
++# to get through to SelectVersion.
++if [ `IsWindows` = "false" ]; then
++   TestLongMainClass "mklink"
++else
++    $JAVAEXE -version:1.0+
++    if [ $? -eq 0 ]; then
++        TestLongMainClass "1.0+"
++    else
++        printf  "Warning: TestLongMainClass skipped as there is no"
++       printf  "viable MJRE installed.\n"
++    fi
++fi
++
+ #
+ # Because scribbling in the registry can be rather destructive, only a
+ # subset of the tests are run on Windows.
+ #
+-case "$OS" in
+-	Windows* | CYGWIN* )
+-		exit 0;
+-	;;
+-esac
++if [ `IsWindows` = "true" ]; then
++   exit 0;
++fi
+ 
+ #
+ # Additional version specifiers containing spaces.  (Sigh, unable to
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6734167.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,89 @@
+--- old/src/share/classes/java/util/Calendar.java	Fri Oct  3 00:27:50 2008
++++ openjdk/jdk/src/share/classes/java/util/Calendar.java	Fri Oct  3 00:27:50 2008
+@@ -41,9 +41,14 @@
+ import java.io.IOException;
+ import java.io.ObjectInputStream;
+ import java.io.ObjectOutputStream;
++import java.io.OptionalDataException;
+ import java.io.Serializable;
++import java.security.AccessControlContext;
+ import java.security.AccessController;
++import java.security.PermissionCollection;
++import java.security.PrivilegedActionException;
+ import java.security.PrivilegedExceptionAction;
++import java.security.ProtectionDomain;
+ import java.text.DateFormat;
+ import java.text.DateFormatSymbols;
+ import sun.util.BuddhistCalendar;
+@@ -2626,6 +2631,18 @@
+         }
+     }
+ 
++    private static class CalendarAccessControlContext {
++        private static final AccessControlContext INSTANCE;
++        static {
++            RuntimePermission perm = new RuntimePermission("accessClassInPackage.sun.util.calendar");
++            PermissionCollection perms = perm.newPermissionCollection();
++            perms.add(perm);
++            INSTANCE = new AccessControlContext(new ProtectionDomain[] {
++                                                    new ProtectionDomain(null, perms)
++                                                });
++        }
++    }
++
+     /**
+      * Reconstitutes this object from a stream (i.e., deserialize it).
+      */
+@@ -2655,17 +2672,30 @@
+         serialVersionOnStream = currentSerialVersion;
+ 
+         // If there's a ZoneInfo object, use it for zone.
++        ZoneInfo zi = null;
+         try {
+-            ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged(
+-                new PrivilegedExceptionAction() {
+-                    public Object run() throws Exception {
+-                        return input.readObject();
+-                    }
+-                });
+-            if (zi != null) {
+-                zone = zi;
++            zi = AccessController.doPrivileged(
++                    new PrivilegedExceptionAction<ZoneInfo>() {
++                        public ZoneInfo run() throws Exception {
++                            return (ZoneInfo) input.readObject();
++                        }
++                    },
++                    CalendarAccessControlContext.INSTANCE);
++        } catch (PrivilegedActionException pae) {
++            Exception e = pae.getException();
++            if (!(e instanceof OptionalDataException)) {
++                if (e instanceof RuntimeException) {
++                    throw (RuntimeException) e;
++                } else if (e instanceof IOException) {
++                    throw (IOException) e;
++                } else if (e instanceof ClassNotFoundException) {
++                    throw (ClassNotFoundException) e;
++                }
++                throw new RuntimeException(e);
+             }
+-        } catch (Exception e) {
++        }
++        if (zi != null) {
++            zone = zi;
+         }
+ 
+         // If the deserialized object has a SimpleTimeZone, try to
+@@ -2674,9 +2704,9 @@
+         // implementation as much as possible.
+         if (zone instanceof SimpleTimeZone) {
+             String id = zone.getID();
+-            TimeZone zi = TimeZone.getTimeZone(id);
+-            if (zi != null && zi.hasSameRules(zone) && zi.getID().equals(id)) {
+-                zone = zi;
++            TimeZone tz = TimeZone.getTimeZone(id);
++            if (tz != null && tz.hasSameRules(zone) && tz.getID().equals(id)) {
++                zone = tz;
+             }
+         }
+     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6755943.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,617 @@
+--- old/src/share/native/com/sun/java/util/jar/pack/bytes.cpp	Fri Oct 17 10:50:38 2008
++++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/bytes.cpp	Fri Oct 17 10:50:38 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -56,7 +56,7 @@
+     return;
+   }
+   byte* oldptr = ptr;
+-  ptr = (byte*)::realloc(ptr, len_+1);
++  ptr = (len_ >= PSIZE_MAX) ? null : (byte*)::realloc(ptr, len_+1);
+   if (ptr != null)  {
+     mtrace('r', oldptr, 0);
+     mtrace('m', ptr, len_+1);
+@@ -126,7 +126,7 @@
+ // Make sure there are 'o' bytes beyond the fill pointer,
+ // advance the fill pointer, and return the old fill pointer.
+ byte* fillbytes::grow(size_t s) {
+-  size_t nlen = b.len+s;
++  size_t nlen = add_size(b.len, s);
+   if (nlen <= allocated) {
+     b.len = nlen;
+     return limit()-s;
+--- old/src/share/native/com/sun/java/util/jar/pack/defines.h	Fri Oct 17 10:50:38 2008
++++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h	Fri Oct 17 10:50:38 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2001-2004 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -47,11 +47,13 @@
+ #define NOT_PRODUCT(xxx)
+ #define assert(p) (0)
+ #define printcr false &&
++#define VERSION_STRING "%s version %s\n"
+ #else
+ #define IF_PRODUCT(xxx)
+ #define NOT_PRODUCT(xxx) xxx
+ #define assert(p) ((p) || (assert_failed(#p), 1))
+ #define printcr u->verbose && u->printcr_if_verbose
++#define VERSION_STRING "%s version non-product %s\n"
+ extern "C" void breakpoint();
+ extern void assert_failed(const char*);
+ #define BREAK (breakpoint())
+@@ -79,9 +81,9 @@
+ 
+ #define lengthof(array) (sizeof(array)/sizeof(array[0]))
+ 
+-#define NEW(T, n)    (T*) must_malloc(sizeof(T)*(n))
+-#define U_NEW(T, n)  (T*) u->alloc(sizeof(T)*(n))
+-#define T_NEW(T, n)  (T*) u->temp_alloc(sizeof(T)*(n))
++#define NEW(T, n)    (T*) must_malloc(scale_size(n, sizeof(T)))
++#define U_NEW(T, n)  (T*) u->alloc(scale_size(n, sizeof(T)))
++#define T_NEW(T, n)  (T*) u->temp_alloc(scale_size(n, sizeof(T)))
+ 
+ 
+ // bytes and byte arrays
+--- old/src/share/native/com/sun/java/util/jar/pack/main.cpp	Fri Oct 17 10:50:39 2008
++++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/main.cpp	Fri Oct 17 10:50:39 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -300,7 +300,7 @@
+     case 'J':  argp += 1; break;  // skip ignored -Jxxx parameter
+ 
+     case 'V':
+-      fprintf(u.errstrm, "%s version %s\n", nbasename(argv[0]), sccsver);
++      fprintf(u.errstrm, VERSION_STRING, nbasename(argv[0]), sccsver);
+       exit(0);
+ 
+     case 'h':
+--- old/src/share/native/com/sun/java/util/jar/pack/unpack.cpp	Fri Oct 17 10:50:40 2008
++++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp	Fri Oct 17 10:50:40 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -618,18 +618,17 @@
+   if ((archive_options & AO_HAVE_FILE_HEADERS) != 0) {
+     uint hi = hdr.getInt();
+     uint lo = hdr.getInt();
+-    archive_size = band::makeLong(hi, lo);
++    julong x = band::makeLong(hi, lo);
++    archive_size = (size_t) x;
++    if (archive_size != x) {
++      // Silly size specified; force overflow.
++      archive_size = PSIZE_MAX+1;
++    }
+     hdrVals += 2;
+   } else {
+     hdrValsSkipped += 2;
+   }
+ 
+-  if (archive_size != (size_t)archive_size) {
+-    // Silly size specified.
+-    abort("archive too large");
+-    return;
+-  }
+-
+   // Now we can size the whole archive.
+   // Read everything else into a mega-buffer.
+   rp = hdr.rp;
+@@ -643,8 +642,8 @@
+       abort("EOF reading fixed input buffer");
+       return;
+     }
+-  } else if (archive_size > 0) {
+-    input.set(U_NEW(byte, (size_t) header_size_0 + archive_size + C_SLOP),
++  } else if (archive_size != 0) {
++    input.set(U_NEW(byte, add_size(header_size_0, archive_size, C_SLOP)),
+               (size_t) header_size_0 + archive_size);
+     assert(input.limit()[0] == 0);
+     // Move all the bytes we read initially into the real buffer.
+@@ -654,7 +653,6 @@
+   } else {
+     // It's more complicated and painful.
+     // A zero archive_size means that we must read until EOF.
+-    assert(archive_size == 0);
+     input.init(CHUNK*2);
+     CHECK;
+     input.b.len = input.allocated;
+@@ -664,7 +662,7 @@
+     rplimit += header_size;
+     while (ensure_input(input.limit() - rp)) {
+       size_t dataSoFar = input_remaining();
+-      size_t nextSize = dataSoFar + CHUNK;
++      size_t nextSize = add_size(dataSoFar, CHUNK);
+       input.ensureSize(nextSize);
+       CHECK;
+       input.b.len = input.allocated;
+@@ -949,10 +947,12 @@
+   // First band:  Read lengths of shared prefixes.
+   if (len > PREFIX_SKIP_2)
+     cp_Utf8_prefix.readData(len - PREFIX_SKIP_2);
++    NOT_PRODUCT(else cp_Utf8_prefix.readData(0));  // for asserts
+ 
+   // Second band:  Read lengths of unshared suffixes:
+   if (len > SUFFIX_SKIP_1)
+     cp_Utf8_suffix.readData(len - SUFFIX_SKIP_1);
++    NOT_PRODUCT(else cp_Utf8_suffix.readData(0));  // for asserts
+ 
+   bytes* allsuffixes = T_NEW(bytes, len);
+   CHECK;
+--- old/src/share/native/com/sun/java/util/jar/pack/unpack.h	Fri Oct 17 10:50:41 2008
++++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/unpack.h	Fri Oct 17 10:50:41 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2002-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -204,7 +204,7 @@
+ 
+   // archive header fields
+   int      magic, minver, majver;
+-  julong   archive_size;
++  size_t   archive_size;
+   int      archive_next_count, archive_options, archive_modtime;
+   int      band_headers_size;
+   int      file_count, attr_definition_count, ic_count, class_count;
+--- old/src/share/native/com/sun/java/util/jar/pack/utils.cpp	Fri Oct 17 10:50:41 2008
++++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/utils.cpp	Fri Oct 17 10:50:41 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2001-2004 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -46,14 +46,13 @@
+ 
+ #include "unpack.h"
+ 
+-void* must_malloc(int size) {
+-  int msize = size;
+-  assert(size >= 0);
++void* must_malloc(size_t size) {
++  size_t msize = size;
+   #ifdef USE_MTRACE
+-  if (msize < sizeof(int))
++  if (msize >= 0 && msize < sizeof(int))
+     msize = sizeof(int);  // see 0xbaadf00d below
+   #endif
+-  void* ptr = malloc(msize);
++  void* ptr = (msize > PSIZE_MAX) ? null : malloc(msize);
+   if (ptr != null) {
+     memset(ptr, 0, size);
+   } else {
+--- old/src/share/native/com/sun/java/util/jar/pack/utils.h	Fri Oct 17 10:50:42 2008
++++ openjdk/jdk/src/share/native/com/sun/java/util/jar/pack/utils.h	Fri Oct 17 10:50:42 2008
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
++ * Copyright 2001-2008 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -25,7 +25,7 @@
+ 
+ //Definitions of our util functions
+ 
+-void* must_malloc(int size);
++void* must_malloc(size_t size);
+ #ifndef USE_MTRACE
+ #define mtrace(c, ptr, size) (0)
+ #else
+@@ -32,6 +32,24 @@
+ void mtrace(char c, void* ptr, size_t size);
+ #endif
+ 
++// overflow management
++#define OVERFLOW ((size_t)-1)
++#define PSIZE_MAX (OVERFLOW/2)  /* normal size limit */
++
++inline size_t scale_size(size_t size, size_t scale) {
++  return (size > PSIZE_MAX / scale) ? OVERFLOW : size * scale;
++}
++
++inline size_t add_size(size_t size1, size_t size2) {
++  return ((size1 | size2 | (size1 + size2)) > PSIZE_MAX)
++    ? OVERFLOW
++    : size1 + size2;
++}
++
++inline size_t add_size(size_t size1, size_t size2, int size3) {
++  return add_size(add_size(size1, size2), size3);
++}
++
+ // These may be expensive, because they have to go via Java TSD,
+ // if the optional u argument is missing.
+ struct unpacker;
+--- /dev/null	Fri Oct 17 10:50:42 2008
++++ openjdk/jdk/test/tools/pack200/MemoryAllocatorTest.java	Fri Oct 17 10:50:42 2008
+@@ -0,0 +1,369 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++/*
++ * @test
++ * @bug 6755943
++ * @summary Checks any memory overruns in archive length.
++ * @run main/timeout=1200 MemoryAllocatorTest
++ */
++import java.io.BufferedReader;
++import java.io.DataOutputStream;
++import java.io.File;
++import java.io.FileOutputStream;
++import java.io.IOException;
++import java.io.InputStreamReader;
++import java.io.OutputStream;
++import java.io.RandomAccessFile;
++import java.nio.MappedByteBuffer;
++import java.nio.channels.FileChannel;
++import java.util.ArrayList;
++import java.util.List;
++import java.util.Map;
++
++public class MemoryAllocatorTest {
++
++    /*
++     * The smallest possible pack file with 1 empty resource
++     */
++    static int[] magic = {
++        0xCA, 0xFE, 0xD0, 0x0D
++    };
++    static int[] version_info = {
++        0x07, // minor
++        0x96  // major
++    };
++    static int[] option = {
++        0x10
++    };
++    static int[] size_hi = {
++        0x00
++    };
++    static int[] size_lo_ulong = {
++        0xFF, 0xFC, 0xFC, 0xFC, 0xFC // ULONG_MAX 0xFFFFFFFF
++    };
++    static int[] size_lo_correct = {
++        0x17
++    };
++    static int[] data = {
++        0x00, 0xEC, 0xDA, 0xDE, 0xF8, 0x45, 0x01, 0x02,
++        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++        0x00, 0x00, 0x00, 0x01, 0x31, 0x01, 0x00
++    };
++    // End of pack file data
++
++    static final String JAVA_HOME = System.getProperty("java.home");
++
++    static final boolean debug = Boolean.getBoolean("MemoryAllocatorTest.Debug");
++    static final boolean WINDOWS = System.getProperty("os.name").startsWith("Windows");
++    static final boolean LINUX = System.getProperty("os.name").startsWith("Linux");
++    static final boolean SIXTYFOUR_BIT = System.getProperty("sun.arch.data.model", "32").equals("64");
++    static final private int EXPECTED_EXIT_CODE = (WINDOWS) ? -1 : 255;
++
++    static int testExitValue = 0;
++    
++    static byte[] bytes(int[] a) {
++        byte[] b = new byte[a.length];
++        for (int i = 0; i < b.length; i++) {
++            b[i] = (byte) a[i];
++        }
++        return b;
++    }
++    
++    static void createPackFile(boolean good, File packFile) throws IOException {
++        FileOutputStream fos = new FileOutputStream(packFile);
++        fos.write(bytes(magic));
++        fos.write(bytes(version_info));
++        fos.write(bytes(option));
++        fos.write(bytes(size_hi));
++        if (good) {
++            fos.write(bytes(size_lo_correct));
++        } else {
++            fos.write(bytes(size_lo_ulong));
++        }
++        fos.write(bytes(data));
++    }
++
++    /*
++     * This method modifies the LSB of the size_lo for various wicked
++     * values between MAXINT-0x3F and MAXINT.
++     */
++    static int modifyPackFile(File packFile) throws IOException {
++        RandomAccessFile raf = new RandomAccessFile(packFile, "rws");
++        long len = packFile.length();
++        FileChannel fc = raf.getChannel();
++        MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_WRITE, 0, len);
++        int pos = magic.length + version_info.length + option.length +
++                size_hi.length;
++        byte value = bb.get(pos);
++        value--;
++        bb.position(pos);
++        bb.put(value);
++        bb.force();
++        fc.truncate(len);
++        fc.close();
++        return value & 0xFF;
++    }
++
++    static String getUnpack200Cmd() throws Exception {
++        File binDir = new File(JAVA_HOME, "bin");
++        File unpack200File = WINDOWS
++                ? new File(binDir, "unpack200.exe")
++                : new File(binDir, "unpack200");
++
++        String cmd = unpack200File.getAbsolutePath();
++        if (!unpack200File.canExecute()) {
++            throw new Exception("please check" +
++                    cmd + " exists and is executable");
++        }
++        return cmd;
++    }
++
++    static TestResult runUnpacker(File packFile) throws Exception {
++        if (!packFile.exists()) {
++            throw new Exception("please check" + packFile + " exists");
++        }
++        ArrayList<String> alist = new ArrayList<String>();
++        ProcessBuilder pb = new ProcessBuilder(getUnpack200Cmd(),
++                packFile.getName(), "testout.jar");
++        Map<String, String> env = pb.environment();
++        pb.directory(new File("."));
++        int retval = 0;
++        try {
++            pb.redirectErrorStream(true);
++            Process p = pb.start();
++            BufferedReader rd = new BufferedReader(
++                    new InputStreamReader(p.getInputStream()), 8192);
++            String in = rd.readLine();
++            while (in != null) {
++                alist.add(in);
++                System.out.println(in);
++                in = rd.readLine();
++            }
++            retval = p.waitFor();
++            p.destroy();
++        } catch (Exception ex) {
++            ex.printStackTrace();
++            throw new RuntimeException(ex.getMessage());
++        }
++        return new TestResult("", retval, alist);
++    }
++
++    /*
++     * The debug version builds of unpack200 call abort(3) which might set
++     * an unexpected return value, therefore this test is to determine
++     * if we are using a product or non-product build and check the
++     * return value appropriately.
++     */
++    static boolean isNonProductVersion() throws Exception {
++        ArrayList<String> alist = new ArrayList<String>();
++        ProcessBuilder pb = new ProcessBuilder(getUnpack200Cmd(), "--version");
++        Map<String, String> env = pb.environment();
++        pb.directory(new File("."));
++        int retval = 0;
++        try {
++            pb.redirectErrorStream(true);
++            Process p = pb.start();
++            BufferedReader rd = new BufferedReader(
++                    new InputStreamReader(p.getInputStream()), 8192);
++            String in = rd.readLine();
++            while (in != null) {
++                alist.add(in);
++                System.out.println(in);
++                in = rd.readLine();
++            }
++            retval = p.waitFor();
++            p.destroy();
++        } catch (Exception ex) {
++            ex.printStackTrace();
++            throw new RuntimeException(ex.getMessage());
++        }
++        for (String x : alist) {
++            if (x.contains("non-product")) {
++                return true;
++            }
++        }
++        return false;
++    }
++
++    /**
++     * @param args the command line arguments
++     * @throws java.lang.Exception 
++     */
++    public static void main(String[] args) throws Exception {
++
++        File packFile = new File("tiny.pack");
++        boolean isNPVersion = isNonProductVersion();
++
++        // Create a good pack file and test if everything is ok
++        createPackFile(true, packFile);
++        TestResult tr = runUnpacker(packFile);
++        tr.setDescription("a good pack file");
++        tr.checkPositive();
++        tr.isOK();
++        System.out.println(tr);
++
++        /*
++         * jprt systems on windows and linux seem to have abundant memory
++         * therefore can take a very long time to run, and even if it does
++         * the error message is not accurate for us to discern if the test
++         * passes successfully.
++         */
++        if (SIXTYFOUR_BIT && (LINUX || WINDOWS)) {
++            System.out.println("Warning: Windows/Linux 64bit tests passes vacuously");
++            return;
++        }
++        
++        /*
++         * debug builds call abort, the exit code under these conditions
++         * are not really relevant.
++         */
++        if (isNPVersion) {
++            System.out.println("Warning: non-product build: exit values not checked");
++        }
++    
++        // create a bad pack file
++        createPackFile(false, packFile);
++        tr = runUnpacker(packFile);
++        tr.setDescription("a wicked pack file");
++        tr.contains("Native allocation failed");
++        if(!isNPVersion) {
++            tr.checkValue(EXPECTED_EXIT_CODE);
++        }
++        System.out.println(tr);
++        int value = modifyPackFile(packFile);
++        tr.setDescription("value=" + value);
++
++        // continue creating bad pack files by modifying the specimen pack file.
++        while (value >= 0xc0) {
++            tr = runUnpacker(packFile);
++            tr.contains("Native allocation failed");
++            if (!isNPVersion) {
++                tr.checkValue(EXPECTED_EXIT_CODE);
++            }
++            tr.setDescription("wicked value=0x" +
++                    Integer.toHexString(value & 0xFF));
++            System.out.println(tr);
++            value = modifyPackFile(packFile);
++        }
++        if (testExitValue != 0) {
++            throw new Exception("Pack200 archive length tests(" +
++                    testExitValue + ") failed ");
++        } else {
++            System.out.println("All tests pass");
++        }
++    }
++
++    /*
++     * A class to encapsulate the test results and stuff, with some ease
++     * of use methods to check the test results.
++     */
++    static class TestResult {
++
++        StringBuilder status;
++        int exitValue;
++        List<String> testOutput;
++        String description;
++
++        public TestResult(String str, int rv, List<String> oList) {
++            status = new StringBuilder(str);
++            exitValue = rv;
++            testOutput = oList;
++        }
++
++        void setDescription(String description) {
++            this.description = description;
++        }
++
++        void checkValue(int value) {
++            if (exitValue != value) {
++                status =
++                        status.append("  Error: test expected exit value " +
++                        value + "got " + exitValue);
++                testExitValue++;
++            }
++        }
++
++        void checkNegative() {
++            if (exitValue == 0) {
++                status = status.append(
++                        "  Error: test did not expect 0 exit value");
++
++                testExitValue++;
++            }
++        }
++
++        void checkPositive() {
++            if (exitValue != 0) {
++                status = status.append(
++                        "  Error: test did not return 0 exit value");
++                testExitValue++;
++            }
++        }
++
++        boolean isOK() {
++            return exitValue == 0;
++        }
++
++        boolean isZeroOutput() {
++            if (!testOutput.isEmpty()) {
++                status = status.append("  Error: No message from cmd please");
++                testExitValue++;
++                return false;
++            }
++            return true;
++        }
++
++        boolean isNotZeroOutput() {
++            if (testOutput.isEmpty()) {
++                status = status.append("  Error: Missing message");
++                testExitValue++;
++                return false;
++            }
++            return true;
++        }
++
++        public String toString() {
++            if (debug) {
++                for (String x : testOutput) {
++                    status = status.append(x + "\n");
++                }
++            }
++            if (description != null) {
++                status.insert(0, description);
++            }
++            return status.append("\nexitValue = " + exitValue).toString();
++        }
++
++        boolean contains(String str) {
++            for (String x : testOutput) {
++                if (x.contains(str)) {
++                    return true;
++                }
++            }
++            status = status.append("   Error: string <" + str + "> not found ");
++            testExitValue++;
++            return false;
++        }
++    }
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-6766136.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,189 @@
+--- old/src/share/native/sun/awt/splashscreen/splashscreen_gfx_impl.h	Wed Nov 12 12:25:11 2008
++++ openjdk/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gfx_impl.h	Wed Nov 12 12:25:11 2008
+@@ -31,7 +31,7 @@
+ /* here come some very simple macros */
+ 
+ /* advance a pointer p by sizeof(type)*n bytes */
+-#define INCPN(type,p,n) ((p) = (type*)(p)+n)
++#define INCPN(type,p,n) ((p) = (type*)(p)+(n))
+ 
+ /* advance a pointer by sizeof(type) */
+ #define INCP(type,p) INCPN(type,(p),1)
+--- old/src/share/native/sun/awt/splashscreen/splashscreen_gif.c	Wed Nov 12 12:25:12 2008
++++ openjdk/jdk/src/share/native/sun/awt/splashscreen/splashscreen_gif.c	Wed Nov 12 12:25:12 2008
+@@ -53,6 +53,10 @@
+ // convert libungif samples to our ones
+ #define MAKE_QUAD_GIF(c,a) MAKE_QUAD((c).Red, (c).Green, (c).Blue, (a))
+ 
++#define SAFE_TO_ALLOC(c, sz)                                               \
++    (((c) > 0) && ((sz) > 0) &&                                            \
++     ((0xffffffffu / ((unsigned int)(c))) > (unsigned int)(sz)))
++
+ /* stdio FILE* and memory input functions for libungif */
+ int
+ SplashStreamGifInputFunc(GifFileType * gif, GifByteType * buf, int n)
+@@ -62,6 +66,15 @@
+     return rc;
+ }
+ 
++/* These macro help to ensure that we only take part of frame that fits into 
++   logical screen. */
++
++/* Ensure that p belongs to [pmin, pmax) interval. Returns fixed point (if fix is needed) */
++#define FIX_POINT(p, pmin, pmax) ( ((p) < (pmin)) ? (pmin) : (((p) > (pmax)) ? (pmax) : (p)))
++/* Ensures that line starting at point p does not exceed boundary pmax.
++   Returns fixed length (if fix is needed) */
++#define FIX_LENGTH(p, len, pmax) ( ((p) + (len)) > (pmax) ? ((pmax) - (p)) : (len))
++
+ int
+ SplashDecodeGif(Splash * splash, GifFileType * gif)
+ {
+@@ -70,6 +83,7 @@
+     byte_t *pBitmapBits, *pOldBitmapBits;
+     int i, j;
+     int imageIndex;
++    int cx, cy, cw, ch; /* clamped coordinates */
+     const int interlacedOffset[] = { 0, 4, 2, 1, 0 };   /* The way Interlaced image should. */
+     const int interlacedJumps[] = { 8, 8, 4, 2, 1 };    /* be read - offsets and jumps... */
+ 
+@@ -79,14 +93,31 @@
+ 
+     SplashCleanup(splash);
+ 
++    if (!SAFE_TO_ALLOC(gif->SWidth, splash->imageFormat.depthBytes)) {
++        return 0;
++    }
+     stride = gif->SWidth * splash->imageFormat.depthBytes;
+     if (splash->byteAlignment > 1)
+         stride =
+             (stride + splash->byteAlignment - 1) & ~(splash->byteAlignment - 1);
+ 
++    if (!SAFE_TO_ALLOC(gif->SHeight, stride)) {
++        return 0;
++    }
++
++    if (!SAFE_TO_ALLOC(gif->ImageCount, sizeof(SplashImage*))) {
++        return 0;
++    }
+     bufferSize = stride * gif->SHeight;
+     pBitmapBits = (byte_t *) malloc(bufferSize);
++    if (!pBitmapBits) {
++        return 0;
++    }
+     pOldBitmapBits = (byte_t *) malloc(bufferSize);
++    if (!pOldBitmapBits) {
++        free(pBitmapBits);
++        return 0;
++    }
+     memset(pBitmapBits, 0, bufferSize);
+ 
+     splash->width = gif->SWidth;
+@@ -94,6 +125,11 @@
+     splash->frameCount = gif->ImageCount;
+     splash->frames = (SplashImage *)
+         malloc(sizeof(SplashImage) * gif->ImageCount);
++    if (!splash->frames) {
++      free(pBitmapBits);
++      free(pOldBitmapBits);
++      return 0;
++    } 
+     memset(splash->frames, 0, sizeof(SplashImage) * gif->ImageCount);
+     splash->loopCount = 1;
+ 
+@@ -109,6 +145,11 @@
+         int colorCount = 0;
+         rgbquad_t colorMapBuf[SPLASH_COLOR_MAP_SIZE];
+ 
++	cx = FIX_POINT(desc->Left, 0, gif->SWidth);
++	cy = FIX_POINT(desc->Top, 0, gif->SHeight);
++	cw = FIX_LENGTH(desc->Left, desc->Width, gif->SWidth);
++	ch = FIX_LENGTH(desc->Top, desc->Height, gif->SHeight);
++
+         if (colorMap) {
+             if (colorMap->ColorCount <= SPLASH_COLOR_MAP_SIZE) {
+                 colorCount = colorMap->ColorCount;
+@@ -195,13 +236,24 @@
+             for (; pass < npass; ++pass) {
+                 int jump = interlacedJumps[pass];
+                 int ofs = interlacedOffset[pass];
+-                int numLines = (desc->Height + jump - 1 - ofs) / jump;
++                /* Number of source lines for current pass */
++                int numPassLines = (desc->Height + jump - ofs - 1) / jump;
++                /* Number of lines that fits to dest buffer */
++                int numLines = (ch + jump - ofs - 1) / jump;
+ 
++
+                 initRect(&srcRect, 0, 0, desc->Width, numLines, 1,
+                     desc->Width, pSrc, &srcFormat);
+-                initRect(&dstRect, desc->Left, desc->Top + ofs, desc->Width,
+-                    numLines, jump, stride, pBitmapBits, &splash->imageFormat);
+-                pSrc += convertRect(&srcRect, &dstRect, CVT_ALPHATEST);
++
++                if (numLines > 0) {
++                    initRect(&dstRect, cx, cy + ofs, cw,
++                             numLines, jump, stride, pBitmapBits,
++                             &splash->imageFormat);
++
++                    pSrc += convertRect(&srcRect, &dstRect, CVT_ALPHATEST);
++                }
++                // skip extra source data
++                pSrc += (numPassLines - numLines) * srcRect.stride;
+             }
+         }
+ 
+@@ -209,6 +261,12 @@
+ 
+         splash->frames[imageIndex].bitmapBits =
+             (rgbquad_t *) malloc(bufferSize);
++	if (!splash->frames[imageIndex].bitmapBits) {
++	  free(pBitmapBits);
++	  free(pOldBitmapBits);
++          /* Assuming that callee will take care of splash frames we have already allocated */
++	  return 0;
++	}
+         memcpy(splash->frames[imageIndex].bitmapBits, pBitmapBits, bufferSize);
+ 
+         SplashInitFrameShape(splash, imageIndex);
+@@ -224,27 +282,29 @@
+             {
+                 ImageRect dstRect;
+                 rgbquad_t fillColor = 0;                        // 0 is transparent
+-                if (transparentColor < 0) {
++
++                if (transparentColor > 0) {
+                     fillColor= MAKE_QUAD_GIF(
+                         colorMap->Colors[gif->SBackGroundColor], 0xff);
+                 }
+-                initRect(&dstRect, desc->Left, desc->Top,
+-                    desc->Width, desc->Height, 1, stride,
+-                    pBitmapBits, &splash->imageFormat);
++                initRect(&dstRect,
++                         cx, cy, cw, ch,
++                         1, stride,
++                         pBitmapBits, &splash->imageFormat);
+                 fillRect(fillColor, &dstRect);
+             }
+             break;
+         case GIF_DISPOSE_RESTORE:
+             {
+-
+-                int lineSize = desc->Width * splash->imageFormat.depthBytes;
+-
+-                for (j = 0; j < desc->Height; j++) {
+-                    int lineIndex = stride * (j + desc->Top) +
+-                        desc->Left * splash->imageFormat.depthBytes;
+-
+-                    memcpy(pBitmapBits + lineIndex, pOldBitmapBits + lineIndex,
+-                        lineSize);
++                int lineSize = cw * splash->imageFormat.depthBytes;
++                if (lineSize > 0) {
++                    int lineOffset = cx * splash->imageFormat.depthBytes;
++                    int lineIndex = cy * stride + lineOffset;
++                    for (j=0; j<ch; j++) {
++                        memcpy(pBitmapBits + lineIndex, pOldBitmapBits + lineIndex,
++                               lineSize);
++                        lineIndex += stride;
++                    }
+                 }
+             }
+             break;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-ecj-pr261.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,40 @@
+diff -r fa4572c7c75f openjdk-ecj/jdk/make/java/nio/Makefile
+--- openjdk-ecj/jdk/make/java/nio/Makefile	Thu Nov 27 08:42:23 2008 +0000
++++ openjdk-ecj/jdk/make/java/nio/Makefile	Thu Nov 27 10:12:08 2008 +0000
+@@ -85,6 +85,9 @@ ifeq ($(PLATFORM), linux)
+ ifeq ($(PLATFORM), linux)
+ FILES_java += \
+         sun/nio/ch/AbstractPollSelectorImpl.java \
++	sun/nio/ch/DevPollArrayWrapper.java \
++	sun/nio/ch/DevPollSelectorImpl.java \
++	sun/nio/ch/DevPollSelectorProvider.java \
+ 	sun/nio/ch/EPollArrayWrapper.java \
+ 	sun/nio/ch/EPollSelectorProvider.java \
+ 	sun/nio/ch/EPollSelectorImpl.java \
+@@ -99,6 +102,7 @@ FILES_c += \
+ 	NativeThread.c
+ 
+ FILES_export += \
++	sun/nio/ch/DevPollArrayWrapper.java \
+         sun/nio/ch/EPollArrayWrapper.java \
+ 	sun/nio/ch/InheritedChannel.java \
+ 	sun/nio/ch/NativeThread.java
+diff -r 3ee709488c6c openjdk-ecj/jdk/make/java/nio/FILES_java.gmk
+--- openjdk-ecj/jdk/make/java/nio/FILES_java.gmk	Thu Nov 27 10:16:56 2008 +0000
++++ openjdk-ecj/jdk/make/java/nio/FILES_java.gmk	Thu Nov 27 11:08:57 2008 +0000
+@@ -31,6 +31,7 @@ FILES_src = \
+ 	java/nio/StringCharBuffer.java \
+ 	\
+ 	java/nio/channels/ByteChannel.java \
++	java/nio/channels/CancelledKeyException.java \
+ 	java/nio/channels/Channel.java \
+ 	java/nio/channels/Channels.java \
+ 	java/nio/channels/DatagramChannel.java \
+@@ -38,6 +39,7 @@ FILES_src = \
+ 	java/nio/channels/FileLock.java \
+ 	java/nio/channels/GatheringByteChannel.java \
+ 	java/nio/channels/InterruptibleChannel.java \
++	java/nio/channels/Pipe.java \
+ 	java/nio/channels/ReadableByteChannel.java \
+ 	java/nio/channels/ScatteringByteChannel.java \
+ 	java/nio/channels/SelectableChannel.java \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-samejvm-safe.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,12 @@
+--- openjdk.orig/jdk/test/TEST.ROOT	2008-11-06 09:44:52.000000000 +0100
++++ openjdk/jdk/test/TEST.ROOT	2008-11-23 16:15:53.000000000 +0100
+@@ -4,3 +4,9 @@
+ 
+ # The list of keywords supported in the entire test suite
+ keys=2d dnd i18n
++
++# List if directory (prefixes) that contain test that are safe to run in
++# -samejvm mode. Only used if the test root (dir containing this file) is
++# given to jtreg and the -samejvm argument is used, ignored otherwise
++# (meaning all tests are assumed to be same jvm safe).
++samejvmsafe=com/sun/crypto com/sun/management com/sun/media com/sun/security java/beans/beancontext java/beans/PropertyChangeSupport java/beans/Statement java/beans/VetoableChangeSupport java/lang/Boolean java/lang/Byte java/lang/Double java/lang/Float java/lang/Integer java/lang/Long java/lang/Short java/lang/Math java/lang/StrictMath java/lang/String java/lang/Throwable java/lang/instrument java/math java/net/URI java/net/URLDecoder java/net/URLEncoder java/nio/Buffer java/nio/ByteOrder java/nio/MappedByteBuffer java/nio/channels/Channels java/nio/channels/DatagramChannel java/nio/channels/spi java/security/cert java/security/Provider java/text java/util/jar java/util/zip java/util/Array java/util/BitSet java/util/Collection java/util/List javax/crypto/Cipher javax/imageio javax/management/openmbean javax/naming javax/rmi javax/sound sun/net/www/protocol sun/misc sun/nio sun/rmi sun/security/pkcs11 sun/security/rsa sun/security/util sun/security/x509 sun/util
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-stroker-finish.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,20 @@
+--- openjdk6/jdk/src/share/classes/sun/java2d/pisces/Stroker.java
++++ openjdk/jdk/src/share/classes/sun/java2d/pisces/Stroker.java
+@@ -695,7 +695,7 @@
+             long ldx = (long)(px0 - x0);
+             long ldy = (long)(py0 - y0);
+             long llen = lineLength(ldx, ldy);
+-            long s = (long)lineWidth2*65536/llen;
++            long s = (llen == 0) ? 0 : (long)lineWidth2*65536/llen;
+ 
+             int capx = x0 - (int)(ldx*s >> 16);
+             int capy = y0 - (int)(ldy*s >> 16);
+@@ -717,7 +717,7 @@
+             long ldx = (long)(sx1 - sx0);
+             long ldy = (long)(sy1 - sy0);
+             long llen = lineLength(ldx, ldy);
+-            long s = (long)lineWidth2*65536/llen;
++            long s = (llen == 0) ? 0 : (long)lineWidth2*65536/llen;
+ 
+             int capx = sx0 - (int)(ldx*s >> 16);
+             int capy = sy0 - (int)(ldy*s >> 16);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-000.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,430 @@
+6675596: SurfaceManagerFactory should allow plugging in different implementations
+Reviewed-by: tdv, campbell
+Contributed-by: Roman Kennke <roman.kennke@aicas.com>
+
+diff -r ed68352f7e42 -r 4af4867ed787 src/share/classes/sun/awt/image/SunVolatileImage.java
+--- openjdk/jdk/src/share/classes/sun/awt/image/SunVolatileImage.java	Wed May 14 09:16:18 2008 -0700
++++ openjdk/jdk/src/share/classes/sun/awt/image/SunVolatileImage.java	Wed May 14 16:05:07 2008 -0700
+@@ -165,7 +165,8 @@
+         {
+             return new BufImgVolatileSurfaceManager(this, context);
+         }
+-        return SurfaceManagerFactory.createVolatileManager(this, context);
++        SurfaceManagerFactory smf = SurfaceManagerFactory.getInstance();
++        return smf.createVolatileManager(this, context);
+     }
+ 
+     private Color getForeground() {
+diff -r ed68352f7e42 -r 4af4867ed787 src/share/classes/sun/java2d/SurfaceManagerFactory.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/share/classes/sun/java2d/SurfaceManagerFactory.java	Wed May 14 16:05:07 2008 -0700
+@@ -0,0 +1,91 @@
++/*
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++package sun.java2d;
++
++import sun.awt.image.SunVolatileImage;
++import sun.awt.image.VolatileSurfaceManager;
++
++/**
++ * This factory creates platform specific VolatileSurfaceManager
++ * implementations.
++ *
++ * There are two platform specific SurfaceManagerFactories in OpenJDK,
++ * UnixSurfaceManagerFactory and WindowsSurfaceManagerFactory.
++ * The actually used SurfaceManagerFactory is set by the respective platform
++ * GraphicsEnvironment implementations in the static initializer.
++ */
++public abstract class SurfaceManagerFactory {
++
++    /**
++     * The single shared instance.
++     */
++    private static SurfaceManagerFactory instance;
++
++    /**
++     * Returns the surface manager factory instance. This returns a factory
++     * that has been set by {@link #setInstance(SurfaceManagerFactory)}.
++     *
++     * @return the surface manager factory
++     */
++    public synchronized static SurfaceManagerFactory getInstance() {
++
++        if (instance == null) {
++            throw new IllegalStateException("No SurfaceManagerFactory set.");
++        }
++        return instance;
++    }
++
++    /**
++     * Sets the surface manager factory. This may only be called once, and it
++     * may not be set back to {@code null} when the factory is already
++     * instantiated.
++     *
++     * @param factory the factory to set
++     */
++    public synchronized static void setInstance(SurfaceManagerFactory factory) {
++
++        if (factory == null) {
++            // We don't want to allow setting this to null at any time.
++            throw new IllegalArgumentException("factory must be non-null");
++        }
++
++        if (instance != null) {
++            // We don't want to re-set the instance at any time.
++            throw new IllegalStateException("The surface manager factory is already initialized");
++        }
++
++        instance = factory;
++    }
++
++    /**
++     * Creates a new instance of a VolatileSurfaceManager given any
++     * arbitrary SunVolatileImage.  An optional context Object can be supplied
++     * as a way for the caller to pass pipeline-specific context data to
++     * the VolatileSurfaceManager (such as a backbuffer handle, for example).
++     */
++     public abstract VolatileSurfaceManager
++         createVolatileManager(SunVolatileImage image, Object context);
++}
+diff -r ed68352f7e42 -r 4af4867ed787 src/solaris/classes/sun/awt/X11GraphicsEnvironment.java
+--- openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java	Wed May 14 09:16:18 2008 -0700
++++ openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java	Wed May 14 16:05:07 2008 -0700
+@@ -48,6 +48,8 @@
+ import sun.font.FontManager;
+ import sun.font.NativeFont;
+ import sun.java2d.SunGraphicsEnvironment;
++import sun.java2d.SurfaceManagerFactory;
++import sun.java2d.UnixSurfaceManagerFactory;
+ 
+ /**
+  * This is an implementation of a GraphicsEnvironment object for the
+@@ -177,6 +179,10 @@
+                 return null;
+             }
+          });
++
++        // Install the correct surface manager factory.
++        SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory());
++
+     }
+ 
+     private static boolean glxAvailable;
+diff -r ed68352f7e42 -r 4af4867ed787 src/solaris/classes/sun/java2d/SurfaceManagerFactory.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/SurfaceManagerFactory.java	Wed May 14 09:16:18 2008 -0700
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,65 +0,0 @@
+-/*
+- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.  Sun designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Sun in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+- * CA 95054 USA or visit www.sun.com if you need additional information or
+- * have any questions.
+- */
+-
+-package sun.java2d;
+-
+-import java.awt.GraphicsConfiguration;
+-import java.awt.image.BufferedImage;
+-import sun.awt.X11GraphicsConfig;
+-import sun.awt.image.SunVolatileImage;
+-import sun.awt.image.SurfaceManager;
+-import sun.awt.image.VolatileSurfaceManager;
+-import sun.java2d.opengl.GLXGraphicsConfig;
+-import sun.java2d.opengl.GLXVolatileSurfaceManager;
+-import sun.java2d.x11.X11VolatileSurfaceManager;
+-
+-/**
+- * This is a factory class with static methods for creating a
+- * platform-specific instance of a particular SurfaceManager.  Each platform
+- * (Windows, Unix, etc.) has its own specialized SurfaceManagerFactory.
+- */
+-public class SurfaceManagerFactory {
+-    /**
+-     * Creates a new instance of a VolatileSurfaceManager given any
+-     * arbitrary SunVolatileImage.  An optional context Object can be supplied
+-     * as a way for the caller to pass pipeline-specific context data to
+-     * the VolatileSurfaceManager (such as a backbuffer handle, for example).
+-     *
+-     * For Unix platforms, this method returns either an X11- or a GLX-
+-     * specific VolatileSurfaceManager based on the GraphicsConfiguration
+-     * under which the SunVolatileImage was created.
+-     */
+-    public static VolatileSurfaceManager
+-        createVolatileManager(SunVolatileImage vImg,
+-                              Object context)
+-    {
+-        GraphicsConfiguration gc = vImg.getGraphicsConfig();
+-        if (gc instanceof GLXGraphicsConfig) {
+-            return new GLXVolatileSurfaceManager(vImg, context);
+-        } else {
+-            return new X11VolatileSurfaceManager(vImg, context);
+-        }
+-    }
+-}
+diff -r ed68352f7e42 -r 4af4867ed787 src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java	Wed May 14 16:05:07 2008 -0700
+@@ -0,0 +1,64 @@
++/*
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++
++package sun.java2d;
++
++import java.awt.GraphicsConfiguration;
++
++import sun.awt.image.SunVolatileImage;
++import sun.awt.image.VolatileSurfaceManager;
++import sun.java2d.opengl.GLXGraphicsConfig;
++import sun.java2d.opengl.GLXVolatileSurfaceManager;
++import sun.java2d.x11.X11VolatileSurfaceManager;
++
++/**
++ * The SurfaceManagerFactory that creates VolatileSurfaceManager
++ * implementations for the Unix volatile images.
++ */
++public class UnixSurfaceManagerFactory extends SurfaceManagerFactory {
++
++    /**
++     * Creates a new instance of a VolatileSurfaceManager given any
++     * arbitrary SunVolatileImage.  An optional context Object can be supplied
++     * as a way for the caller to pass pipeline-specific context data to
++     * the VolatileSurfaceManager (such as a backbuffer handle, for example).
++     *
++     * For Unix platforms, this method returns either an X11- or a GLX-
++     * specific VolatileSurfaceManager based on the GraphicsConfiguration
++     * under which the SunVolatileImage was created.
++     */
++    public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
++                                                        Object context)
++    {
++        GraphicsConfiguration gc = vImg.getGraphicsConfig();
++        if (gc instanceof GLXGraphicsConfig) {
++            return new GLXVolatileSurfaceManager(vImg, context);
++        } else {
++            return new X11VolatileSurfaceManager(vImg, context);
++        }
++    }
++
++}
+diff -r ed68352f7e42 -r 4af4867ed787 src/windows/classes/sun/awt/Win32GraphicsEnvironment.java
+--- openjdk/jdk/src/windows/classes/sun/awt/Win32GraphicsEnvironment.java	Wed May 14 09:16:18 2008 -0700
++++ openjdk/jdk/src/windows/classes/sun/awt/Win32GraphicsEnvironment.java	Wed May 14 16:05:07 2008 -0700
+@@ -42,6 +42,8 @@
+ import sun.awt.windows.WToolkit;
+ import sun.font.FontManager;
+ import sun.java2d.SunGraphicsEnvironment;
++import sun.java2d.SurfaceManagerFactory;
++import sun.java2d.WindowsSurfaceManagerFactory;
+ import sun.java2d.windows.WindowsFlags;
+ 
+ /**
+@@ -64,6 +66,9 @@
+         WindowsFlags.initFlags();
+         initDisplayWrapper();
+         eudcFontFileName = getEUDCFontFile();
++
++        // Install correct surface manager factory.
++        SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());
+     }
+ 
+     /**
+diff -r ed68352f7e42 -r 4af4867ed787 src/windows/classes/sun/java2d/SurfaceManagerFactory.java
+--- openjdk/jdk/src/windows/classes/sun/java2d/SurfaceManagerFactory.java	Wed May 14 09:16:18 2008 -0700
++++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
+@@ -1,64 +0,0 @@
+-/*
+- * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation.  Sun designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Sun in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+- * CA 95054 USA or visit www.sun.com if you need additional information or
+- * have any questions.
+- */
+-
+-package sun.java2d;
+-
+-import java.awt.GraphicsConfiguration;
+-import java.awt.image.BufferedImage;
+-import sun.awt.image.SunVolatileImage;
+-import sun.awt.image.SurfaceManager;
+-import sun.awt.image.VolatileSurfaceManager;
+-import sun.java2d.opengl.WGLGraphicsConfig;
+-import sun.java2d.opengl.WGLVolatileSurfaceManager;
+-import sun.java2d.windows.WindowsFlags;
+-import sun.java2d.windows.WinVolatileSurfaceManager;
+-
+-/**
+- * This is a factory class with static methods for creating a
+- * platform-specific instance of a particular SurfaceManager.  Each platform
+- * (Windows, Unix, etc.) has its own specialized SurfaceManagerFactory.
+- */
+-public class SurfaceManagerFactory {
+-    /**
+-     * Creates a new instance of a VolatileSurfaceManager given any
+-     * arbitrary SunVolatileImage.  An optional context Object can be supplied
+-     * as a way for the caller to pass pipeline-specific context data to
+-     * the VolatileSurfaceManager (such as a backbuffer handle, for example).
+-     *
+-     * For Windows platforms, this method returns a Windows-specific
+-     * VolatileSurfaceManager.
+-     */
+-    public static VolatileSurfaceManager
+-        createVolatileManager(SunVolatileImage vImg,
+-                              Object context)
+-    {
+-        GraphicsConfiguration gc = vImg.getGraphicsConfig();
+-        if (gc instanceof WGLGraphicsConfig) {
+-            return new WGLVolatileSurfaceManager(vImg, context);
+-        } else {
+-            return new WinVolatileSurfaceManager(vImg, context);
+-        }
+-    }
+-}
+diff -r ed68352f7e42 -r 4af4867ed787 src/windows/classes/sun/java2d/WindowsSurfaceManagerFactory.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/windows/classes/sun/java2d/WindowsSurfaceManagerFactory.java	Wed May 14 16:05:07 2008 -0700
+@@ -0,0 +1,64 @@
++/*
++ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++package sun.java2d;
++
++import java.awt.GraphicsConfiguration;
++import java.awt.image.BufferedImage;
++import sun.awt.image.SunVolatileImage;
++import sun.awt.image.SurfaceManager;
++import sun.awt.image.VolatileSurfaceManager;
++import sun.java2d.opengl.WGLGraphicsConfig;
++import sun.java2d.opengl.WGLVolatileSurfaceManager;
++import sun.java2d.windows.WindowsFlags;
++import sun.java2d.windows.WinVolatileSurfaceManager;
++
++/**
++ * The SurfaceManagerFactory that creates VolatileSurfaceManager
++ * implementations for the Windows volatile images.
++ */
++public class WindowsSurfaceManagerFactory extends SurfaceManagerFactory {
++
++    /**
++     * Creates a new instance of a VolatileSurfaceManager given any
++     * arbitrary SunVolatileImage.  An optional context Object can be supplied
++     * as a way for the caller to pass pipeline-specific context data to
++     * the VolatileSurfaceManager (such as a backbuffer handle, for example).
++     *
++     * For Windows platforms, this method returns a Windows-specific
++     * VolatileSurfaceManager.
++     */
++    public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
++                                                        Object context)
++    {
++        GraphicsConfiguration gc = vImg.getGraphicsConfig();
++        if (gc instanceof WGLGraphicsConfig) {
++            return new WGLVolatileSurfaceManager(vImg, context);
++        } else {
++            return new WinVolatileSurfaceManager(vImg, context);
++        }
++    }
++
++}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-001.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,5320 @@
+changeset:   6d294fa2bd42
+user:        ceisserer
+date:        Sat Jul 26 00:13:41 2008 +0200
+summary:     summary: initial implementation of the X render pipeline
+
+diff -r dc592ff5af5e jdk/make/sun/font/FILES_c.gmk
+--- openjdk/jdk/make/sun/font/FILES_c.gmk	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/font/FILES_c.gmk	Sat Nov 29 19:56:09 2008 +0100
+@@ -117,6 +117,7 @@
+ FILES_cpp_platform = D3DTextRenderer.cpp
+ else
+ FILES_c_platform = X11FontScaler.c \
++                   XRTextRenderer.c \
+                    X11TextRenderer.c
+ FILES_cpp_platform =
+ endif
+diff -r dc592ff5af5e jdk/make/sun/font/Makefile
+--- openjdk/jdk/make/sun/font/Makefile	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/font/Makefile	Sat Nov 29 19:56:09 2008 +0100
+@@ -92,6 +92,7 @@
+     sun/font/NativeStrike.java \
+     sun/font/NativeStrikeDisposer.java \
+     sun/font/X11TextRenderer.java \
++    sun/font/XRTextRenderer.java \
+     sun/awt/X11GraphicsEnvironment.java 
+ 
+ endif # PLATFORM
+diff -r dc592ff5af5e jdk/make/sun/font/mapfile-vers
+--- openjdk/jdk/make/sun/font/mapfile-vers	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/font/mapfile-vers	Sat Nov 29 19:56:09 2008 +0100
+@@ -63,6 +63,7 @@
+                 Java_sun_font_NativeFont_getGlyphImage;
+                 Java_sun_font_NativeFont_getGlyphImageNoDefault;
+                 Java_sun_font_NativeFont_getFontMetrics;
++                Java_sun_font_XRTextRenderer_doDrawGlyphList;
+ 	local:
+ 		*;
+ };
+diff -r dc592ff5af5e jdk/make/sun/font/mapfile-vers.openjdk
+--- openjdk/jdk/make/sun/font/mapfile-vers.openjdk	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/font/mapfile-vers.openjdk	Sat Nov 29 19:56:09 2008 +0100
+@@ -82,6 +82,7 @@
+                 Java_sun_font_FreetypeFontScaler_getUnitsPerEMNative;
+                 Java_sun_font_FreetypeFontScaler_initNativeScaler;
+                 Java_sun_font_FreetypeFontScaler_getGlyphPointNative;
++                Java_sun_font_XRTextRenderer_doDrawGlyphList;
+ 	local:
+ 		*;
+ };
+diff -r dc592ff5af5e jdk/make/sun/xawt/FILES_c_unix.gmk
+--- openjdk/jdk/make/sun/xawt/FILES_c_unix.gmk	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/xawt/FILES_c_unix.gmk	Sat Nov 29 19:56:09 2008 +0100
+@@ -77,5 +77,12 @@
+ 	debug_util.c \
+ 	awt_Plugin.c \
+ 	gtk2_interface.c \
+-        swing_GTKEngine.c \
+-        swing_GTKStyle.c
++	swing_GTKEngine.c \
++	swing_GTKStyle.c \
++	ArrayList.c \
++	MaskBuffer.c \
++	XRSurfaceData.c \
++	XRGlyphCache.c \
++	XRTextRenderer_md.c \
++        XRRenderer.c \
++        XRPMBlitLoops.c
+diff -r dc592ff5af5e jdk/make/sun/xawt/Makefile
+--- openjdk/jdk/make/sun/xawt/Makefile	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/xawt/Makefile	Sat Nov 29 19:56:09 2008 +0100
+@@ -86,7 +86,7 @@
+ vpath %.c   $(PLATFORM_SRC)/native/sun/java2d/opengl
+ vpath %.c   $(PLATFORM_SRC)/native/sun/java2d/x11
+ 
+-OTHER_LDLIBS = $(LIBM) -lawt -lXext -lX11 -ldl \
++OTHER_LDLIBS = $(LIBM) -lawt -lXext -lX11 -lXrender -ldl \
+                    $(LDFLAGS_COMMON) $(AWT_RUNPATH) $(OTHER_LDFLAGS) -lXtst -lXi
+ 
+ ifeq  ($(PLATFORM), solaris)
+diff -r dc592ff5af5e jdk/make/sun/xawt/mapfile-vers
+--- openjdk/jdk/make/sun/xawt/mapfile-vers	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/make/sun/xawt/mapfile-vers	Sat Nov 29 19:56:09 2008 +0100
+@@ -346,6 +346,33 @@
+         Java_sun_java2d_x11_X11SurfaceData_XSetForeground;
+         Java_sun_java2d_x11_X11SurfaceData_XSetGraphicsExposures;
+ 
++        Java_sun_java2d_xr_XRSurfaceData_flushNativeSurface;
++        Java_sun_java2d_xr_XRSurfaceData_XRIsDrawableValid;
++        Java_sun_java2d_xr_XRSurfaceData_setInvalid;
++        Java_sun_java2d_xr_XRSurfaceData_XRInitXRender;
++        Java_sun_java2d_xr_XRSurfaceData_initOps;
++        Java_sun_java2d_xr_XRSurfaceData_XRSetForeground;
++        Java_sun_java2d_xr_XRSurfaceData_XRSetComposite;
++        Java_sun_java2d_xr_XRSurfaceData_initIDs;
++        Java_sun_java2d_xr_XRSurfaceData_XRInitSurface;
++	Java_sun_java2d_xr_XRSurfaceData_XRResetClip;
++	Java_sun_java2d_xr_XRSurfaceData_XRSetTransformNative;
++        Java_sun_java2d_xr_XRSurfaceData_XRSetFilter;
++	Java_sun_java2d_xr_XRSurfaceData_XRSetTexturePaint;
++	Java_sun_java2d_xr_XRSurfaceData_XRSetGradientPaint;
++        Java_sun_java2d_xr_XRSurfaceData_XRSetLinearGradientPaint;
++        Java_sun_java2d_xr_XRSurfaceData_XRSetRadialGradientPaint;
++        Java_sun_java2d_xr_XRSurfaceData_XRResetPaint;
++        Java_sun_java2d_xr_XRSurfaceData_XRSetRepeat;
++	Java_sun_java2d_xr_XRPMBlitLoops_nativeRenderBlit;
++	Java_sun_java2d_xr_XRRenderer_XRFillRect;
++	Java_sun_java2d_xr_XRRenderer_XRFillSpans;
++        Java_sun_java2d_xr_XRRenderer_XRDoPath;
++	Java_sun_java2d_xr_XRRenderer_XRDrawLine;
++        Java_sun_java2d_xr_XRMaskFill_maskFill;
++	Java_sun_java2d_xr_XRMaskBlit_maskBlit;
++	XRT_DrawGlyphList;
++
+         Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1arrow;
+         Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box;
+         Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box_1gap;
+diff -r dc592ff5af5e jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java
+--- openjdk/jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/share/classes/sun/java2d/pipe/BufferedPaints.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -307,7 +307,7 @@
+      * linear RGB space.  Copied directly from the
+      * MultipleGradientPaintContext class.
+      */
+-    private static int convertSRGBtoLinearRGB(int color) {
++    public static int convertSRGBtoLinearRGB(int color) {
+         float input, output;
+ 
+         input = color / 255.0f;
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java
+--- openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -37,6 +37,7 @@
+ import java.util.HashMap;
+ 
+ import sun.java2d.opengl.GLXGraphicsConfig;
++import sun.java2d.xr.*;
+ import sun.java2d.loops.SurfaceType;
+ 
+ /**
+@@ -150,6 +151,8 @@
+             }
+ 
+             boolean glxSupported = X11GraphicsEnvironment.isGLXAvailable();
++            boolean xrender = X11GraphicsEnvironment.isXRenderAvailable();
++            
+             boolean dbeSupported = isDBESupported();
+             if (dbeSupported && doubleBufferVisuals == null) {
+                 doubleBufferVisuals = new HashSet();
+@@ -164,10 +167,19 @@
+                 if (ret[i] == null) {
+                     boolean doubleBuffer =
+                         (dbeSupported &&
+-                         doubleBufferVisuals.contains(new Integer(visNum)));
+-                    ret[i] = X11GraphicsConfig.getConfig(this, visNum, depth,
+-                            getConfigColormap(i, screen),
+-                            doubleBuffer);
++                         doubleBufferVisuals.contains(Integer.valueOf(visNum)));
++                    
++                    if(!xrender)
++                    {
++                        ret[i] = XRGraphicsConfig.getConfig(this, visNum, depth,
++                                getConfigColormap(i, screen),
++                                doubleBuffer);
++                    }else
++                    {
++                        ret[i] = X11GraphicsConfig.getConfig(this, visNum, depth,
++                                getConfigColormap(i, screen),
++                                doubleBuffer);
++                    }
+                 }
+             }
+             configs = ret;
+@@ -241,9 +253,19 @@
+                     doubleBuffer =
+                         doubleBufferVisuals.contains(new Integer(visNum));
+                 }
+-                defaultConfig = X11GraphicsConfig.getConfig(this, visNum,
+-                                                            depth, getConfigColormap(0, screen),
+-                                                            doubleBuffer);
++                
++                if(X11GraphicsEnvironment.isXRenderAvailable())
++                {
++                	System.out.println("XRender pipeline enabled");
++                    defaultConfig = XRGraphicsConfig.getConfig(this, visNum,
++                            depth, getConfigColormap(0, screen),
++                            doubleBuffer);
++                }else
++                {
++                    defaultConfig = X11GraphicsConfig.getConfig(this, visNum,
++                            depth, getConfigColormap(0, screen),
++                            doubleBuffer);
++                }
+             }
+         }
+     }
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java
+--- openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -47,9 +47,9 @@
+ import sun.font.Font2D;
+ import sun.font.FontManager;
+ import sun.font.NativeFont;
+-import sun.java2d.SunGraphicsEnvironment;
+-import sun.java2d.SurfaceManagerFactory;
+-import sun.java2d.UnixSurfaceManagerFactory;
++import sun.java2d.*;
++import sun.java2d.x11.*;
++import sun.java2d.xr.*;
+ 
+ /**
+  * This is an implementation of a GraphicsEnvironment object for the
+@@ -174,19 +174,43 @@
+                                 "pipeline (GLX 1.3 not available)");
+                         }
+                     }
++                    
++                    /*CE*/
++                    // Now check for XRender system property
++                    String xProp = System.getProperty("sun.java2d.xrender");
++                        if (xProp != null) {
++                        if (xProp.equals("true") || xProp.equals("t")) {
++                            xRenderAvailable = true;
++                        } else if (xProp.equals("True") || xProp.equals("T")) {
++                            xRenderAvailable = true;
++                            xRenderVerbose = true;
++                        }
++                    }
++                        
++                        if(xRenderAvailable)
++                        {
++                            XRSurfaceData.initXRSurfaceData();
++                        }else
++                        {
++                        	X11SurfaceData.initX11SurfaceData();
++                        }
+                 }
+-
++               
++   
+                 return null;
+             }
+          });
+-
++        
+         // Install the correct surface manager factory.
+         SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory());
+-
+     }
+-
++    
+     private static boolean glxAvailable;
+     private static boolean glxVerbose;
++    
++    private static boolean xRenderAvailable; /*CE*/
++    private static boolean xRenderVerbose;
++    private static boolean isX11SurfaceDataInitialized = false;
+ 
+     private static native boolean initGLX();
+ 
+@@ -196,6 +220,15 @@
+ 
+     public static boolean isGLXVerbose() {
+         return glxVerbose;
++    }
++    
++    /*CE*/
++    public static boolean isXRenderAvailable() {
++        return xRenderAvailable;
++    }
++
++    public static boolean isXRenderVerbose() {
++        return xRenderVerbose;
+     }
+ 
+     /**
+@@ -1070,4 +1103,14 @@
+     @Override
+     public void paletteChanged() {
+     }
++
++	public static boolean isX11SurfaceDataInitialized()
++	{
++		return isX11SurfaceDataInitialized;
++	}
++
++	public static void setX11SurfaceDataInitialized()
++	{
++		X11GraphicsEnvironment.isX11SurfaceDataInitialized = true;
++	}
+ }
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/font/XRTextRenderer.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/font/XRTextRenderer.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,53 @@
++/*
++ * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++package sun.font;
++
++import sun.awt.SunToolkit;
++import sun.java2d.SunGraphics2D;
++import sun.java2d.pipe.GlyphListPipe;
++import sun.java2d.xr.*;
++
++/**
++ * A delegate pipe of SG2D for drawing any text to a XRender surface
++ */
++public class XRTextRenderer extends GlyphListPipe {
++    
++    native void doDrawGlyphList(long dstData, int numGlyphs, boolean subPixPos, boolean rgbOrder, int lcdContrast, boolean usePositions, float xOrigin, float yOrigin, long[] imgArray, float[] posArray);
++    
++    protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) 
++    {
++        try 
++        {
++            SunToolkit.awtLock();
++            XRSurfaceData x11sd = (XRSurfaceData)sg2d.surfaceData;
++    		x11sd.validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
++            
++            doDrawGlyphList(x11sd.getNativeOps(), gl.getNumGlyphs(), gl.isSubPixPos(), gl.isRGBOrder(), sg2d.lcdTextContrast, gl.usePositions(), gl.getX(), gl.getY(), gl.getImages(), gl.getPositions());
++        } finally {
++            SunToolkit.awtUnlock();
++        }
++    }
++}
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -33,6 +33,7 @@
+ import sun.java2d.opengl.GLXGraphicsConfig;
+ import sun.java2d.opengl.GLXVolatileSurfaceManager;
+ import sun.java2d.x11.X11VolatileSurfaceManager;
++import sun.java2d.xr.*;
+ 
+ /**
+  * The SurfaceManagerFactory that creates VolatileSurfaceManager
+@@ -52,11 +53,14 @@
+      */
+     public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
+                                                         Object context)
+-    {
++    {    	
+         GraphicsConfiguration gc = vImg.getGraphicsConfig();
++        
+         if (gc instanceof GLXGraphicsConfig) {
+             return new GLXVolatileSurfaceManager(vImg, context);
+-        } else {
++        } else if(gc instanceof XRGraphicsConfig) {
++            return new XRVolatileSurfaceManager(vImg, context);
++        }else {
+             return new X11VolatileSurfaceManager(vImg, context);
+         }
+     }
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -42,10 +42,7 @@
+ import java.awt.image.Raster;
+ import java.awt.peer.ComponentPeer;
+ 
+-import sun.awt.SunHints;
+-import sun.awt.SunToolkit;
+-import sun.awt.X11ComponentPeer;
+-import sun.awt.X11GraphicsConfig;
++import sun.awt.*;
+ import sun.awt.image.PixelConverter;
+ import sun.font.X11TextRenderer;
+ import sun.java2d.InvalidPipeException;
+@@ -70,7 +67,7 @@
+ 
+     protected int depth;
+ 
+-    private static native void initIDs(Class xorComp, boolean tryDGA);
++    private static native void initIDs(Class xorComp, boolean tryDGA);  //OK
+     protected native void initSurface(int depth, int width, int height,
+                                       long drawable);
+     native boolean isDrawableValid();
+@@ -198,7 +195,10 @@
+     protected static TextPipe x11textpipe;
+     protected static boolean dgaAvailable;
+ 
+-    static {
++    public static void initX11SurfaceData()
++    {
++    	if(!X11GraphicsEnvironment.isX11SurfaceDataInitialized())
++    	{
+         if (!GraphicsEnvironment.isHeadless()) {
+             // If a screen magnifier is present, don't attempt to use DGA
+             String magPresent = (String) java.security.AccessController.doPrivileged
+@@ -232,9 +232,12 @@
+                 X11PMBlitLoops.register();
+                 X11PMBlitBgLoops.register();
+             }
+-        }
++            
++            X11GraphicsEnvironment.setX11SurfaceDataInitialized();
++        }    	
++    	}
+     }
+-
++    
+     /**
+      * Returns true if we can use DGA on any of the screens
+      */
+@@ -616,7 +619,7 @@
+     {
+         // assert SunToolkit.isAWTLockHeldByCurrentThread();
+ 
+-        if (!isValid()) {
++    	if (!isValid()) {
+             throw new InvalidPipeException("bounds changed");
+         }
+ 
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,50 @@
++package sun.java2d.xr;
++
++import java.awt.*;
++import java.awt.geom.*;
++
++import sun.java2d.*;
++import sun.java2d.loops.*;
++import sun.java2d.pipe.*;
++
++
++public class XRDrawImage extends DrawImage {
++
++    @Override
++    protected void renderImageXform(SunGraphics2D sg, Image img,
++                                    AffineTransform tx, int interpType,
++                                    int sx1, int sy1, int sx2, int sy2,
++                                    Color bgColor)
++    {    	
++            SurfaceData dstData = sg.surfaceData;
++            SurfaceData srcData =
++                dstData.getSourceSurfaceData(img,
++                                             sg.TRANSFORM_GENERIC,
++                                             sg.imageComp,
++                                             bgColor);
++
++            if (srcData != null && !isBgOperation(srcData, bgColor) && srcData instanceof XRSurfaceData)
++            {
++                SurfaceType srcType = srcData.getSurfaceType();
++                SurfaceType dstType = dstData.getSurfaceType();
++                
++                ((XRSurfaceData) srcData).setPreferredInterpolation(XRUtils.ATransOpToXRQuality(interpType));
++                
++                TransformBlit blit = TransformBlit.getFromCache(srcType,
++                                                                sg.imageComp,
++                                                                dstType);
++
++                if (blit != null) {
++                    blit.Transform(srcData, dstData,
++                                   sg.composite, sg.getCompClip(),
++                                   tx, interpType,
++                                   sx1, sy1, 0, 0, sx2-sx1, sy2-sy1);
++                    return;
++                }
++       
++        }
++
++        super.renderImageXform(sg, img, tx, interpType,  sx1, sy1, sx2, sy2, bgColor);
++    }
++}
++
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,42 @@
++/*
++ * To change this template, choose Tools | Templates
++ * and open the template in the editor.
++ */
++
++package sun.java2d.xr;
++
++import sun.awt.*;
++import sun.awt.image.*;
++import sun.java2d.*;
++
++/**
++ *
++ * @author ce
++ */
++public class XRGraphicsConfig extends X11GraphicsConfig
++implements SurfaceManager.ProxiedGraphicsConfig
++{
++	private XRGraphicsConfig(X11GraphicsDevice device, int visualnum, int depth, int colormap, boolean doubleBuffer)
++    {
++		super(device, visualnum, depth, colormap, doubleBuffer);
++    }
++    
++    public SurfaceData createSurfaceData(X11ComponentPeer peer) {
++        return XRSurfaceData.createData(peer);
++    }
++	
++    public static XRGraphicsConfig getConfig(X11GraphicsDevice device,
++            int visualnum, int depth,
++            int colormap, boolean doubleBuffer)
++    {
++        if (!X11GraphicsEnvironment.isXRenderAvailable()) {
++            return null;
++        }
++        
++        return new XRGraphicsConfig(device, visualnum, depth, colormap, doubleBuffer);
++    }
++    
++    public Object getProxyKey() {
++        return this;
++    }
++}
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,71 @@
++package sun.java2d.xr;
++
++import static sun.java2d.loops.CompositeType.SrcNoEa;
++import static sun.java2d.loops.CompositeType.SrcOver;
++import static sun.java2d.loops.SurfaceType.IntArgb;
++import static sun.java2d.loops.SurfaceType.IntArgbPre;
++import static sun.java2d.loops.SurfaceType.IntRgb;
++
++import java.awt.AlphaComposite;
++import java.awt.Composite;
++
++import sun.awt.*;
++import sun.java2d.*;
++import sun.java2d.loops.*;
++import sun.java2d.pipe.Region;
++
++public class XRMaskBlit extends MaskBlit
++{
++	static void register()
++	{
++		GraphicsPrimitive[] primitives = 
++		{ 
++				new XRMaskBlit(IntArgbPre, SrcOver, IntArgbPre), 
++				new XRMaskBlit(IntRgb, SrcOver, IntRgb), 
++				new XRMaskBlit(IntArgbPre, SrcNoEa, IntRgb), 
++				new XRMaskBlit(IntRgb, SrcNoEa, IntArgbPre)
++		};
++		GraphicsPrimitiveMgr.register(primitives);
++	}
++
++	public XRMaskBlit(SurfaceType srcType, CompositeType compType, SurfaceType dstType)
++	{
++		super(srcType, CompositeType.AnyAlpha, dstType);
++	}
++
++	protected native void maskBlit(long srcXsdo, long dstxsdo, long alphaXsdo, int srcx, int srcy, int dstx, int dsty, int w, int h, int maskoff, int maskscan, int masklen, byte[] mask);
++
++	
++	static XRSurfaceData alphaPM;
++	static int alphaWidth = 0, alphaHeight = 0;
++	public void MaskBlit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int srcx, int srcy, int dstx, int dsty, int width, int height, byte[] mask, int maskoff, int maskscan)
++	{
++		if (width <= 0 || height <= 0)
++		{
++			return;
++		}
++
++		try
++		{
++			SunToolkit.awtLock();
++			
++			if (alphaPM == null || alphaWidth < width || alphaHeight < height)
++			{
++				alphaPM = XRSurfaceData.createData(((XRSurfaceData) dst).graphicsConfig, width, height);
++				alphaWidth = width;
++				alphaHeight = height;
++			}
++
++			XRSurfaceData x11sd = (XRSurfaceData) src;
++			x11sd.validateAsSource(null, XRUtils.RepeatNone);
++			
++			XRSurfaceData x11dst = (XRSurfaceData) dst;
++			x11dst.validate(clip, comp, null, null, null, 0);
++			
++			maskBlit(src.getNativeOps(), dst.getNativeOps(), alphaPM.getNativeOps(), srcx, srcy, dstx, dsty, width, height, maskoff, maskscan, mask != null ? mask.length : 0, mask);
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
++}
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,75 @@
++package sun.java2d.xr;
++
++import static sun.java2d.loops.CompositeType.SrcNoEa;
++import static sun.java2d.loops.CompositeType.SrcOver;
++import static sun.java2d.loops.SurfaceType.AnyColor;
++import static sun.java2d.loops.SurfaceType.GradientPaint;
++import static sun.java2d.loops.SurfaceType.LinearGradientPaint;
++import static sun.java2d.loops.SurfaceType.OpaqueColor;
++import static sun.java2d.loops.SurfaceType.OpaqueGradientPaint;
++import static sun.java2d.loops.SurfaceType.OpaqueLinearGradientPaint;
++import static sun.java2d.loops.SurfaceType.OpaqueRadialGradientPaint;
++import static sun.java2d.loops.SurfaceType.OpaqueTexturePaint;
++import static sun.java2d.loops.SurfaceType.RadialGradientPaint;
++import static sun.java2d.loops.SurfaceType.TexturePaint;
++import static sun.java2d.pipe.BufferedOpCodes.MASK_FILL;
++
++import java.awt.*;
++import java.awt.geom.*;
++import java.awt.geom.Rectangle2D.Float;
++import java.awt.image.*;
++
++import sun.awt.*;
++import sun.java2d.*;
++import sun.java2d.loops.*;
++import sun.java2d.opengl.*;
++import sun.java2d.pipe.*;
++
++public class XRMaskFill extends MaskFill
++{
++	static void register()
++	{
++		GraphicsPrimitive[] primitives = { new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueColor, SrcNoEa, XRSurfaceData.IntRgbX11), new XRMaskFill(GradientPaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueGradientPaint, SrcNoEa, XRSurfaceData.IntRgbX11),
++				new XRMaskFill(LinearGradientPaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueLinearGradientPaint, SrcNoEa, XRSurfaceData.IntRgbX11), new XRMaskFill(RadialGradientPaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueRadialGradientPaint, SrcNoEa, XRSurfaceData.IntRgbX11),
++				new XRMaskFill(TexturePaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueTexturePaint, SrcNoEa, XRSurfaceData.IntRgbX11),
++
++				new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueColor, SrcNoEa, XRSurfaceData.IntArgbX11), new XRMaskFill(GradientPaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueGradientPaint, SrcNoEa, XRSurfaceData.IntArgbX11),
++				new XRMaskFill(LinearGradientPaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueLinearGradientPaint, SrcNoEa, XRSurfaceData.IntArgbX11), new XRMaskFill(RadialGradientPaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueRadialGradientPaint, SrcNoEa, XRSurfaceData.IntArgbX11),
++				new XRMaskFill(TexturePaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueTexturePaint, SrcNoEa, XRSurfaceData.IntArgbX11) };
++
++		GraphicsPrimitiveMgr.register(primitives);
++	}
++
++	protected XRMaskFill(SurfaceType srcType, CompositeType compType, SurfaceType surfaceType)
++	{
++		super(srcType, compType, surfaceType);
++	}
++
++	protected native void maskFill(long xsdo, long alphaXsdo, int x, int y, int w, int h, int maskoff, int maskscan, int masklen, byte[] mask);
++
++	static XRSurfaceData alphaPM;
++	static int alphaWidth = 0, alphaHeight = 0;
++
++	public void MaskFill(SunGraphics2D sg2d, SurfaceData sData, Composite comp, final int x, final int y, final int w, final int h, final byte[] mask, final int maskoff, final int maskscan)
++	{
++		try
++		{
++			SunToolkit.awtLock();
++
++			XRSurfaceData x11sd = (XRSurfaceData) sData;
++			x11sd.validate(sg2d.getCompClip(), sg2d.getComposite(), sg2d.getTransform(), sg2d.getPaint(), sg2d, 0);
++
++			if (alphaPM == null || alphaWidth < w || alphaHeight < h)
++			{
++				alphaPM = XRSurfaceData.createData(((XRSurfaceData) sData).graphicsConfig, w, h);
++				alphaWidth = w;
++				alphaHeight = h;
++			}
++
++			maskFill(sData.getNativeOps(), alphaPM.getNativeOps(), x, y, w, h, maskoff, maskscan, mask != null ? mask.length : 0, mask);
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
++}
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,206 @@
++/*
++ * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++package sun.java2d.xr;
++
++import sun.awt.SunToolkit;
++import sun.java2d.loops.*;
++import sun.java2d.opengl.*;
++import sun.java2d.pipe.Region;
++import sun.java2d.SurfaceData;
++import java.awt.*;
++import java.awt.geom.*;
++import java.awt.image.*;
++
++/**
++ * X11PMBlitLoops
++ *
++ * This class accelerates Blits between two surfaces of types *PM.  Since
++ * the onscreen surface is of that type and some of the offscreen surfaces
++ * may be of that type (if they were created via X11OffScreenImage), then
++ * this type of Blit will accelerated double-buffer copies between those
++ * two surfaces.
++*/
++public class XRPMBlitLoops
++{
++
++	public static void register()
++	{
++		GraphicsPrimitive[] primitives = {
++		
++				new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11), new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11), new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
++
++				new X11PMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), new X11PMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11), new X11PMScaledBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11), new X11PMScaledBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
++
++				new X11PMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), new X11PMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11), new X11PMTransformedBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11), new X11PMTransformedBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
++
++				/*TODO Allow blits from argb surfaces too*/
++		};
++		GraphicsPrimitiveMgr.register(primitives);
++	}
++
++	/**
++	 * Blit
++	 * This native method is where all of the work happens in the
++	 * accelerated Blit.
++	 */
++	public static native void nativeRenderBlit(long srcData, long dstData, int sx, int sy, int dx, int dy, int w, int h);
++
++	static AffineTransform identityTransform = AffineTransform.getTranslateInstance(0, 0);
++	static double[] tmpCoord = new double[4];
++}
++
++class X11PMBlit extends Blit
++{
++	public X11PMBlit(SurfaceType srcType, SurfaceType dstType)
++	{
++		super(srcType, CompositeType.AnyAlpha, dstType);
++	}
++
++	public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h)
++	{
++		try
++		{
++			SunToolkit.awtLock();
++
++			XRSurfaceData x11sdDst = (XRSurfaceData) dst;
++			x11sdDst.validate(clip, comp, null, null, null, 0);
++			XRSurfaceData x11sdSrc = (XRSurfaceData) src;
++	
++			x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);
++
++			XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), sx, sy, dx, dy, w, h);
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
++}
++
++class X11PMScaledBlit extends ScaledBlit
++{
++	public X11PMScaledBlit(SurfaceType srcType, SurfaceType dstType)
++	{
++		super(srcType, CompositeType.AnyAlpha, dstType);
++	}
++
++	public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, double dx2, double dy2)
++	{
++		try
++		{
++			SunToolkit.awtLock();
++
++			XRSurfaceData x11sdDst = (XRSurfaceData) dst;
++			x11sdDst.validate(clip, comp, null, null, null, 0);
++			XRSurfaceData x11sdSrc = (XRSurfaceData) src;
++
++			double xScale = (dx2 - dx1) / (sx2 - sx1);
++			double yScale = (dy2 - dy1) / (sy2 - sy1);
++
++			sx1 *= xScale;
++			sx2 *= xScale;
++			sy1 *= yScale;
++			sy2 *= yScale;
++
++			AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale);
++
++			x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST);
++
++			XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));
++
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
++}
++
++/**
++ * Called also if scale+transform is set
++ * @author Clemens Eisserer
++ */
++class X11PMTransformedBlit extends TransformBlit
++{
++	public X11PMTransformedBlit(SurfaceType srcType, SurfaceType dstType)
++	{
++		super(srcType, CompositeType.AnyAlpha, dstType);
++	}
++
++	public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy, int dstx, int dsty, int width, int height)
++	{
++		try
++		{			
++			SunToolkit.awtLock();
++
++			XRSurfaceData x11sdDst = (XRSurfaceData) dst;
++			x11sdDst.validate(clip, comp, null, null, null, 0);
++			XRSurfaceData x11sdSrc = (XRSurfaceData) src;
++
++			boolean needClip =  (xform.getScaleX() != 0.0f) || (xform.getShearY() != 0.0f);
++			try
++			{				
++				/*Calculate area which will be covered by the transform-blit*/
++				Rectangle2D.Float rect = new Rectangle2D.Float(dstx, dsty, width, height);
++				Shape shp = xform.createTransformedShape(rect);
++				Rectangle bounds = shp.getBounds();
++				
++				AffineTransform sourceTrans = (AffineTransform) xform.clone();
++				sourceTrans.translate(-srcx, -srcy);
++			
++//				System.out.println("srcx "+srcx+" srcy:"+srcy+" dstx:"+dstx+" dsty:"+dsty+" width:"+width+" height:"+height);
++//				System.out.println("Dest-Translation: x:"+xform.getTranslateX()+" y:"+xform.getTranslateY());
++				
++				//AffineTransform sourceTransform = new AffineTransform(xform.getScaleX(), xform.getShearY(), xform.getShearX(), xform.getScaleY(), 0, 0);
++				//sourceTransform.translate(-srcx, -srcy);
++				
++				sourceTrans.invert();
++			    
++				
++			    //x11sdSrc.validateAsSource(sourceTrans, XRUtils.RepeatPad); /*Pad avoids smearing, but falls back to software*/
++				x11sdSrc.validateAsSource(sourceTrans, XRUtils.RepeatNone);
++
++				
++				if(needClip)
++				{
++			        x11sdDst.setShapeClip(shp);
++				}
++				
++			    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), 0, 0, 0, 0, bounds.x + bounds.width, bounds.y + bounds.height);// bounds.x, bounds.y, bounds.width, bounds.height);//(int) (maxX - minX), (int) (maxY - minY));
++		
++			    if(needClip)
++			    {
++			        x11sdDst.resetShapeClip();
++			    }
++			   
++			} catch (Exception ex)
++			{
++				ex.printStackTrace();
++			}
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
++}
+\ No newline at end of file
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,255 @@
++package sun.java2d.xr;
++
++import java.awt.*;
++import java.awt.geom.*;
++
++import sun.awt.SunToolkit;
++import sun.java2d.SunGraphics2D;
++import sun.java2d.pipe.Region;
++import sun.java2d.pipe.PixelDrawPipe;
++import sun.java2d.pipe.PixelFillPipe;
++import sun.java2d.pipe.ShapeDrawPipe;
++import sun.java2d.pipe.SpanIterator;
++import sun.java2d.pipe.ShapeSpanIterator;
++import sun.java2d.pipe.LoopPipe;
++
++public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe
++{
++	public XRRenderer()
++	{}
++
++	public static XRRenderer getInstance()
++	{
++		return new XRRenderer();
++		//	return (GraphicsPrimitive.tracingEnabled() ? new X11TracingRenderer() : new X11Renderer());
++	}
++
++	private final void validate(SunGraphics2D sg2d)
++	{
++		// NOTE: getCompClip() will revalidateAll() if the
++		// surfaceData is invalid.  This should ensure that
++		// the clip and pixel that we are validating against
++		// are the most current.
++		//
++		// The assumption is that the pipeline after that
++		// revalidation will either be another X11 pipe
++		// (because the drawable format never changes on X11)
++		// or a null pipeline if the surface is disposed.
++		//
++		// Since we do not get the ops structure of the SurfaceData
++		// until the actual call down to the native level we will
++		// pick up the most recently validated copy.
++		// Note that if the surface is disposed, a NullSurfaceData
++		// (with null native data structure) will be set in
++		// sg2d, so we have to protect against it in native code.
++
++		XRSurfaceData x11sd = (XRSurfaceData) sg2d.surfaceData;
++		x11sd.validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
++	}
++
++	native void XRDrawLine(long pXSData, int x1, int y1, int x2, int y2);
++
++	public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2)
++	{
++		try
++		{
++			SunToolkit.awtLock();
++			
++			validate(sg2d);
++			int transx = sg2d.transX;
++			int transy = sg2d.transY;
++			XRDrawLine(sg2d.surfaceData.getNativeOps(), x1 + transx, y1 + transy, x2 + transx, y2 + transy);
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
++
++	public void drawRect(SunGraphics2D sg2d, int x, int y, int width, int height)
++	{
++		draw(sg2d, new Rectangle2D.Float(x, y, width, height));
++	}
++
++	public void drawPolyline(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
++	{
++		throw new RuntimeException("Not implemented");
++	}
++
++	public void drawPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
++	{
++		draw(sg2d, new Polygon(xpoints, ypoints, npoints));
++	}
++
++	native void XRFillRect(long pXSData, int x, int y, int width, int height);
++
++	public void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height)
++	{
++		SunToolkit.awtLock();
++		try
++		{
++			validate(sg2d);
++
++			x += sg2d.transform.getTranslateX();
++			y += sg2d.transform.getTranslateY();
++			XRFillRect(sg2d.surfaceData.getNativeOps(), x, y, width, height);
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
++
++	public void fillPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
++	{
++		fill(sg2d, new Polygon(xpoints, ypoints, npoints));
++	}
++
++	public void drawRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight)
++	{
++		draw(sg2d, new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
++	}
++
++	public void fillRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight)
++	{
++		fill(sg2d, new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
++	}
++
++	public void drawOval(SunGraphics2D sg2d, int x, int y, int width, int height)
++	{
++		draw(sg2d, new Ellipse2D.Float(x, y, width, height));
++	}
++
++	public void fillOval(SunGraphics2D sg2d, int x, int y, int width, int height)
++	{
++		fill(sg2d, new Ellipse2D.Float(x, y, width, height));
++	}
++
++	public void drawArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle)
++	{
++		draw(sg2d, new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN));
++	}
++
++	public void fillArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle)
++	{
++		fill(sg2d, new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE));
++	}
++
++	native void XRFillSpans(long pXSData, SpanIterator si, long iterator, int transx, int transy);
++
++	native void XRDoPath(SunGraphics2D sg2d, long pXSData, int transX, int transY, Path2D.Float p2df, boolean isFill);
++
++	private void doPath(SunGraphics2D sg2d, Shape s, boolean isFill)
++	{
++		Path2D.Float p2df;
++		int transx, transy;
++		if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE)
++		{
++			if (s instanceof Path2D.Float)
++			{
++				p2df = (Path2D.Float) s;
++			} else
++			{
++				p2df = new Path2D.Float(s);
++			}
++			transx = sg2d.transX;
++			transy = sg2d.transY;
++		} else
++		{
++			p2df = new Path2D.Float(s, sg2d.transform);
++			transx = 0;
++			transy = 0;
++		}
++		
++		try
++		{
++			SunToolkit.awtLock();
++			validate(sg2d);
++			XRDoPath(sg2d, sg2d.surfaceData.getNativeOps(), transx, transy, p2df, isFill);
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
++
++	public void draw(SunGraphics2D sg2d, Shape s)
++	{
++
++		if (sg2d.strokeState == sg2d.STROKE_THIN)
++		{
++			doPath(sg2d, s, false);
++			return;
++		}
++		
++		if (sg2d.strokeState < sg2d.STROKE_CUSTOM)
++		{
++			ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
++			try
++			{
++				try
++				{
++					SunToolkit.awtLock();
++					validate(sg2d);
++					XRFillSpans(sg2d.surfaceData.getNativeOps(), si, si.getNativeIterator(), 0, 0);
++				} finally
++				{
++					SunToolkit.awtUnlock();
++				}
++			} finally
++			{
++				si.dispose();
++			}
++		} else
++		{
++			fill(sg2d, sg2d.stroke.createStrokedShape(s));
++		}
++	}
++
++	public void fill(SunGraphics2D sg2d, Shape s)
++	{
++		if (sg2d.strokeState == sg2d.STROKE_THIN)
++		{
++			doPath(sg2d, s, true);
++			return;
++		}
++
++		AffineTransform at;
++		int transx, transy;
++		if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE)
++		{
++			// Transform (translation) will be done by XFillSpans
++			at = null;
++			transx = sg2d.transX;
++			transy = sg2d.transY;
++		} else
++		{
++			// Transform will be done by the PathIterator
++			at = sg2d.transform;
++			transx = transy = 0;
++		}
++
++		ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
++		try
++		{
++			// Subtract transx/y from the SSI clip to match the
++			// (potentially untranslated) geometry fed to it
++			Region clip = sg2d.getCompClip();
++			ssi.setOutputAreaXYXY(clip.getLoX() - transx, clip.getLoY() - transy, clip.getHiX() - transx, clip.getHiY() - transy);
++			ssi.appendPath(s.getPathIterator(at));
++			try
++			{
++				SunToolkit.awtLock();
++				
++				validate(sg2d);
++				XRFillSpans(sg2d.surfaceData.getNativeOps(), ssi, ssi.getNativeIterator(), transx, transy);
++			} finally
++			{
++				SunToolkit.awtUnlock();
++			}
++		} finally
++		{
++			ssi.dispose();
++		}
++	}
++
++	native void devCopyArea(long sdOps, long xgc, int srcx, int srcy, int dstx, int dsty, int w, int h);
++
++}
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,1017 @@
++/*
++ * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++package sun.java2d.xr;
++
++import java.awt.*;
++import java.awt.MultipleGradientPaint.*;
++import java.awt.Transparency;
++import java.awt.geom.*;
++import java.awt.image.*;
++import sun.awt.*;
++import sun.awt.image.PixelConverter;
++import sun.font.*;
++import sun.java2d.InvalidPipeException;
++import sun.java2d.SunGraphics2D;
++import sun.java2d.SurfaceData;
++import sun.java2d.SurfaceDataProxy;
++import sun.java2d.loops.*;
++import sun.java2d.pipe.*;
++import static sun.java2d.xr.XRUtils.XDoubleToFixed;
++
++public abstract class XRSurfaceData extends SurfaceData
++{
++	X11ComponentPeer peer;
++	XRGraphicsConfig graphicsConfig;
++	private RenderLoops solidloops;
++
++	protected int depth;
++
++	private static native void initIDs(boolean gradCache);
++
++	protected native void XRInitSurface(int depth, int width, int height, long drawable, int pictFormat);
++
++	native boolean XRIsDrawableValid();
++
++	protected native void flushNativeSurface();
++
++	native void XRInitXRender(long xsdo, int pictForm);
++
++	public static final String DESC_BYTE_A8_X11 = "Byte A8 Pixmap";
++	public static final String DESC_INT_RGB_X11 = "Integer RGB Pixmap";
++	public static final String DESC_INT_ARGB_X11 = "Integer ARGB-Pre Pixmap";
++
++	public static final SurfaceType ByteA8X11 = SurfaceType.ByteGray.deriveSubType(DESC_BYTE_A8_X11);
++	public static final SurfaceType IntRgbX11 = SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_X11);
++	public static final SurfaceType IntArgbX11 = SurfaceType.IntArgbPre.deriveSubType(DESC_INT_ARGB_X11);
++
++	public Raster getRaster(int x, int y, int w, int h)
++	{
++		throw new InternalError("not implemented yet");
++	}
++
++	protected XRRenderer x11pipe;
++	protected PixelToShapeConverter x11txpipe;
++	protected TextPipe x11textpipe;
++	protected XRDrawImage xrDrawImage;
++
++	public static void initXRSurfaceData()
++	{
++		if (!X11GraphicsEnvironment.isX11SurfaceDataInitialized())
++		{
++			boolean cacheGradients = true;
++			String xProp = System.getProperty("sun.java2d.xrgradcache");
++			if (xProp != null)
++			{
++				cacheGradients = !(xProp.equalsIgnoreCase("false") || xProp.equalsIgnoreCase("f"));
++			}
++
++			initIDs(cacheGradients);
++
++			XRPMBlitLoops.register();
++			XRMaskFill.register();
++			XRMaskBlit.register();
++
++			X11GraphicsEnvironment.setX11SurfaceDataInitialized();
++		}
++	}
++
++	protected boolean isDrawableValid()
++	{
++		try
++		{
++			SunToolkit.awtLock();
++			return XRIsDrawableValid();
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
++
++	@Override
++	public SurfaceDataProxy makeProxyFor(SurfaceData srcData)
++	{
++		return XRSurfaceDataProxy.createProxy(srcData, graphicsConfig);
++	}
++
++	public void validatePipe(SunGraphics2D sg2d)
++	{
++	        TextPipe textpipe;
++	        boolean validated = false;
++
++	        if (/* CompositeType.SrcNoEa (any color) */
++	            (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
++	             sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR)        ||
++
++	            /* CompositeType.SrcOver (any color) */
++	            (sg2d.compositeState == SunGraphics2D.COMP_ALPHA    &&
++	             sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
++	             (((AlphaComposite)sg2d.composite).getRule() ==
++	              AlphaComposite.SRC_OVER)))
++	        {
++	            textpipe = x11textpipe;
++	        } else {
++	            // do this to initialize textpipe correctly; we will attempt
++	            // to override the non-text pipes below
++	            super.validatePipe(sg2d);
++	            textpipe = sg2d.textpipe;
++	            validated = true;
++	        }
++
++	        PixelToShapeConverter txPipe = null;
++	        XRRenderer nonTxPipe = null;
++
++	        if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) 
++	        {
++	            if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) {
++	                if (sg2d.compositeState < sg2d.COMP_XOR) {
++	                    txPipe = x11txpipe;
++	                    nonTxPipe = x11pipe;
++	                }
++	            } else if (sg2d.compositeState <= sg2d.COMP_ALPHA) {
++	                if (isPaintValid(sg2d)) {
++	                    txPipe = x11txpipe;
++	                    nonTxPipe = x11pipe;
++	                }
++	                // custom paints handled by super.validatePipe() below
++	            }
++	        }
++
++	        if (txPipe != null) {
++	            if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
++	                sg2d.drawpipe = txPipe;
++	                sg2d.fillpipe = txPipe;
++	            } else if (sg2d.strokeState != sg2d.STROKE_THIN) {
++	                sg2d.drawpipe = txPipe;
++	                sg2d.fillpipe = nonTxPipe;
++	            } else {
++	                sg2d.drawpipe = nonTxPipe;
++	                sg2d.fillpipe = nonTxPipe;
++	            }
++	            sg2d.shapepipe = nonTxPipe;
++	        } else {
++	            if (!validated) {
++	                super.validatePipe(sg2d);
++	            }
++	        }
++
++	        // install the text pipe based on our earlier decision
++	        sg2d.textpipe = textpipe;
++
++	        // always override the image pipe with the specialized OGL pipe
++	        sg2d.imagepipe = xrDrawImage;
++		
++//		
++//		if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON && /*sg2d.paintState <= sg2d.PAINT_ALPHACOLOR &&*/(sg2d.compositeState <= sg2d.COMP_ALPHA || sg2d.compositeState == sg2d.COMP_XOR))
++//		{
++//			if (x11txpipe == null)
++//			{
++//				/*
++//				 * Note: this is thread-safe since x11txpipe is the
++//				 * second of the two pipes constructed in makePipes().
++//				 * In the rare case we are racing against another
++//				 * thread making new pipes, setting lazypipe is a
++//				 * safe alternative to waiting for the other thread.
++//				 */
++//				sg2d.drawpipe = lazypipe;
++//				sg2d.fillpipe = lazypipe;
++//				sg2d.shapepipe = lazypipe;
++//				sg2d.imagepipe = lazypipe;
++//				sg2d.textpipe = lazypipe;
++//				return;
++//			}
++//
++//			if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE)
++//			{
++//				sg2d.drawpipe = x11txpipe;
++//				sg2d.fillpipe = x11txpipe;
++//			} else if (sg2d.strokeState != sg2d.STROKE_THIN)
++//			{
++//				sg2d.drawpipe = x11txpipe;
++//				sg2d.fillpipe = x11pipe;
++//			} else
++//			{
++//				sg2d.drawpipe = x11pipe;
++//				sg2d.fillpipe = x11pipe;
++//			}
++//			sg2d.shapepipe = x11pipe;
++//			sg2d.imagepipe = new XRDrawImage();
++//		} else
++//		{
++//			super.validatePipe(sg2d);
++//		}
++//
++//		//		 if (sg2d.compositeState <= sg2d.COMP_ALPHA) {
++//		//             if (XRPaints.isValid(sg2d)) {
++//		//                 sg2d.drawpipe = x11pipe;
++//		//                 sg2d.fillpipe = x11pipe;
++//		//             }
++//		//		 }
++//
++//		sg2d.textpipe = x11textpipe;
++
++	}
++	
++
++    @Override
++    protected MaskFill getMaskFill(SunGraphics2D sg2d) {
++        if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR && !isPaintValid(sg2d)) {
++            	return null;
++        }
++        return super.getMaskFill(sg2d);
++    }
++
++	public RenderLoops getRenderLoops(SunGraphics2D sg2d)
++	{
++		if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && sg2d.compositeState <= sg2d.COMP_ALPHA)
++		{
++			return solidloops;
++		}
++		
++		return super.getRenderLoops(sg2d);
++	}
++
++	public GraphicsConfiguration getDeviceConfiguration()
++	{
++		return graphicsConfig;
++	}
++
++	/**
++	 * Method for instantiating a Window SurfaceData
++	 */
++	public static XRWindowSurfaceData createData(X11ComponentPeer peer)
++	{
++		XRGraphicsConfig gc = getGC(peer);
++		return new XRWindowSurfaceData(peer, gc, gc.getSurfaceType());
++	}
++
++	/**
++	 * Method for instantiating a Pixmap SurfaceData (offscreen)
++	 */
++	public static XRPixmapSurfaceData createData(XRGraphicsConfig gc, int width, int height, ColorModel cm, Image image, long drawable, int transparency)
++	{
++		int depth = transparency > Transparency.OPAQUE ? 32 : 24;
++		if (depth == 24)
++		{
++			cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00, 0x000000FF);
++		} else
++		{
++			cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
++		}
++
++		return new XRPixmapSurfaceData(gc, width, height, image, getSurfaceType(gc, transparency), cm, drawable, transparency, XRUtils.getPictureFormatForTransparency(transparency), depth);
++	}
++
++	public static XRPixmapSurfaceData createData(XRGraphicsConfig gc, int width, int height)
++	{
++		/*TODO - may I really pass this XRGraphicsConfig down, although depth is different??*/
++		return new XRPixmapSurfaceData(gc, width, height, null, ByteA8X11, new DirectColorModel(8, 0x00000000, 0x00000000, 0x00000000, 0x000000FF), 0, Transparency.OPAQUE, XRUtils.PictStandardA8, 8);
++	}
++
++	//	/**
++	//	 * Initializes the native Ops pointer.
++	//	 */
++	private native void initOps(X11ComponentPeer peer, XRGraphicsConfig gc, int depth);
++
++	protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, SurfaceType sType, ColorModel cm, int depth, int transparency)
++	{
++		super(sType, cm);
++		this.peer = peer;
++		this.graphicsConfig = gc;
++		this.solidloops = graphicsConfig.getSolidLoops(sType);
++		this.depth = depth;
++		initOps(peer, graphicsConfig, depth);
++
++		setBlitProxyKey(gc.getProxyKey());
++	}
++
++	public void initXRender(int pictureFormat)
++	{
++		try
++		{
++			SunToolkit.awtLock();
++			XRInitXRender(getNativeOps(), pictureFormat);
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
++
++	public static XRGraphicsConfig getGC(X11ComponentPeer peer)
++	{
++		if (peer != null)
++		{
++			return (XRGraphicsConfig) peer.getGraphicsConfiguration();
++		} else
++		{
++			GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
++			GraphicsDevice gd = env.getDefaultScreenDevice();
++			return (XRGraphicsConfig) gd.getDefaultConfiguration();
++		}
++	}
++
++	/**
++	 * Returns a boolean indicating whether or not a copyArea from
++	 * the given rectangle source coordinates might be incomplete
++	 * and result in X11 GraphicsExposure events being generated
++	 * from XCopyArea.
++	 * This method allows the SurfaceData copyArea method to determine
++	 * if it needs to set the GraphicsExposures attribute of the X11 GC
++	 * to True or False to receive or avoid the events.
++	 * @return true if there is any chance that an XCopyArea from the
++	 *              given source coordinates could produce any X11
++	 *              Exposure events.
++	 */
++	public abstract boolean canSourceSendExposures(int x, int y, int w, int h);
++	
++	public void validateCopyAreaGC(Region gcClip)
++	{
++		if (validatedGCClip != gcClip)
++		{
++			if (gcClip != null)
++			{
++				//XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
++			} else
++			{
++				//XRResetClip(getNativeOps());
++			}
++			validatedGCClip = gcClip;
++		}
++	}
++
++	public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy)
++	{
++		if (x11pipe == null)
++		{
++			if (!isDrawableValid())
++			{
++				return true;
++			}
++			makePipes();
++		}
++		CompositeType comptype = sg2d.imageComp;
++		if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE && (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa.equals(comptype)))
++		{
++			x += sg2d.transX;
++			y += sg2d.transY;
++			SunToolkit.awtLock();
++			try
++			{
++				validateCopyAreaGC(sg2d.getCompClip());
++				//validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
++				//						boolean needExposures = canSourceSendExposures(x, y, w, h);
++				//						long xgc = getBlitGC(sg2d.getCompClip(), needExposures);
++				
++				
++				x11pipe.devCopyArea(getNativeOps(), xgc, x, y, x + dx, y + dy, w, h);
++				//X11PMBlitLoops.nativeRenderBlit(getNativeOps(), getNativeOps(), x, y, dx, dy, w, h);
++			} finally
++			{
++				SunToolkit.awtUnlock();
++			}
++			return true;
++		}
++		return false;
++	}
++
++	public static SurfaceType getSurfaceType(XRGraphicsConfig gc, int transparency)
++	{
++		SurfaceType sType = null;
++
++		switch (transparency)
++		{
++			case Transparency.OPAQUE:
++				sType = XRSurfaceData.IntRgbX11;
++				break;
++
++			case Transparency.BITMASK:
++			case Transparency.TRANSLUCENT:
++				sType = XRSurfaceData.IntArgbX11;
++				break;
++		}
++
++		return sType;
++	}
++
++	public native void setInvalid();
++
++	public void invalidate()
++	{
++		if (isValid())
++		{
++			setInvalid();
++			super.invalidate();
++		}
++	}
++
++	/**
++	 * The following methods and variables are used to keep the Java-level
++	 * context state in sync with the native X11 GC associated with this
++	 * X11SurfaceData object.
++	 */
++
++	private static native long XCreateGC(long pXSData);
++
++	private static native void XRSetForeground(int pixel);
++
++	private static native void XRSetComposite(int compRule, float eAlpha);
++
++	private static native void XRSetClip(long xsdo, int lox, int loy, int hix, int hiy, Region complexclip);
++
++	private static native void XRResetClip(long xsdo);
++
++	private static native void XRSetTransformNative(long xsdo, int m00, int m01, int m02, int m10, int m11, int m12);
++
++	private static native void XRSetTexturePaint(long xsdo);
++
++	private static native void XRResetPaint();
++
++	private static native void XRSetRepeat(long xsdo, int repeat);
++
++	private void XRSetTransform(AffineTransform transform)
++	{
++		double[] transformData = new double[6];
++		transform.getMatrix(transformData);
++
++		XRSetTransformNative(getNativeOps(), XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]), XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
++	}
++
++	//private long xgc;
++
++	public static int validatedPixel = -1;
++	public static int validatedPaintState = -1;
++	private static Composite validatedComp;
++	public static Paint validatedPaint;
++	private static int validatedTextureInterpolation = -1;
++
++	private Region validatedClip;
++	private Region validatedGCClip;
++	private boolean validatedExposures = true;
++
++	private int validatedFlags;
++
++	private boolean transformInUse = false;
++	private AffineTransform validatedSourceTransform = new AffineTransform();
++	private int validatedRepeat = XRUtils.RepeatNone;
++	private int validatedInterpolation = -1;
++
++	private int preferredInterpolation = -1;
++
++	public void setPreferredInterpolation(int interpolation)
++	{
++		this.preferredInterpolation = interpolation;
++	}
++
++	public void setShapeClip(Shape shape)
++	{
++		Region shapeClip = Region.getInstance(validatedClip, shape, null);
++		XRSetClip(getNativeOps(), shapeClip.getLoX(), shapeClip.getLoY(), shapeClip.getHiX(), shapeClip.getHiY(), shapeClip.isRectangular() ? null : shapeClip);
++	}
++
++	public void resetShapeClip()
++	{
++		XRSetClip(getNativeOps(), validatedClip.getLoX(), validatedClip.getLoY(), validatedClip.getHiX(), validatedClip.getHiY(), validatedClip.isRectangular() ? null : validatedClip);
++	}
++
++	void validateAsSource(AffineTransform sxForm, int repeat)
++	{
++		validateAsSource(sxForm, repeat, preferredInterpolation);
++	}
++
++	void validateAsSource(AffineTransform sxForm, int repeat, int interpolation)
++	{
++		if (validatedClip != null)
++		{
++			validatedClip = null;
++			XRResetClip(getNativeOps());
++		}
++
++		if (validatedRepeat != repeat)
++		{
++			validatedRepeat = repeat;
++			XRSetRepeat(getNativeOps(), repeat);
++		}
++
++		if (sxForm == null)
++		{
++			if (transformInUse)
++			{
++				validatedSourceTransform.setToIdentity();
++				XRSetTransform(validatedSourceTransform);
++				transformInUse = false;
++			}
++		} else
++		{
++			if (!transformInUse || (transformInUse && !sxForm.equals(validatedSourceTransform)))
++			{
++				validatedSourceTransform.setTransform(sxForm.getScaleX(), sxForm.getShearY(), sxForm.getShearX(), sxForm.getScaleY(), sxForm.getTranslateX(), sxForm.getTranslateY());
++				XRSetTransform(validatedSourceTransform);
++				transformInUse = true;
++			}
++		}
++
++		if (interpolation != validatedInterpolation)
++		{
++			XRSetFilter(getNativeOps(), interpolation);
++			validatedInterpolation = interpolation;
++		}
++	}
++
++	public static native void XRSetFilter(long xsdo, int value);
++
++	private void setComposite(Composite comp)
++	{
++		if (comp instanceof AlphaComposite)
++		{
++			AlphaComposite aComp = (AlphaComposite) comp;
++			float extraAlpha = aComp.getAlpha();
++			//extraAlphaUsed = extraAlpha != 1.0f;
++
++			XRSetComposite(XRUtils.j2dAlphaCompToXR(aComp.getRule()), extraAlpha);
++		} else if (comp instanceof XORComposite)
++		{
++
++		} else
++		{
++			throw new InternalError("Composite accaleration not implemented for: " + comp.getClass().getName());
++		}
++	}
++
++	public static int[] convertToIntArgbPixels(Color[] colors, boolean linear)
++	{
++		int[] pixels = new int[colors.length];
++		for (int i = 0; i < colors.length; i++)
++		{
++			pixels[i] = colorToIntArgbPixel(colors[i], linear);
++		}
++		return pixels;
++	}
++
++	public static int colorToIntArgbPixel(Color c, boolean linear)
++	{
++		int rgb = c.getRGB();
++		if (!linear && ((rgb >> 24) == -1))
++		{
++			return rgb;
++		}
++		int a = rgb >>> 24;
++		int r = (rgb >> 16) & 0xff;
++		int g = (rgb >> 8) & 0xff;
++		int b = (rgb) & 0xff;
++		if (linear)
++		{
++			r = BufferedPaints.convertSRGBtoLinearRGB(r);
++			g = BufferedPaints.convertSRGBtoLinearRGB(g);
++			b = BufferedPaints.convertSRGBtoLinearRGB(b);
++		}
++
++		return ((a << 24) | (r << 16) | (g << 8) | (b));
++	}
++
++	private static void setGradientPaint(SunGraphics2D sg2d, GradientPaint paint, boolean useMask)
++	{
++		int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(), paint.getColor2() }, false);
++
++		float fractions[] = new float[2];
++		fractions[0] = 0;
++		fractions[1] = 1;
++
++		Point2D pt1 = paint.getPoint1();
++		Point2D pt2 = paint.getPoint2();
++
++		AffineTransform at = (AffineTransform) sg2d.transform.clone();
++		try
++		{
++			at.invert();
++		} catch (NoninvertibleTransformException ex)
++		{
++			ex.printStackTrace();
++		}
++
++		double[] transformData = new double[6];
++		at.getMatrix(transformData);
++
++		int repeat = paint.isCyclic() ? XRUtils.RepeatReflect : XRUtils.RepeatPad;
++
++		XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()), XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()), XDoubleToFixed(pt2.getY()), 2, repeat, useMask, false, XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]),
++				XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
++	}
++
++	public static boolean isPaintValid(SunGraphics2D sg2d)
++	{
++		if(sg2d.paintState == SunGraphics2D.PAINT_RAD_GRADIENT)
++		{
++			RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint;
++			return grad.getFocusPoint().equals(grad.getCenterPoint());
++		}
++		
++		return true;
++	}
++	
++	public static void setRadialGradientPaint(SunGraphics2D sg2d, RadialGradientPaint paint)
++	{
++		boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
++		Color[] colors = paint.getColors();
++		int numStops = colors.length;
++		Point2D center = paint.getCenterPoint();
++		Point2D focus = paint.getFocusPoint();
++
++		int cycleMethod = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
++		float[] fractions = paint.getFractions();
++		int[] pixels = convertToIntArgbPixels(colors, linear);
++		float radius = paint.getRadius();
++
++		// save original (untransformed) center and focus points
++		double cx = center.getX();
++		double cy = center.getY();
++		double fx = focus.getX();
++		double fy = focus.getY();
++
++		AffineTransform at = paint.getTransform();
++		at.preConcatenate(sg2d.transform);
++		focus = at.transform(focus, focus);
++
++		// transform unit circle to gradient coords; we start with the
++		// unit circle (center=(0,0), focus on positive x-axis, radius=1)
++		// and then transform into gradient space
++		at.translate(cx, cy);
++		at.rotate(fx - cx, fy - cy);
++		//  at.scale(radius, radius);
++
++		// invert to get mapping from device coords to unit circle
++		try
++		{
++			at.invert();
++		} catch (Exception e)
++		{
++			at.setToScale(0.0, 0.0);
++		}
++		focus = at.transform(focus, focus);
++
++		// clamp the focus point so that it does not rest on, or outside
++		// of, the circumference of the gradient circle
++		fx = Math.min(focus.getX(), 0.99);
++
++		double[] transformData = new double[6];
++		at.getMatrix(transformData);
++
++		XRSetRadialGradientPaint(fractions, pixels, XDoubleToFixed(fx), numStops, cycleMethod, false, linear, XDoubleToFixed(0), XDoubleToFixed(radius), XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]), XDoubleToFixed(transformData[3]),
++				XDoubleToFixed(transformData[5]));
++	}
++
++	public native static void XRSetRadialGradientPaint(float[] fractions, int[] pixels, int fx, int numStops, int cycleMethod, boolean useMask, boolean linear, int innerRadius, int outerRadius, int m00, int m01, int m02, int m10, int m11, int m12);
++
++	public static void setLinearGradientPaint(SunGraphics2D sg2d, LinearGradientPaint paint, boolean useMask)
++	{
++		boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
++		Color[] colors = paint.getColors();
++		int numStops = colors.length;
++		Point2D pt1 = paint.getStartPoint();
++		Point2D pt2 = paint.getEndPoint();
++
++		AffineTransform at = paint.getTransform();
++		at.preConcatenate(sg2d.transform);
++
++		int cycleMethod = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
++		float[] fractions = paint.getFractions();
++		int[] pixels = convertToIntArgbPixels(colors, linear);
++
++		try
++		{
++			at.invert();
++		} catch (NoninvertibleTransformException ex)
++		{
++			ex.printStackTrace();
++		}
++
++		double[] transformData = new double[6];
++		at.getMatrix(transformData);
++
++		XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()), XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()), XDoubleToFixed(pt2.getY()), numStops, cycleMethod, useMask, linear, XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]),
++				XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
++	}
++
++	private static native void XRSetLinearGradientPaint(float[] fractions, int[] pixels, int x1, int y1, int x2, int y2, int numStops, int cycleMethod, boolean useMask, boolean linear, int m00, int m01, int m02, int m10, int m11, int m12);
++
++	private static TexturePaint setTexturePaint(SunGraphics2D sg2d, TexturePaint paint, boolean useMask)
++	{
++		BufferedImage bi = paint.getImage();
++		SurfaceData dstData = sg2d.surfaceData;
++		SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
++
++		// REMIND: this hack tries to ensure that we have a cached texture
++		if (!(srcData instanceof XRSurfaceData))
++		{
++			srcData = dstData.getSourceSurfaceData(paint.getImage(), SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
++			if (!(srcData instanceof XRSurfaceData))
++			{
++				return null;
++			}
++		}
++
++		XRSurfaceData x11SrcData = (XRSurfaceData) srcData;
++
++		validatedTextureInterpolation = sg2d.interpolationType;
++		XRSetFilter(x11SrcData.getNativeOps(), XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
++
++		AffineTransform at = (AffineTransform) sg2d.transform.clone();
++		Rectangle2D anchor = paint.getAnchorRect();
++		at.translate(anchor.getX(), anchor.getY());
++		at.scale(anchor.getWidth() / ((double) bi.getWidth()), anchor.getHeight() / ((double) bi.getHeight()));
++		try
++		{
++			at.invert();
++		} catch (NoninvertibleTransformException ex)
++		{
++			ex.printStackTrace();
++		}
++
++		x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType)); /*Todo - doesn't work if interpolation value is changed after texturepaint is "realized"*/
++
++		XRSetTexturePaint(srcData.getNativeOps());
++
++		return paint;
++	}
++
++	public void setPaint(SunGraphics2D sg2d, Paint paint)
++	{
++		if (sg2d != null)
++		{
++			if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR)
++			{
++				XRResetPaint();
++			} else
++			{
++				switch (sg2d.paintState)
++				{
++					case SunGraphics2D.PAINT_GRADIENT:
++						setGradientPaint(sg2d, (GradientPaint) paint, false);
++						validatedPaint = paint;
++						break;
++
++					case SunGraphics2D.PAINT_LIN_GRADIENT:
++						setLinearGradientPaint(sg2d, (LinearGradientPaint) paint, false);
++						validatedPaint = paint;
++						break;
++
++					case SunGraphics2D.PAINT_RAD_GRADIENT:
++						setRadialGradientPaint(sg2d, (RadialGradientPaint) paint);
++						validatedPaint = paint;
++						break;
++
++					case SunGraphics2D.PAINT_TEXTURE:
++						validatedPaint = setTexturePaint(sg2d, (TexturePaint) paint, false);
++						break;
++
++					default:
++						throw new InternalError("should not reach");
++				}
++			}
++		}
++	}
++
++	public void validate(Region clip, Composite comp, AffineTransform xform, Paint paint, SunGraphics2D sg2d, int flags)
++	{
++		boolean updateClip = (clip != validatedClip);
++		boolean updatePaint = (paint != validatedPaint) || paint == null;
++
++		if (!isValid())
++		{
++			throw new InvalidPipeException("bounds changed");
++		}
++
++		// validate clip
++		if (updateClip)
++		{
++			if (clip != null)
++			{
++				XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
++			} else
++			{
++				XRResetClip(getNativeOps());
++			}
++			validatedClip = clip;
++		}
++
++		// validate composite (note that a change in the context flags
++		// may require us to update the composite state, even if the
++		// composite has not changed)
++		if ((comp != validatedComp) || (flags != validatedFlags))
++		{
++			if (comp != null)
++			{
++				setComposite(comp);
++			} else
++			{
++				comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
++				setComposite(comp);
++			}
++			// the paint state is dependent on the composite state, so make
++			// sure we update the color below
++			updatePaint = true;
++			validatedComp = comp;
++			validatedFlags = flags;
++		}
++
++		if (sg2d != null && validatedPixel != sg2d.pixel)
++		{
++			validatedPixel = sg2d.pixel;
++			XRSetForeground(validatedPixel);
++		}
++
++		// validate paint
++		if (updatePaint)
++		{
++			if (paint != null)
++			{
++				setPaint(sg2d, paint);
++			} else
++			{
++				XRResetPaint();
++			}
++			validatedPaint = paint;
++		}
++	}
++
++	long xgc;
++
++	public void makePipes()
++	{
++		if (x11pipe == null)
++		{
++			try
++			{
++				SunToolkit.awtLock();
++				xgc = XCreateGC(getNativeOps());
++
++				x11pipe = XRRenderer.getInstance();
++				x11txpipe = new PixelToShapeConverter(x11pipe);
++				x11textpipe = new XRTextRenderer();
++				xrDrawImage = new XRDrawImage();
++			} finally
++			{
++				SunToolkit.awtUnlock();
++			}
++		}
++	}
++
++	public static class XRWindowSurfaceData extends XRSurfaceData
++	{
++		public XRWindowSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, SurfaceType sType)
++		{
++			super(peer, gc, sType, peer.getColorModel(), peer.getColorModel().getPixelSize(), Transparency.OPAQUE);
++
++			if (isDrawableValid())
++			{
++				initXRender(XRUtils.getPictureFormatForTransparency(Transparency.OPAQUE));
++				makePipes();
++			}
++		}
++
++		public SurfaceData getReplacement()
++		{
++			return peer.getSurfaceData();
++		}
++
++		public Rectangle getBounds()
++		{
++			Rectangle r = peer.getBounds();
++			r.x = r.y = 0;
++			return r;
++		}
++
++		@Override
++		public boolean canSourceSendExposures(int x, int y, int w, int h)
++		{
++			return true;
++		}
++
++		/**
++		 * Returns destination Component associated with this SurfaceData.
++		 */
++		public Object getDestination()
++		{
++			return peer.getTarget();
++		}
++	}
++
++	public static class XRPixmapSurfaceData extends XRSurfaceData
++	{
++		Image offscreenImage;
++		int width;
++		int height;
++		int transparency;
++
++		public XRPixmapSurfaceData(XRGraphicsConfig gc, int width, int height, Image image, SurfaceType sType, ColorModel cm, long drawable, int transparency, int pictFormat, int depth)
++		{
++			super(null, gc, sType, cm, depth, transparency);
++			this.width = width;
++			this.height = height;
++			offscreenImage = image;
++			this.transparency = transparency;
++			initSurface(depth, width, height, drawable, pictFormat);
++			makePipes();
++		}
++
++		public void initSurface(int depth, int width, int height, long drawable, int pictFormat)
++		{
++			try
++			{
++				SunToolkit.awtLock();
++				XRInitSurface(depth, width, height, drawable, pictFormat);
++			} finally
++			{
++				SunToolkit.awtUnlock();
++			}
++		}
++
++		public SurfaceData getReplacement()
++		{
++			return restoreContents(offscreenImage);
++		}
++
++		/**
++		 * Need this since the surface data is created with
++		 * the color model of the target GC, which is always
++		 * opaque. But in SunGraphics2D.blitSD we choose loops
++		 * based on the transparency on the source SD, so
++		 * it could choose wrong loop (blit instead of blitbg,
++		 * for example).
++		 */
++		public int getTransparency()
++		{
++			return transparency;
++		}
++
++		public Rectangle getBounds()
++		{
++			return new Rectangle(width, height);
++		}
++
++		@Override
++		public boolean canSourceSendExposures(int x, int y, int w, int h)
++		{
++			return (x < 0 || y < 0 || (x + w) > width || (y + h) > height);
++		}
++
++		public void flush()
++		{
++			/*
++			 * We need to invalidate the surface before disposing the
++			 * native Drawable and GC.  This way if an application tries
++			 * to render to an already flushed X11SurfaceData, we will notice
++			 * in the validate() method above that it has been invalidated,
++			 * and we will avoid using those native resources that have
++			 * already been disposed.
++			 */
++			invalidate();
++			flushNativeSurface();
++		}
++
++		/**
++		 * Returns destination Image associated with this SurfaceData.
++		 */
++		public Object getDestination()
++		{
++			return offscreenImage;
++		}
++	}
++
++	private static LazyPipe lazypipe = new LazyPipe();
++
++	public static class LazyPipe extends ValidatePipe
++	{
++		public boolean validate(SunGraphics2D sg2d)
++		{
++			XRSurfaceData xsd = (XRSurfaceData) sg2d.surfaceData;
++			if (!xsd.isDrawableValid())
++			{
++				return false;
++			}
++			xsd.makePipes();
++			return super.validate(sg2d);
++		}
++	}
++}
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,103 @@
++/*
++ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++package sun.java2d.xr;
++
++import java.awt.Color;
++import java.awt.AlphaComposite;
++import java.awt.GraphicsConfiguration;
++import java.awt.Transparency;
++import java.awt.image.ColorModel;
++import java.awt.image.IndexColorModel;
++import java.awt.image.DirectColorModel;
++
++import sun.awt.X11GraphicsConfig;
++import sun.java2d.SurfaceData;
++import sun.java2d.SurfaceDataProxy;
++import sun.java2d.SunGraphics2D;
++import sun.java2d.loops.SurfaceType;
++import sun.java2d.loops.CompositeType;
++import sun.java2d.opengl.*;
++
++/**
++ * The proxy class contains the logic for when to replace a
++ * SurfaceData with a cached X11 Pixmap and the code to create
++ * the accelerated surfaces.
++ */
++public class XRSurfaceDataProxy extends SurfaceDataProxy
++    implements Transparency
++{
++    public static SurfaceDataProxy createProxy(SurfaceData srcData,
++                                               XRGraphicsConfig dstConfig)
++    {
++        if (srcData instanceof XRSurfaceData) {
++            // srcData must be a VolatileImage which either matches
++            // our visual or not - either way we do not cache it...
++            return UNCACHED;
++        }
++        
++        return new XRSurfaceDataProxy(dstConfig, srcData.getTransparency());
++    }
++
++    XRGraphicsConfig xrgc;
++    int transparency;
++
++    public XRSurfaceDataProxy(XRGraphicsConfig x11gc) {
++        this.xrgc = x11gc;
++    }
++
++    @Override
++    public SurfaceData validateSurfaceData(SurfaceData srcData,
++                                           SurfaceData cachedData,
++                                           int w, int h)
++    {
++        if (cachedData == null) {
++            // Bitmask will be created lazily during the blit phase
++            cachedData = XRSurfaceData.createData(xrgc, w, h,
++                                                   xrgc.getColorModel(),
++                                                   null, 0, getTransparency());
++        }
++        return cachedData;
++    }
++    
++    public XRSurfaceDataProxy(XRGraphicsConfig x11gc, int transparency) {
++        this.xrgc = x11gc;
++        this.transparency = transparency;
++    }
++
++    @Override
++    public boolean isSupportedOperation(SurfaceData srcData,
++                                        int txtype,
++                                        CompositeType comp,
++                                        Color bgColor)
++    {
++        return (bgColor == null || transparency == Transparency.OPAQUE);
++    }
++
++	public int getTransparency()
++	{
++		return transparency;
++	}
++}
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,142 @@
++package sun.java2d.xr;
++
++import static java.awt.AlphaComposite.*;
++
++import java.awt.*;
++import java.awt.MultipleGradientPaint.*;
++import java.awt.image.*;
++
++public class XRUtils
++{
++	/*Composition Operators*/
++	public static final int PictOpClear = 0;
++	public static final int PictOpSrc = 1;
++	public static final int PictOpDst = 2;
++	public static final int PictOpOver = 3;
++	public static final int PictOpOverReverse = 4;
++	public static final int PictOpIn = 5;
++	public static final int PictOpInReverse = 6;
++	public static final int PictOpOut = 7;
++	public static final int PictOpOutReverse = 8;
++	public static final int PictOpAtop = 9;
++	public static final int PictOpAtopReverse = 10;
++	public static final int PictOpXor = 11;
++	public static final int PictOpAdd = 12;
++	public static final int PictOpSaturate = 13;
++
++	/*Repeats*/
++	public static final int RepeatNone = 0;
++	public static final int RepeatNormal = 1;
++	public static final int RepeatPad = 2;
++	public static final int RepeatReflect = 3;
++	
++	/*Interpolation qualities*/
++	public static final int FAST = 0;
++	public static final int GOOD = 1;
++	public static final int BEST = 2;
++	
++	/*PictFormats*/
++	public static final int PictStandardARGB32 = 0;
++	public static final int PictStandardRGB24 = 1;
++	public static final int PictStandardA8 = 2;
++	public static final int PictStandardA4 = 3;
++	public static final int PictStandardA1 = 4;
++	
++	public static int ATransOpToXRQuality(int affineTranformOp)
++	{
++		switch(affineTranformOp)
++		{
++			case AffineTransformOp.TYPE_NEAREST_NEIGHBOR:
++				return FAST;
++				
++			case AffineTransformOp.TYPE_BILINEAR:
++				return GOOD;
++				
++			case AffineTransformOp.TYPE_BICUBIC:
++				return BEST;
++		}
++		
++		return -1;
++	}
++	
++	public static int getPictureFormatForTransparency(int transparency)
++	{ 
++		switch(transparency)
++		{
++			case Transparency.OPAQUE:
++				return PictStandardRGB24;
++				
++			case Transparency.BITMASK:
++			case Transparency.TRANSLUCENT:
++				return PictStandardARGB32;
++		}
++		
++		return -1;
++	}
++
++	public static int getRepeatForCycleMethod(CycleMethod cycleMethod)
++	{
++		if (cycleMethod.equals(CycleMethod.NO_CYCLE))
++		{
++			return RepeatPad;
++		} else if (cycleMethod.equals(CycleMethod.REFLECT))
++		{
++			return RepeatReflect;
++		} else if (cycleMethod.equals(CycleMethod.REPEAT))
++		{
++			return RepeatNormal;
++		}
++
++		return RepeatNone;
++	}
++
++	public static int XDoubleToFixed(double dbl)
++	{
++		return (int) (dbl * 65536);
++	}
++
++	public static int j2dAlphaCompToXR(int j2dRule)
++	{
++		switch (j2dRule)
++		{
++			case CLEAR:
++				return PictOpClear;
++
++			case SRC:
++				//return PictOpOver;
++				return PictOpSrc;
++
++			case DST:
++				return PictOpDst;
++
++			case SRC_OVER:
++				return PictOpOver;
++
++			case DST_OVER:
++				return PictOpOverReverse;
++
++			case SRC_IN:
++				return PictOpIn;
++
++			case DST_IN:
++				return PictOpInReverse;
++
++			case SRC_OUT:
++				return PictOpOut;
++
++			case DST_OUT:
++				return PictOpOutReverse;
++
++			case SRC_ATOP:
++				return PictOpAtop;
++
++			case DST_ATOP:
++				return PictOpAtopReverse;
++
++			case XOR:
++				return PictOpXor;
++		}
++
++		throw new InternalError("No XRender equivalent available for requested java2d composition rule");
++	}
++}
+diff -r dc592ff5af5e jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,105 @@
++/*
++ * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++package sun.java2d.xr;
++
++import java.awt.GraphicsConfiguration;
++import java.awt.ImageCapabilities;
++import java.awt.Transparency;
++import java.awt.image.ColorModel;
++import sun.awt.X11GraphicsConfig;
++import sun.awt.image.SunVolatileImage;
++import sun.awt.image.VolatileSurfaceManager;
++import sun.java2d.SurfaceData;
++
++/**
++ * X11 platform implementation of the VolatileSurfaceManager class.
++ * The class attempts to create and use a pixmap-based SurfaceData
++ * object (X11PixmapSurfaceData).
++ * If this object cannot be created or re-created as necessary, the
++ * class falls back to a system memory based SurfaceData object
++ * (BufImgSurfaceData) that will be used until the accelerated
++ * SurfaceData can be restored.
++ */
++public class XRVolatileSurfaceManager extends VolatileSurfaceManager {
++
++    public XRVolatileSurfaceManager(SunVolatileImage vImg, Object context) {
++        super(vImg, context);
++    }
++
++    protected boolean isAccelerationEnabled() {
++        return true;
++    }
++
++    /**
++     * Create a pixmap-based SurfaceData object
++     */
++    protected SurfaceData initAcceleratedSurface() {
++        SurfaceData sData;
++
++        try {
++            XRGraphicsConfig gc = (XRGraphicsConfig) vImg.getGraphicsConfig();
++            ColorModel cm = gc.getColorModel();
++            long drawable = 0;
++            if (context instanceof Long) {
++                drawable = ((Long)context).longValue();
++            }
++            sData = XRSurfaceData.createData(gc,
++                                              vImg.getWidth(),
++                                              vImg.getHeight(),
++                                              cm, vImg, drawable,
++                                              vImg.getTransparency());
++        } catch (NullPointerException ex) {
++            sData = null;
++        } catch (OutOfMemoryError er) {
++            sData = null;
++        }
++
++        return sData;
++    }
++
++    protected boolean isConfigValid(GraphicsConfiguration gc) {
++        // REMIND: we might be too paranoid here, requiring that
++        // the GC be exactly the same as the original one.  The
++        // real answer is one that guarantees that pixmap copies
++        // will be correct (which requires like bit depths and
++        // formats).
++        return ((gc == null) || (gc == vImg.getGraphicsConfig()));
++    }
++
++    /**
++     * Need to override the default behavior because Pixmaps-based
++     * images are accelerated but not volatile.
++     */
++    @Override
++    public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
++        if (isConfigValid(gc) && isAccelerationEnabled()) {
++            // accelerated but not volatile
++            return new ImageCapabilities(true);
++        }
++        // neither accelerated nor volatile
++        return new ImageCapabilities(false);
++    }
++}
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/font/XRTextRenderer.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/font/XRTextRenderer.c	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,77 @@
++/*
++ * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++/*
++ * Important note : All AWTxxx functions are defined in font.h.
++ * These were added to remove the dependency of this file on X11.
++ * These functions are used to perform X11 operations and should
++ * be "stubbed out" in environments that do not support X11.
++ * The implementation of these functions has been moved from this file
++ * into X11TextRenderer_md.c, which is compiled into another library.
++ */
++
++#include "sun_font_X11TextRenderer.h"
++
++#include "Region.h"
++#include "SurfaceData.h"
++#include "GraphicsPrimitiveMgr.h"
++#include "glyphblitting.h"
++#include <malloc.h>
++#include "Trace.h"
++
++
++JNIEXPORT void JNICALL XRT_DrawGlyphList(JNIEnv *env, jobject xtr,
++                 jlong dstData, jint numGlyphs, jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
++                 jboolean usePositions, jfloat xOrigin, jfloat yOrigin, jlong *images, jfloat *positions);
++
++
++
++JNIEXPORT void JNICALL Java_sun_font_XRTextRenderer_doDrawGlyphList (JNIEnv *env, jobject xtr,
++     jlong dstData, jint numGlyphs, jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
++     jboolean usePositions, jfloat xOrigin, jfloat yOrigin, jlongArray imgArray, jfloatArray posArray)
++{
++    jlong *images;
++
++    J2dTraceLn(J2D_TRACE_INFO, "XRTextRenderer_drawGlyphList");
++
++    images = (jlong *) (*env)->GetPrimitiveArrayCritical(env, imgArray, NULL);
++    if (images != NULL) {
++
++        if (usePositions == JNI_TRUE) {
++            jfloat *positions = (jfloat *) (*env)->GetPrimitiveArrayCritical(env, posArray, NULL);
++
++            if (positions != NULL) {
++                XRT_DrawGlyphList(env, xtr, dstData, numGlyphs, subPixPos, rgbOrder, lcdContrast, usePositions, xOrigin, yOrigin, images, positions);
++                (*env)->ReleasePrimitiveArrayCritical(env, posArray,
++                                                      positions, JNI_ABORT);
++            }
++        } else {
++            XRT_DrawGlyphList(env, xtr, dstData, numGlyphs, subPixPos, rgbOrder, lcdContrast, usePositions, xOrigin, yOrigin, images, NULL);
++        }
++
++        (*env)->ReleasePrimitiveArrayCritical(env, imgArray,
++                                              images, JNI_ABORT);
++    }
++}
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/ArrayList.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.c	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,39 @@
++#include <malloc.h>
++#include <string.h>
++#include "ArrayList.h"
++
++void initXRList(XrArrayList *list, jint capacity, size_t blkSize)
++{
++  //printf("Init XR LIst!\n");fflush(stdout);
++  list->used = 0;
++  list->capacity = capacity;
++
++  if(capacity != 0) {
++    list->elements = calloc(capacity, blkSize);
++  }else {
++    list->elements = NULL;
++  }
++}
++
++void* getNewXR(XrArrayList *list, size_t blkSize)
++{
++  if((list->used+1) >= list->capacity)
++  {
++    int newCapacity = list->capacity*2 + 10;
++    if(list->capacity > 0) {
++      list->elements = realloc(list->elements, newCapacity * blkSize);
++    }else {
++      list->elements = calloc(newCapacity, blkSize);
++    }
++    list->capacity = newCapacity;
++  }
++
++  return list->elements + (list->used++ * blkSize);
++}
++
++void clearXRList(XrArrayList *list)
++{
++  list->used = 0;
++  //memset(list->elements, 0, list->used);
++}
++
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/ArrayList.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.h	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,18 @@
++#ifndef ArrayList_h_Included
++#define ArrayList_h_Included
++
++#include "jni.h"
++
++typedef struct {
++   void *elements;
++   jint capacity;
++   jint used;
++} XrArrayList;
++
++void initXRList(XrArrayList *list, jint capacity, size_t blkSize);
++
++void* getNewXR(XrArrayList *list, size_t blkSize);
++
++void clearXRList(XrArrayList *list);
++
++#endif /* ArrayList_h_Included */
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,576 @@
++#include "MaskBuffer.h"
++#include "XRSurfaceData.h"
++#include "X11SurfaceData.h"
++
++#define MAX(a,b) ((a) > (b) ? (a) : (b))
++#define MIN(a,b) ((a) < (b) ? (a) : (b))
++
++#define GET_DIRTY_LINE_REGION(X1, Y1, X2, Y2, RX1, RY1, RX2, RY2)        \
++  {                                                                      \
++    if(X1 < X2) {                                                        \
++      RX1 = X1;                                                          \
++      RX2 = X2;                                                          \
++    }else {                                                              \
++      RX1 = X2;                                                          \
++      RX2 = X1;                                                          \
++    }                                                                    \
++                                                                         \
++    if(Y1 < Y2) {                                                        \
++      RY1 = Y1;                                                          \
++      RY2 = Y2;                                                          \
++    }else {                                                              \
++      RY1 = Y2;                                                          \
++      RY2 = Y1;                                                          \
++    }                                                                    \
++  }
++
++#ifndef HEADLESS
++MaskBuffer* initMaskBuffer(Window window)
++{
++  MaskBuffer *buffer = malloc(sizeof(MaskBuffer));
++  initRegion(&buffer->region);
++ 
++  initXRList(&buffer->rects, sizeof(XRectangle), 512);
++  initXRList(&buffer->lines, sizeof(XSegment), 512);
++
++  buffer->xTiles = 0;
++  buffer->yTiles = 0;
++  buffer->xTileCap = 0;
++  buffer->yTileCap = 0;
++  buffer->tiles = NULL;
++
++  XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, PictStandardA8);
++  XRenderPictFormat *fmt32 = XRenderFindStandardFormat(awt_display, PictStandardARGB32);
++
++  buffer->maskPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 8);
++  buffer->lineMaskPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 8);
++  buffer->gradPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 32);
++ 
++  XRenderPictureAttributes pict_attr;
++  buffer->maskPicture = XRenderCreatePicture(awt_display, buffer->maskPixmap, fmt, 0, &pict_attr);
++  buffer->lineMaskPicture = XRenderCreatePicture(awt_display, buffer->lineMaskPixmap, fmt, 0, &pict_attr);
++  buffer->gradPict = XRenderCreatePicture(awt_display, buffer->gradPixmap, fmt32, 0, &pict_attr);
++
++  XRenderColor color_black={.red=0, .green=0, .blue=0, .alpha=0xffff};
++  XRenderFillRectangle (awt_display, PictOpClear, buffer->maskPicture, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
++  XRenderFillRectangle (awt_display, PictOpClear, buffer->lineMaskPicture, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
++  XRenderFillRectangle (awt_display, PictOpClear, buffer->gradPict, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
++
++  buffer->validatedGCAlpha = 1.0f;
++  XGCValues values;
++  values.foreground = 255;
++  buffer->drawLineGC = XCreateGC(awt_display, buffer->lineMaskPixmap, GCForeground, &values);
++  /*Invisible GC for readback assistance*/
++  values.foreground = 0;
++  buffer->clearLineGC = XCreateGC(awt_display, buffer->lineMaskPixmap, GCForeground, &values);
++
++  return buffer;
++}
++
++static void allocTileBuffer(MaskBuffer* buf)
++{
++  buf->xTiles = ((buf->region.x2 - buf->region.x) / MASK_TILE_SIZE) + 1;
++  buf->yTiles = ((buf->region.y2 - buf->region.y) / MASK_TILE_SIZE) + 1;
++
++  //If current tile-array is too small, allocate a larger one
++  if(buf->tiles == NULL || buf->xTileCap < buf->xTiles || buf->yTileCap < buf->yTiles) {
++    buf->xTileCap = MAX((buf->xTiles * 2), buf->xTileCap);
++    buf->yTileCap = MAX((buf->yTiles * 2), buf->yTileCap);
++    if(buf->tiles != NULL) {
++      free(buf->tiles);
++    }
++    buf->tiles = calloc(buf->xTileCap * buf->yTileCap, sizeof(XrTile));
++  }
++
++  //Init/Reset the tiles that will be used later
++  int x,y;
++  for(y=0; y < buf->yTiles; y++) {
++    for(x=0; x < buf->xTiles; x++) {
++      initXrTile(&buf->tiles[y*buf->xTileCap + x]);
++    }
++ }
++}
++
++static void cleanMaskBuffer(MaskBuffer *buf)
++{
++  initRegion(&buf->region); //TODO: eigentlich nicht noetig
++  buf->xTiles = 0;
++  buf->yTiles = 0;
++  clearXRList(&buf->rects);
++  clearXRList(&buf->lines);
++}
++
++static void getTileDirtyArea(MaskRegion *dirtyRectArea, MaskRegion *dirtyLineArea, MaskRegion *totalDirtyArea)
++{
++  totalDirtyArea->x = MIN(dirtyRectArea->x, dirtyLineArea->x);
++  totalDirtyArea->y = MIN(dirtyRectArea->y, dirtyLineArea->y);
++  totalDirtyArea->x2 = MAX(dirtyRectArea->x2, dirtyLineArea->x2);
++  totalDirtyArea->y2 = MAX(dirtyRectArea->y2, dirtyLineArea->y2);
++}
++
++/**
++* Grows the dirty region of the tile.
++* This allows to log which areas of the mask are used, and only do Composition
++* with the parts that are really occupied.
++*/
++static void growDirtyRegion(MaskRegion *region, jint x, jint y, jint x2, jint y2)
++{
++  if(x < region->x){
++    region->x = x;
++  }
++  if(y < region->y) {
++    region->y = y;
++  }
++  if(x2 > region->x2){ 
++    region->x2 = x2;
++  }
++  if(y2 > region->y2){
++    region->y2 = y2;
++  }
++}
++
++static void growDirtyRegionTileLimit(MaskRegion *region, jint x, jint y, jint x2, jint y2)
++{
++  if(x < region->x){
++    region->x = MAX(x, 0);
++  }
++  if(y < region->y) {
++    region->y = MAX(y, 0);
++  }
++  if(x2 > region->x2){ 
++    region->x2 = MIN(x2, MASK_TILE_SIZE);
++  }
++  if(y2 > region->y2){
++    region->y2 = MIN(y2, MASK_TILE_SIZE);
++  }
++}
++
++/**
++* Limits the rect's coordinates to the mask coordinates.
++* The result is used by growDirtyRegion.
++*/
++static void limitRetcCoords(XRectangle *rect) 
++{
++   if((rect->x + rect->width) > MASK_TILE_SIZE) {
++      rect->width = MASK_TILE_SIZE - rect->x;
++   }
++   if((rect->y + rect->height) > MASK_TILE_SIZE) {
++      rect->height = MASK_TILE_SIZE - rect->y;
++   }
++
++  if(rect->x < 0){
++    rect->width += rect->x;
++    rect->x = 0;
++  }
++  if(rect->y < 0) {
++     rect->height += rect->y;
++     rect->y = 0;
++  }
++}
++
++static void initRegion(MaskRegion *region)
++{
++  region->x = 99999;
++  region->y = 99999;
++  region->x2 = -99999;
++  region->y2 = -99999;
++}
++
++void addRect(MaskBuffer* buf, short x, short y, unsigned short w, unsigned short h)
++{
++  XRectangle *rect = (XRectangle*) getNewXR(&buf->rects, sizeof(XRectangle));
++  rect->x = x;
++  rect->y = y;
++  rect->width = w;
++  rect->height = h;
++
++  growDirtyRegion(&buf->region, x, y, x+w, y+h);
++}
++
++void addLine(MaskBuffer* buf, int x1, int y1, int x2, int y2)
++{
++  /* EXA tries to accalerate lines which can be rendered with a single fillRect.
++   * Unfourtunatly EXA is a bit dumb because our image is held in sysmem all the time anyway.
++   * So although it would be pretty cheap in sysmem, it migrates the mask to vram just to do a single accalerated fillRect.
++   * This should really be fixed in EXA, I hope I get it done sometimes.
++   *
++   * We seperate rect/line rendering to not cause exzessive migration, therefor we simple add that "line" to our rects.
++   */
++
++  int minX, minY, maxX, maxY;
++  GET_DIRTY_LINE_REGION(x1, y1, x2, y2, minX, minY, maxX, maxY); 
++  int xDiff = maxX - minX;
++  int yDiff = maxY - minY;
++
++   if(xDiff == 0 || yDiff == 0)
++   {
++     addRect(buf, minX, minY, maxX - minX + 1, maxY - minY + 1);
++   }else
++   if(xDiff == 1 && yDiff == 1)
++   {
++     addRect(buf, x1, y1, 1, 1);
++     addRect(buf, x2, y2, 1, 1);
++   } else 
++   {
++     XSegment *line = (XSegment*) getNewXR(&buf->lines, sizeof(XSegment));
++     line->x1 = x1;
++     line->y1 = y1;
++     line->x2 = x2;
++     line->y2 = y2;
++ 
++     growDirtyRegion(&buf->region, minX, minY, maxX + 1, maxY + 1);
++  }
++}
++
++static void initXrTile(XrTile *tile)
++{
++  initRegion(&tile->dirtyLineArea);
++  initRegion(&tile->dirtyRectArea);
++  clearXRList(&tile->rects);
++  clearXRList(&tile->lines);
++}
++
++static void storeLinesInTiles(MaskBuffer *buf)
++{
++  int i,n,m;
++
++  for(i=0; i < buf->lines.used; i++) {
++     XSegment *line = ((XSegment*) buf->lines.elements) + i; 
++
++     line->x1 -= buf->region.x;
++     line->y1 -= buf->region.y;
++     line->x2 -= buf->region.x;
++     line->y2 -= buf->region.y;
++
++    int minX, minY, maxX, maxY;
++    GET_DIRTY_LINE_REGION(line->x1, line->y1, line->x2, line->y2, minX, minY, maxX, maxY);
++
++     int tileXStartIndex = minX / MASK_TILE_SIZE;
++     int tileYStartIndex = minY / MASK_TILE_SIZE;
++     int tileXLenght = (maxX / MASK_TILE_SIZE + 1) - tileXStartIndex;
++     int tileYLenght = (maxY / MASK_TILE_SIZE + 1) - tileYStartIndex;
++
++      /*TODO: Better coverage analysis should really pay off for lines!*/
++      for(n=0; n < tileYLenght; n++) {
++        for(m=0; m < tileXLenght; m++) { /*Coverage indicator: Simply do not add to not covered tiles*/
++          int tileIndex = (buf->xTileCap * (tileYStartIndex + n)) + tileXStartIndex + m;
++          assert(tileIndex >= 0 && tileIndex < (buf->xTileCap*buf->yTileCap));
++          XrTile *tile = &buf->tiles[tileIndex];
++          XSegment *tileLine = (XSegment*) getNewXR(&tile->lines, sizeof(XSegment));
++
++          int tileStartPosX = (tileXStartIndex + m) * MASK_TILE_SIZE;
++          int tileStartPosY = (tileYStartIndex + n) * MASK_TILE_SIZE;
++
++          tileLine->x1 = line->x1 - tileStartPosX; //Translate coordinates relative to the mask-location
++          tileLine->y1 = line->y1 - tileStartPosY;
++          tileLine->x2 = line->x2 - tileStartPosX;
++          tileLine->y2 = line->y2 - tileStartPosY; 
++
++          int transminX = minX - tileStartPosX;
++          int transminY = minY - tileStartPosY;
++          int transmaxX = maxX - tileStartPosX;
++          int transmaxY = maxY - tileStartPosY;
++
++          growDirtyRegionTileLimit(&tile->dirtyLineArea, transminX,  transminY, transmaxX + 1, transmaxY + 1);
++       }
++     }
++  }
++}
++
++static void storeRectsInTiles(MaskBuffer *buf)
++{
++  int i,n,m;
++
++  for(i=0; i < buf->rects.used; i++) {
++     XRectangle *rect = ((XRectangle*) buf->rects.elements) + i; 
++
++     rect->x -= buf->region.x;
++     rect->y -= buf->region.y;
++
++     int tileXStartIndex = rect->x / MASK_TILE_SIZE;
++     int tileYStartIndex = rect->y / MASK_TILE_SIZE;
++     int tileXLenght = ((rect->x + rect->width) / MASK_TILE_SIZE + 1) - tileXStartIndex;
++     int tileYLenght = ((rect->y + rect->height) / MASK_TILE_SIZE + 1) - tileYStartIndex;
++
++      for(n=0; n < tileYLenght; n++) {
++        for(m=0; m < tileXLenght; m++) {
++          int tileIndex = (buf->xTileCap * (tileYStartIndex + n)) + tileXStartIndex + m;
++          assert(tileIndex >= 0 && tileIndex < (buf->xTileCap*buf->yTileCap));
++          //printf("Index: %d - tileX:%d, tileY:%d, tilesx:%d, tilesy:%d, capx:%d capy:%d\n",tileIndex,  (m + tileXLenght), (n + tileYStartIndex), buf->xTiles, buf->yTiles, buf->xTileCap, buf->yTileCap);fflush(stdout);
++          XrTile *tile = &buf->tiles[tileIndex];
++          XRectangle *tileRect = (XRectangle*) getNewXR(&tile->rects, sizeof(XRectangle));
++
++          int tileStartPosX = (tileXStartIndex + m) * MASK_TILE_SIZE;
++          int tileStartPosY = (tileYStartIndex + n) * MASK_TILE_SIZE;
++
++          tileRect->x = rect->x - tileStartPosX; //Translate coordinates relative to the mask-location
++          tileRect->y = rect->y - tileStartPosY;
++          tileRect->width = rect->width;
++          tileRect->height = rect->height; 
++
++          limitRetcCoords(tileRect);
++          growDirtyRegion(&tile->dirtyRectArea, tileRect->x, tileRect->y, tileRect->x + tileRect->width, tileRect->y + tileRect->height);
++       }
++     }
++  }
++}
++
++static void translateRects(XrArrayList *rectList, int x, int y)
++{
++  int i;
++  for(i = 0; i < rectList->used; i++) {
++      XRectangle *rect = ((XRectangle *) rectList->elements) + i;
++      rect->x += x;
++      rect->y += y;
++   }
++}
++
++void fillMask(MaskBuffer* buf, Picture dest)
++{
++  XRenderColor color_black={.red=0, .green=0, .blue=0, .alpha=0xffff};
++  int i, m, n;
++
++  jboolean maskRequired = (xrSrcData.src != xrSrcData.solid) || (xrSrcData.solidColor.alpha != 0xffff) || (xrSrcData.extraAlpha != 1.0f);
++  /*Extra Alpha is already storen in solid-colo*/
++  jdouble maskAlpha = (xrSrcData.src == xrSrcData.solid) ? 1.0f : xrSrcData.extraAlpha;
++
++  unsigned short alphaValueFixed = XDoubleToUShort(maskAlpha);
++  XRenderColor maskColor;
++  maskColor.alpha = alphaValueFixed;
++
++  /* If we don't have to use a mask and there are no lines, 
++   * we can draw the rects directly and omit tile partitioning */
++  if(maskRequired || buf->lines.used > 0) {
++  allocTileBuffer(buf);
++  storeRectsInTiles(buf);
++  storeLinesInTiles(buf);
++
++  if(buf->lines.used > 0 && buf->validatedGCAlpha != maskAlpha) {
++     buf->validatedGCAlpha = maskAlpha;
++     XSetForeground(awt_display, buf->drawLineGC, (int) (buf->validatedGCAlpha*255));
++  }
++
++  for(i=0; i < buf->yTiles; i++) {
++   for(m=0; m < buf->xTiles; m++) {
++       XrTile *tile = &buf->tiles[i*buf->xTileCap + m];
++       XrArrayList *rectList = &tile->rects;
++       XrArrayList *lineList = &tile->lines;
++
++       if(rectList->used != 0 || lineList->used != 0) {
++	  MaskRegion tileDirtyArea;
++          getTileDirtyArea(&tile->dirtyRectArea, &tile->dirtyLineArea, &tileDirtyArea);
++
++          int tileStartX = m * MASK_TILE_SIZE;
++          int tileStartY = i * MASK_TILE_SIZE;
++          int x = tileDirtyArea.x + tileStartX + buf->region.x;
++          int y = tileDirtyArea.y + tileStartY + buf->region.y;
++          int width = tileDirtyArea.x2 - tileDirtyArea.x;
++          int height = tileDirtyArea.y2 - tileDirtyArea.y;
++          width = MIN(width, MASK_TILE_SIZE);
++          height = MIN(height, MASK_TILE_SIZE);
++
++	  if(maskRequired || lineList->used  > 0) /*Again, only composite _current_tile_ if required, otherwise just fill rects*/
++          {
++            Picture mask = None;
++            if(lineList->used != 0) {
++              XDrawSegments(awt_display, buf->lineMaskPixmap, buf->drawLineGC, (XSegment *) lineList->elements, lineList->used);
++              mask = buf->lineMaskPicture;
++            }
++
++            if(rectList->used != 0) {
++               XRenderComposite (awt_display, PictOpSrc, buf->lineMaskPicture, None, buf->maskPicture, tile->dirtyLineArea.x, tile->dirtyLineArea.y, 0, 0, tile->dirtyLineArea.x, tile->dirtyLineArea.y, (tile->dirtyLineArea.x2 - tile->dirtyLineArea.x), (tile->dirtyLineArea.y2 - tile->dirtyLineArea.y)); 
++               XRenderFillRectangles (awt_display, PictOpSrc, buf->maskPicture, &maskColor, (XRectangle*) rectList->elements, rectList->used);
++               mask = buf->maskPicture;
++               clearXRList(rectList);
++            }
++
++             XRComposite(mask, dest, x, y, tileDirtyArea.x, tileDirtyArea.y, x, y, width, height);
++
++             /*Clear dirty rectangle of the rect-mask*/
++             XRenderFillRectangle (awt_display, PictOpClear, buf->maskPicture, &color_black, tileDirtyArea.x, tileDirtyArea.y, width, height);
++
++             if(lineList->used != 0) {
++               XDrawSegments(awt_display, buf->lineMaskPixmap, buf->clearLineGC, (XSegment *) lineList->elements, lineList->used);
++               clearXRList(lineList);
++	     }
++          }else
++          if(rectList->used != 0)
++          {
++             translateRects(rectList, (tileStartX + buf->region.x), (tileStartY + buf->region.y));
++             XRenderFillRectangles (awt_display, xrSrcData.compRule, dest, &xrSrcData.solidColor, (XRectangle*) rectList->elements, rectList->used);
++             clearXRList(rectList);
++          }
++        }
++      }
++     }
++ } else 
++ {
++   XRenderFillRectangles (awt_display, xrSrcData.compRule, dest, &xrSrcData.solidColor, (XRectangle*) buf->rects.elements, buf->rects.used);
++ }
++
++  cleanMaskBuffer(buf);
++}
++
++#endif
++
++
++	   /*printf("Composition: x:%d y:%d width:%d height:%d, dx:%d, dy:%d\n", x, y, width, height, tileDirtyArea.x, tileDirtyArea.y);
++           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, 0, 0, MASK_TILE_SIZE, 1);
++           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, 0, MASK_TILE_SIZE-1, MASK_TILE_SIZE, 1);
++           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, 0, 0, 1, MASK_TILE_SIZE);
++           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, MASK_TILE_SIZE-1, 0, 1, MASK_TILE_SIZE);*/
++
++
++
++           /* if(xrSrcData.src == xrSrcData.gradient)
++             { 
++               XRenderComposite (awt_display, PictOpSrc, xrSrcData.gradient, None, buf->gradPict, x, y, 0, 0, 0, 0, width, height);
++               XRenderComposite (awt_display, xrSrcData.compRule, buf->gradPict, mask, dest, 0, 0, tileDirtyArea.x, tileDirtyArea.y, x, y, width, height);
++             }else 
++             {
++               XRenderComposite (awt_display, xrSrcData.compRule, xrSrcData.src, mask, dest, x, y, tileDirtyArea.x, tileDirtyArea.y, x, y, width, height);
++             }*/
++
++/*
++void addTrap(MaskBuffer* buf, XTrapezoid *xt)
++{
++  XTrapezoid *trap = (XTrapezoid*) getNewXR(&buf->traps, sizeof(XTrapezoid));
++  memcpy(trap, xt, sizeof(XTrapezoid));
++
++  int leftMin = XFixedToDouble(MIN(trap->left.p1.x, trap->left.p2.x)) - 1;
++  int rightMax = XFixedToDouble(MAX(trap->right.p2.x, trap->right.p1.x)) + 1;
++  int top = XFixedToDouble(trap->top) - 1;
++  int bottom = XFixedToDouble(trap->bottom) + 1;
++
++  growDirtyRegion(&buf->region, leftMin, top, rightMax, bottom);
++}
++*/
++
++/*void translateTrap(XTrapezoid *trap, int x, int y)
++{
++   XFixed xTrans = XDoubleToFixed(x);     
++   XFixed yTrans = XDoubleToFixed(y);
++
++   trap->left.p1.x  += xTrans;
++   trap->left.p2.x  += xTrans;
++   trap->right.p1.x += xTrans;    
++   trap->right.p2.x += xTrans;
++   trap->left.p1.y  += yTrans;
++   trap->left.p2.y  += yTrans;
++   trap->right.p1.y += yTrans;
++   trap->right.p2.y += yTrans;
++   trap->top += yTrans;
++   trap->bottom += yTrans;
++}*/
++
++/*
++void storeTrapsInTiles(MaskBuffer *buf)
++{
++  int i,n,m;
++
++  for(i=0; i < buf->traps.used; i++) {
++     XTrapezoid *trap = ((XTrapezoid*) buf->traps.elements) + i;
++     translateTrap(trap, -buf->region.x, -buf->region.y);
++
++     int leftMin = XFixedToDouble(MIN(trap->left.p1.x, trap->left.p2.x));
++     int rightMax = XFixedToDouble(MAX(trap->right.p2.x, trap->right.p1.x));
++     int top = XFixedToDouble(trap->top) - 1;
++     int bottom = XFixedToDouble(trap->bottom) + 1;
++
++     int tileXStartIndex = leftMin / MASK_TILE_SIZE;
++     int tileYStartIndex = top / MASK_TILE_SIZE;
++     int tileXLenght = ((rightMax / MASK_TILE_SIZE) + 1) - tileXStartIndex;
++     int tileYLenght = ((bottom / MASK_TILE_SIZE) + 1) - tileYStartIndex;
++
++      for(n=0; n < tileYLenght; n++) {
++        for(m=0; m < tileXLenght; m++) {
++          int tileIndex = (buf->xTileCap * (tileYStartIndex + n)) + tileXStartIndex + m;
++          assert(tileIndex >= 0);
++          XrTile *tile = &buf->tiles[tileIndex];
++
++          XTrapezoid *tileTrap = (XTrapezoid*) getNewXR(&tile->traps, sizeof(XTrapezoid));
++          memcpy(tileTrap, trap, sizeof(XTrapezoid));
++
++          int tileStartPosX = (tileXStartIndex + m) * MASK_TILE_SIZE;
++          int tileStartPosY = (tileYStartIndex + n) * MASK_TILE_SIZE;
++          translateTrap(tileTrap, -tileStartPosX, -tileStartPosY);
++
++          leftMin = XFixedToDouble(MIN(tileTrap->left.p1.x, tileTrap->left.p2.x)) - 1;
++          rightMax = XFixedToDouble(MAX(tileTrap->right.p2.x, tileTrap->right.p1.x)) + 1;
++          top = XFixedToDouble(tileTrap->top) - 1;
++          bottom = XFixedToDouble(tileTrap->bottom) + 1;
++
++         // limitRetcCoords(tileRect);
++          //TODO: Better dirty array handling
++          growDirtyRegionTileLimit(&tile->dirtyArea, leftMin, top, rightMax, bottom);
++        }
++      }
++  }
++}*/
++
++//   XrArrayList tileRectList;
++//   initXRList(&tileRectList, sizeof(XRectangle), 64); //Todo memory leak!
++// 
++//   int i, tileStartX, tileStartY;
++//   MaskRegion ditryRegion;
++// 
++//   for(tileStartX = buf->region.x; tileStartX <= buf->region.x2; tileStartX += MASK_TILE_SIZE) {
++//    int tileEndX = tileStartX + MASK_TILE_SIZE;
++// 
++//     for(tileStartY = buf->region.y; tileStartY <= buf->region.y2; tileStartY += MASK_TILE_SIZE) {
++//       int tileEndY = tileStartY + MASK_TILE_SIZE;
++//       initRegion(&ditryRegion);
++// 
++//       for(i=0; i < buf->rects.used; i++) {
++//         XRectangle *rect = ((XRectangle*) buf->rects.elements) + i;
++// 
++//         if((rect->x <= tileEndX) && ((rect->x + rect->width) > tileStartX) &&
++//            (rect->y <= tileEndY) && ((rect->y + rect->height) > tileStartY)) {
++// 	  XRectangle *ptr = (XRectangle *) getNewXR(&tileRectList);
++//           ptr->x = rect->x - tileStartX; /*Translate coordinates relative to the mask-location*/
++//           ptr->y = rect->y - tileStartY;
++//           ptr->width = rect->width;
++//           ptr->height = rect->height;
++// 
++//           limitRetcCoords(ptr);
++//           growDirtyRegion(&ditryRegion, ptr->x, ptr->y, ptr->x + ptr->width, ptr->y + ptr->height);
++//         }
++//       }
++// 
++//         if(tileRectList.used > 0) { 
++//            XRenderFillRectangles (display, PictOpSrc, mask, alphaColor, (XRectangle*) tileRectList.elements, tileRectList.used);
++//            clearXRList(&tileRectList);
++// 
++//            int x = ditryRegion.x + tileStartX;
++//            int y = ditryRegion.y + tileStartY;
++//            int width = ditryRegion.x2 - ditryRegion.x;
++//            int height = ditryRegion.y2 - ditryRegion.y;
++// 
++//            XRenderComposite (display, PictOpOver, src, mask, dest, x, y, ditryRegion.x, ditryRegion.y, x, y, width, height);
++//            XRenderFillRectangle (display, PictOpClear, mask, alphaColor, ditryRegion.x, ditryRegion.y, width, height);
++//         }
++//     } 
++//   }
++
++
++/*
++          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, MASK_TILE_SIZE, 1);
++          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, MASK_TILE_SIZE-1, MASK_TILE_SIZE, 1);
++          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, 1, MASK_TILE_SIZE);
++          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, MASK_TILE_SIZE-1, 0, 1, MASK_TILE_SIZE);
++*/
++
++//         int z;
++//         for(z=0; z < tileRectList.used; z++)
++//  {
++//      XRectangle *rect = ((XRectangle*) tileRectList.elements) + z;
++//      printf("Rechteck %d - %d %d %d %d %d\n", z, rect->x, rect->y, rect->width, rect->height, tileRectList.used);
++// }
++
++//printf("Composition rect: %d %d %d %d\n", x, y, ditryRegion.x2 - ditryRegion.x, ditryRegion.y2 - ditryRegion.y);fflush(stdout);
++          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, MASK_TILE_SIZE, 1);
++          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, MASK_TILE_SIZE-1, MASK_TILE_SIZE, 1);
++          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, 1, MASK_TILE_SIZE);
++          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, MASK_TILE_SIZE-1, 0, 1, MASK_TILE_SIZE);
++
++// printf("Rendering region: %d %d %d %d\n", buf->region.x, buf->region.y, buf->region.x2 - buf->region.x, buf->region.y2 - buf->region.y);fflush(stdout);
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,80 @@
++#ifndef MaskBuffer_h_Included
++#define MaskBuffer_h_Included
++
++#include "jni.h"
++#include <X11/Xlib.h>
++#include "ArrayList.h"
++#include "ArrayList.h"
++#include <malloc.h>
++#include <string.h>
++#include <X11/extensions/Xrender.h>
++#include <assert.h>
++
++#define MASK_TILE_SIZE 256
++
++typedef struct {
++  jint x;
++  jint y;
++  jint x2;
++  jint y2;
++}MaskRegion;
++
++typedef struct {
++  XrArrayList rects;
++  XrArrayList lines;
++
++  MaskRegion dirtyRectArea;
++  MaskRegion dirtyLineArea;
++} XrTile;
++
++typedef struct {
++  Pixmap lineMaskPixmap;
++  Picture lineMaskPicture;
++  GC drawLineGC;
++  GC clearLineGC;
++
++  Pixmap maskPixmap;
++  Picture maskPicture;
++  jfloat validatedGCAlpha;
++
++  XrArrayList rects;
++  XrArrayList lines;
++  MaskRegion region;
++
++  int xTiles;
++  int yTiles;
++  int xTileCap;
++  int yTileCap;
++  XrTile *tiles;
++
++  Pixmap gradPixmap;
++  Picture gradPict;
++}MaskBuffer;
++
++MaskBuffer* initMaskBuffer(Window window);
++
++void addRect(MaskBuffer* buf, short x, short y, unsigned short w, unsigned short h);
++
++void addLine(MaskBuffer* buf, int x1, int y1, int x2, int y2);
++
++void fillMask(MaskBuffer* buf, Picture dest);
++
++static void storeRectsInTiles(MaskBuffer *buf);
++
++static void cleanMaskBuffer(MaskBuffer *buf);
++
++static void limitRetcCoords(XRectangle *rect);
++
++static void initRegion(MaskRegion *region);
++
++static void growDirtyRegion(MaskRegion *region, jint x, jint y, jint x2, jint y2);
++
++static void growDirtyRegionTileLimit(MaskRegion *region, jint x, jint y, jint x2, jint y2);
++
++static void initXrTile(XrTile *tile);
++
++static void getTileDirtyArea(MaskRegion *dirtyRectArea, MaskRegion *dirtyLineArea, MaskRegion *totalDirtyArea);
++
++static void translateRects(XrArrayList *rectList, int x, int y);
++
++#endif /* MaskBuffer_h_Included */
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Sat Nov 29 19:56:09 2008 +0100
+@@ -71,7 +71,7 @@
+ extern AwtGraphicsConfigDataPtr
+     getGraphicsConfigFromComponentPeer(JNIEnv *env, jobject this);
+ extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
+-static jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo);
++
+ static int X11SD_FindClip(SurfaceDataBounds *b, SurfaceDataBounds *bounds,
+                           X11SDOps *xsdo);
+ static int X11SD_ClipToRoot(SurfaceDataBounds *b, SurfaceDataBounds *bounds,
+@@ -97,6 +97,49 @@
+ 
+ #endif /* !HEADLESS */
+ 
++jboolean XShared_initIDs(JNIEnv *env)
++{
++#ifndef HEADLESS
++   union {
++        char c[4];
++        int i;
++    } endian;
++
++    endian.i = 0xff000000;
++    nativeByteOrder = (endian.c[0]) ? MSBFirst : LSBFirst;
++
++    dgaAvailable = JNI_FALSE;
++
++    cachedXImage = NULL;
++
++    if (sizeof(X11RIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
++        JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
++        return JNI_FALSE;
++    }
++
++#ifdef MITSHM
++    if (getenv("NO_AWT_MITSHM") == NULL &&
++        getenv("NO_J2D_MITSHM") == NULL) {
++        char * force;
++        TryInitMITShm(env, &useMitShmExt, &useMitShmPixmaps);
++        useMitShmPixmaps = (useMitShmPixmaps == CAN_USE_MITSHM);
++        force = getenv("J2D_PIXMAPS");
++        if (force != NULL) {
++            if (useMitShmPixmaps && (strcmp(force, "shared") == 0)) {
++                forceSharedPixmaps = JNI_TRUE;
++            } else if (strcmp(force, "server") == 0) {
++                useMitShmPixmaps = JNI_FALSE;
++            }
++        }
++    }
++
++    return JNI_TRUE;
++#endif /* MITSHM */
++
++#endif /* !HEADLESS */
++}
++
++
+ /*
+  * Class:     sun_java2d_x11_X11SurfaceData
+  * Method:    initIDs
+@@ -107,22 +150,9 @@
+                                            jclass XORComp, jboolean tryDGA)
+ {
+ #ifndef HEADLESS
++  if(XShared_initIDs(env))
++  {
+     void *lib = 0;
+-
+-    union {
+-        char c[4];
+-        int i;
+-    } endian;
+-
+-    endian.i = 0xff000000;
+-    nativeByteOrder = (endian.c[0]) ? MSBFirst : LSBFirst;
+-
+-    cachedXImage = NULL;
+-
+-    if (sizeof(X11RIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
+-        JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
+-        return;
+-    }
+ 
+     xorCompClass = (*env)->NewGlobalRef(env, XORComp);
+ 
+@@ -130,7 +160,7 @@
+     /* we use RTLD_NOW because of bug 4032715 */
+         lib = dlopen("libsunwjdga.so", RTLD_NOW);
+     }
+-    dgaAvailable = JNI_FALSE;
++
+     if (lib != NULL) {
+         JDgaStatus ret = JDGA_FAILED;
+         void *sym = dlsym(lib, "JDgaLibInit");
+@@ -149,24 +179,7 @@
+             lib = NULL;
+         }
+     }
+-
+-#ifdef MITSHM
+-    if (getenv("NO_AWT_MITSHM") == NULL &&
+-        getenv("NO_J2D_MITSHM") == NULL) {
+-        char * force;
+-        TryInitMITShm(env, &useMitShmExt, &useMitShmPixmaps);
+-        useMitShmPixmaps = (useMitShmPixmaps == CAN_USE_MITSHM);
+-        force = getenv("J2D_PIXMAPS");
+-        if (force != NULL) {
+-            if (useMitShmPixmaps && (strcmp(force, "shared") == 0)) {
+-                forceSharedPixmaps = JNI_TRUE;
+-            } else if (strcmp(force, "server") == 0) {
+-                useMitShmPixmaps = JNI_FALSE;
+-            }
+-        }
+-    }
+-#endif /* MITSHM */
+-
++  }
+ #endif /* !HEADLESS */
+ }
+ 
+@@ -286,6 +299,8 @@
+     } else {
+         xsdo->pixelmask = 0xff;
+     }
++
++    xsdo->xrPic = None;
+ #endif /* !HEADLESS */
+ }
+ 
+@@ -366,6 +381,10 @@
+         XFreeGC(awt_display, xsdo->cachedGC);
+         xsdo->cachedGC = NULL;
+     }
++    if(xsdo->xrPic != None) {
++      XRenderFreePicture(awt_display, xsdo->xrPic);
++    }
++
+     AWT_UNLOCK();
+ #endif /* !HEADLESS */
+ }
+@@ -385,6 +404,63 @@
+     }
+ #endif /* !HEADLESS */
+ }
++
++
++jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable)
++{
++#ifndef HEADLESS
++
++    if (drawable != (jlong)0) {
++        /* Double-buffering */
++        xsdo->drawable = drawable;
++        xsdo->isPixmap = JNI_FALSE;
++    } else {
++        xsdo->isPixmap = JNI_TRUE;
++        /* REMIND: workaround for bug 4420220 on pgx32 boards:
++           don't use DGA with pixmaps unless USE_DGA_PIXMAPS is set.
++         */
++        xsdo->dgaAvailable = useDGAWithPixmaps;
++
++        xsdo->pmWidth = width;
++        xsdo->pmHeight = height;
++
++#ifdef MITSHM
++        xsdo->shmPMData.pmSize = width * height * depth;
++        xsdo->shmPMData.pixelsReadThreshold = width * height / 8;
++        if (forceSharedPixmaps) {
++            AWT_LOCK();
++            xsdo->drawable = X11SD_CreateSharedPixmap(xsdo);
++            AWT_UNLOCK();
++            if (xsdo->drawable) {
++                xsdo->shmPMData.usingShmPixmap = JNI_TRUE;
++                xsdo->shmPMData.shmPixmap = xsdo->drawable;
++                return JNI_TRUE;
++            }
++        }
++#endif /* MITSHM */
++
++        AWT_LOCK();
++        xsdo->drawable =
++            XCreatePixmap(awt_display,
++                          RootWindow(awt_display,
++                                     xsdo->configData->awt_visInfo.screen),
++                          width, height, depth);
++        AWT_UNLOCK();
++#ifdef MITSHM
++        xsdo->shmPMData.usingShmPixmap = JNI_FALSE;
++        xsdo->shmPMData.pixmap = xsdo->drawable;
++#endif /* MITSHM */
++    }
++    if (xsdo->drawable == 0) {
++        JNU_ThrowOutOfMemoryError(env,
++                                  "Can't create offscreen surface");
++        return JNI_FALSE;
++    }
++
++    return JNI_TRUE;
++#endif /* !HEADLESS */
++}
++
+ 
+ /*
+  * Class:     sun_java2d_x11_X11SurfaceData
+@@ -410,51 +486,8 @@
+        8-bit visuals */
+     xsdo->cData = xsdo->configData->color_data;
+ 
+-    if (drawable != (jlong)0) {
+-        /* Double-buffering */
+-        xsdo->drawable = drawable;
+-        xsdo->isPixmap = JNI_FALSE;
+-    } else {
+-        xsdo->isPixmap = JNI_TRUE;
+-        /* REMIND: workaround for bug 4420220 on pgx32 boards:
+-           don't use DGA with pixmaps unless USE_DGA_PIXMAPS is set.
+-         */
+-        xsdo->dgaAvailable = useDGAWithPixmaps;
+-
+-        xsdo->pmWidth = width;
+-        xsdo->pmHeight = height;
+-
+-#ifdef MITSHM
+-        xsdo->shmPMData.pmSize = width * height * depth;
+-        xsdo->shmPMData.pixelsReadThreshold = width * height / 8;
+-        if (forceSharedPixmaps) {
+-            AWT_LOCK();
+-            xsdo->drawable = X11SD_CreateSharedPixmap(xsdo);
+-            AWT_UNLOCK();
+-            if (xsdo->drawable) {
+-                xsdo->shmPMData.usingShmPixmap = JNI_TRUE;
+-                xsdo->shmPMData.shmPixmap = xsdo->drawable;
+-                return;
+-            }
+-        }
+-#endif /* MITSHM */
+-
+-        AWT_LOCK();
+-        xsdo->drawable =
+-            XCreatePixmap(awt_display,
+-                          RootWindow(awt_display,
+-                                     xsdo->configData->awt_visInfo.screen),
+-                          width, height, depth);
+-        AWT_UNLOCK();
+-#ifdef MITSHM
+-        xsdo->shmPMData.usingShmPixmap = JNI_FALSE;
+-        xsdo->shmPMData.pixmap = xsdo->drawable;
+-#endif /* MITSHM */
+-    }
+-    if (xsdo->drawable == 0) {
+-        JNU_ThrowOutOfMemoryError(env,
+-                                  "Can't create offscreen surface");
+-    }
++    XShared_initSurface(env, xsdo, depth, width, height, drawable);
++    xsdo->xrPic = NULL;
+ #endif /* !HEADLESS */
+ }
+ 
+@@ -700,7 +733,7 @@
+ }
+ #endif /* MITSHM */
+ 
+-static jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo)
++jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo)
+ {
+     if (xsdo->isPixmap == JNI_TRUE) {
+         return SD_FAILURE;
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h	Fri Nov 28 22:59:23 2008 +0100
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h	Sat Nov 29 19:56:09 2008 +0100
+@@ -29,6 +29,10 @@
+ #include "awt_GraphicsEnv.h"
+ 
+ #include <jdga.h>
++
++#include <X11/extensions/Xrender.h>
++#include "MaskBuffer.h"
++#include "XRSurfaceData.h"
+ 
+ /**
+  * This include file contains support declarations for loops using the
+@@ -87,6 +91,7 @@
+ } ShmPixmapData;
+ #endif /* MITSHM */
+ 
++
+ struct _X11SDOps {
+     SurfaceDataOps      sdOps;
+     GetPixmapBgFunc     *GetPixmapWithBg;
+@@ -109,6 +114,7 @@
+     jint                bgPixel;       /* bg pixel for the pixmap */
+     jint                pmWidth;       /* width, height of the */
+     jint                pmHeight;      /* pixmap */
++    Picture             xrPic;
+ #ifdef MITSHM
+     ShmPixmapData       shmPMData;     /* data for switching between shm/nonshm pixmaps*/
+ #endif /* MITSHM */
+@@ -155,3 +161,21 @@
+  */
+ JNIEXPORT X11SDOps * JNICALL
+ X11SurfaceData_GetOps(JNIEnv *env, jobject sData);
++
++/*Prototypes for shared functions used by XRSurfaceData*/
++jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable);
++
++jboolean XShared_initIDs(JNIEnv *env);
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_x11_X11SurfaceData_initOps(JNIEnv *env, jobject xsd,
++                                           jobject peer,
++                                           jobject graphicsConfig, jint depth);
++
++JNIEXPORT jlong JNICALL Java_sun_java2d_x11_X11SurfaceData_XCreateGC (JNIEnv *env, jclass xsd, jlong pXSData);
++
++jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo);
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd);
++
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,313 @@
++#include <malloc.h>
++#include "jni.h"
++#include "XRGlyphCache.h"
++#include "ArrayList.h"
++#include "Trace.h"
++#include <X11/extensions/Xrender.h>
++
++#define DEFAULT_CACHE_SIZE 1024
++#define CACHED_PIXELS 100000
++#define TIMES_RENDERED_THRESHOLD 5
++
++#ifndef HEADLESS
++XRGlyphCacheInfo* XRGlyphCache_Init(XRenderPictFormat* glyphSetPictFormat)
++{
++    XRGlyphCacheInfo *cache;
++    J2dTraceLn(J2D_TRACE_INFO, "XRGlyphCache_Init");
++
++    cache = (XRGlyphCacheInfo *) malloc(sizeof(XRGlyphCacheInfo));
++    if (cache == NULL) {
++        J2dRlsTraceLn(J2D_TRACE_ERROR, "XRGlyphCache_Init: could not allocate GlyphCacheInfo");
++        return NULL;
++    }
++
++    cache->cells = (XRCacheCellInfo *) calloc(DEFAULT_CACHE_SIZE, sizeof(XRCacheCellInfo));
++    if(cache->cells == NULL) {
++        J2dRlsTraceLn(J2D_TRACE_ERROR, "XRGlyphCache_Init: could not allocate cell space");
++        return NULL;
++    }
++
++    cache->glyphSet = XRenderCreateGlyphSet (awt_display, glyphSetPictFormat);
++    cache->cellCapacity = DEFAULT_CACHE_SIZE;
++    cache->usedCells = 0;
++    cache->searchPosition = 0;
++    cache->pixelsUsed = 0;
++
++    return cache;
++}
++
++static jboolean cleanCache(XRGlyphCacheInfo *cache)
++{
++  J2dTraceLn(J2D_TRACE_INFO, "XRGlyphCache_cleanCache");
++
++  jint i;
++
++  /*First set cold cache entries free*/
++  for(i=0; i < cache->cellCapacity; i++) {
++    XRCacheCellInfo *cacheCell = &cache->cells[i];
++    if(cacheCell->pinned == JNI_FALSE) {
++      if(cacheCell->glyphID != 0 && cacheCell->timesRendered < TIMES_RENDERED_THRESHOLD) {
++        J2dTraceLn1(J2D_TRACE_INFO, "Removing glyph from cache. ID:", cacheCell->glyphID);
++        XRenderFreeGlyphs (awt_display, cache->glyphSet, (Glyph *) &cacheCell->glyphID, 1);
++        cacheCell->glyphID = 0;
++        cache->pixelsUsed -= (cacheCell->width * cacheCell->height);
++        cache->usedCells--;
++
++        if(cacheCell->glyphInfo != NULL) {
++	   cacheCell->glyphInfo->cellInfo = NULL;
++	}	
++      }
++    }
++     cacheCell->timesRendered = 0;
++  }
++
++  cache->searchPosition = 0;
++   
++  /*If more than 70% are occupied, we enlarge our cache-size by 1.5*/
++  jint oldCapacity = cache->cellCapacity;
++  XRCacheCellInfo *oldCache = cache->cells;
++  jfloat relUsed = ((jfloat) cache->usedCells) / cache->cellCapacity;
++  if(relUsed > 0.7)
++  {
++     cache->cellCapacity = (jint) cache->cellCapacity*1.5;
++     J2dTraceLn1(J2D_TRACE_INFO, "Extensing glyph-cache capacity to", cache->cellCapacity);
++     
++     cache->cells = (XRCacheCellInfo *) realloc(cache->cells, sizeof(XRCacheCellInfo) * (cache->cellCapacity));
++     if(cache->cells == NULL) {
++        J2dRlsTraceLn(J2D_TRACE_ERROR, "XRGlyphCache_cleanCache: Could not enlarge cell space");
++        return JNI_FALSE;
++      }
++     memset(&cache->cells[oldCapacity], 0, sizeof(XRCacheCellInfo) * (cache->cellCapacity - oldCapacity));
++
++   //If realloc gave us a different location, update pointers in GlyphInfo
++   if(oldCache != cache->cells) {
++       int cnt;
++       for(cnt = 0; cnt < oldCapacity; cnt++) {
++           XRCacheCellInfo *cacheCell = &cache->cells[cnt];
++           if(cacheCell->glyphID != 0 && cacheCell->glyphInfo != NULL) {
++              cacheCell->glyphInfo->cellInfo = cacheCell; /*TODO: we currently mis-use the pointer for our own type*/
++           }
++        }
++    }
++  } 
++
++  return JNI_TRUE;
++}
++
++static jboolean uploadGlyph(XRGlyphCacheInfo *cache, GlyphInfo *jginfo, XRCacheCellInfo *cacheCell)
++{
++     J2dTraceLn(J2D_TRACE_INFO, "XRGlyphCache_uploadGlyph");
++
++     unsigned char* glyphBuf = (unsigned char*) jginfo->image; 
++     jboolean grayscale = (jginfo->rowBytes == jginfo->width);
++     jint dstBytesPerPixel = grayscale ? 1 : 4;
++     jint srcBytesPerPixel = grayscale ? 1 : 3;
++     jint dstStrideWidth = dstBytesPerPixel * jginfo->width;
++     jint srcStrideWidth = srcBytesPerPixel * jginfo->width;
++     jint bufLen = dstStrideWidth * jginfo->height;
++     jint width = jginfo->width, height = jginfo->height;
++     jboolean bufferAllocated = JNI_FALSE;
++
++        if(jginfo->image != NULL) {
++          if(grayscale == JNI_TRUE) {
++
++                 /*XRender expects glyph images to be padded to 4-byte boundaries*/
++                 if(jginfo->width%4 != 0 || jginfo->image == NULL) { 
++                 int pad = 4 - (jginfo->width % 4);
++	         dstBytesPerPixel = jginfo->width + pad;
++                 bufLen =  dstBytesPerPixel * jginfo->height;
++                 glyphBuf = calloc(1, bufLen);
++                 bufferAllocated = JNI_TRUE;
++
++                 if(jginfo->image != NULL)  {
++	           int line, pix;
++	           for(line = 0; line < jginfo->height; line++) {
++		     for(pix = 0; pix < jginfo->width; pix++) {
++		        glyphBuf[line*jginfo->width + pad*line + pix] = jginfo->image[line*jginfo->width + pix];
++		     }
++	           }	
++                 }
++             }
++
++          }else {
++            bufLen =  dstStrideWidth * height;
++            glyphBuf = calloc(1, bufLen);
++            bufferAllocated = JNI_TRUE;
++
++	    int line, srcpix, dstpix;
++	    for(line = 0; line < height; line++) {
++		srcpix = 0;
++		dstpix = 0;
++		while(dstpix < dstStrideWidth) {
++             /*B*/glyphBuf[line*dstStrideWidth + dstpix + 0] = /*B*/jginfo->image[(line*jginfo->rowBytes + srcpix + 2)];
++             /*G*/glyphBuf[line*dstStrideWidth + dstpix + 1] = /*G*/jginfo->image[(line*jginfo->rowBytes + srcpix + 1)];
++             /*R*/glyphBuf[line*dstStrideWidth + dstpix + 2] = /*R*/jginfo->image[(line*jginfo->rowBytes + srcpix + 0)];
++             /*A*/glyphBuf[line*dstStrideWidth + dstpix + 3] = 255;		
++                  srcpix += 3;
++                  dstpix += 4;
++		}
++	    }
++	 }
++      }else {
++         bufLen = 4; //Work arround for bug in older servers
++	 glyphBuf = calloc(1, bufLen);
++         bufferAllocated = JNI_TRUE;
++	 width = 1;
++	 height = 1;
++      }
++     
++
++     Glyph gid = (Glyph) cacheCell->glyphID;
++     XGlyphInfo xginfo={.x=(jginfo->topLeftX*-1),.y=(jginfo->topLeftY*-1),.width=width,.height=height, .xOff = cacheCell->xOff,.yOff = cacheCell->yOff};
++
++     XRenderAddGlyphs(awt_display, cache->glyphSet, &gid, &xginfo, 1, glyphBuf, bufLen);
++     
++     if(bufferAllocated == JNI_TRUE) {
++       free(glyphBuf);
++     }
++
++     return JNI_TRUE;
++}
++
++jboolean XRGlyphCache_CacheGlyphs(XRGlyphCacheInfo *cache, jlong *glyphPtrs, jint glyphCount, jint *ids)
++{ 
++   jint glyphsStored = 0;
++   
++   do {
++    /**
++     * Search for free cache-cells to store glyphs which have not been cached already.
++     * The outer loop iterates over all cache-zells, as long as either all have been walked over or all glyphs are stored.
++     * The inner loop loops over all non-processed glyphs (if the current zell is free), 
++     * and stores it in the free cache-zell if not already cached, and pins it.
++     * If the outer-loop finishes before all glyphs are cached, not enough free zells were available and a cache-cleanup is triggered.
++     */
++      while((cache->searchPosition < cache->cellCapacity) && (glyphsStored < glyphCount)) {
++       XRCacheCellInfo *cacheCell = &cache->cells[cache->searchPosition];
++       
++       while(glyphsStored < glyphCount) {  //loop over unprocessed glyphs
++	 GlyphInfo *currGlyph = (GlyphInfo *)jlong_to_ptr(glyphPtrs[glyphsStored]);// &glyphs[glyphsStored];
++
++         if(currGlyph->cellInfo == NULL) { //If the current glyph is not cached, add it to cache if current cacheZell is a free one
++           //Evaluate not in loop-head, otherwise we would have to iterate until a free cell
++           //even if all glyphs are already cached (common case)
++           if(cacheCell->glyphID != 0)
++           {
++             cache->searchPosition++;
++             break;
++           }
++
++           currGlyph->cellInfo = cacheCell;
++           cacheCell->glyphInfo = currGlyph;
++           cacheCell->glyphID = (unsigned short) cache->searchPosition + 1;
++           cacheCell->xOff = round(currGlyph->advanceX);
++	   cacheCell->yOff = round(currGlyph->advanceY);
++           cacheCell->width = currGlyph->width;
++           cacheCell->height = currGlyph->height;
++
++           jboolean uploadError = uploadGlyph(cache, currGlyph, cacheCell);
++           if(uploadError == JNI_FALSE) {
++             return JNI_FALSE;
++           }
++
++           cache->pixelsUsed += (currGlyph->width * currGlyph->height);
++           cache->usedCells++;
++         }
++
++	  //Work that has to be done independently wether the cell was cached or not
++          XRCacheCellInfo *usedCell = (XRCacheCellInfo *) currGlyph->cellInfo;
++          usedCell->pinned = JNI_TRUE;
++          usedCell->timesRendered++;
++          glyphsStored++;
++        }
++     }
++       
++     //TODO: If we were not able to store all uncached glyphs we free the cache and try again
++     if(glyphsStored < glyphCount || cache->pixelsUsed > CACHED_PIXELS) { 
++       J2dTraceLn(J2D_TRACE_INFO, "XRGlyphCache: Glyph-cache too small, cleanup triggered");
++       if(cleanCache(cache) == JNI_FALSE) {
++	  return JNI_FALSE;
++       }
++     }
++   }while(glyphsStored < glyphCount);
++ 
++   /* Remove pin-property from the cache-entries,
++    * pass IDs to the caller                     */
++   int i;
++   for(i=0; i < glyphCount; i++) {
++     XRCacheCellInfo *cell = (XRCacheCellInfo*) (((GlyphInfo *)jlong_to_ptr(glyphPtrs[i]))->cellInfo);
++     cell->pinned = JNI_FALSE;
++     ids[i] = cell->glyphID;
++   }
++
++   return JNI_TRUE;
++}
++
++#if 0
++void dumpCache(XRGlyphCacheInfo *cache)
++{
++  int i;
++  for(i=0; i < cache->cellCapacity; i++)
++  {
++    XRCacheCellInfo *cell = &cache->cells[i];
++    if(cell->glyphID != 0)
++    {
++      printf("Cache-Position: %d enthaelt glyph: %d mit counter:%d\n", i, cell->glyphID, cell->timesRendered);
++      fflush(stdout);
++    }
++  }
++}
++#endif
++
++#endif /*!Headless*/
++
++
++// 	  int line_, pix_;
++// 	  for(line_ = 0; line_ < jginfo->height; line_++)
++// 	  {
++// 		for(pix_ = 0; pix_ < jginfo->rowBytes; pix_+=3)
++// 		{
++// 		  int r = jginfo->image[line_*jginfo->rowBytes + pix_ + 0];
++//                   int g = jginfo->image[line_*jginfo->rowBytes + pix_ + 1];
++// 	          int b = jginfo->image[line_*jginfo->rowBytes + pix_ + 2];
++//   
++//                 if(r > 99)
++// 	{
++// 	printf("%d,", r);
++// 	}else	
++//         if(r > 9)
++// {
++// 	printf(" %d,", r);
++// }else
++// {
++// 	printf("  %d,", r);
++// }
++// 
++//                 if(g > 99)
++// 	{
++// 	printf("%d,", g);
++// 	}else	
++//         if(g > 9)
++// {
++// 	printf(" %d,", g);
++// }else
++// {
++// 	printf("  %d,", g);
++// }
++// 
++//                 if(b > 99)
++// 	{
++// 	printf("%d,", b);
++// 	}else	
++//         if(b > 9)
++// {
++// 	printf(" %d,", b);
++// }else
++// {
++// 	printf("  %d,", b);
++// }
++// 
++// 	printf(" 255, ");
++// }
++//             printf("\n");
++// 	  }	
++//         fflush(stdout);
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,41 @@
++#ifndef XRGlyphCache_h_Included
++#define XRGlyphCache_h_Included
++
++#include "awt_p.h"
++#include "awt_GraphicsEnv.h"
++
++#include <X11/extensions/Xrender.h>
++#include "jni.h"
++#include "fontscalerdefs.h"
++
++typedef struct _XRGlyphCacheInfo XRGlyphCacheInfo;
++typedef struct _XRCacheCellInfo XRCacheCellInfo;
++
++struct _XRGlyphCacheInfo {
++    XRCacheCellInfo *cells;
++    jint searchPosition;
++    jint usedCells;
++    jint cellCapacity;
++    jint pixelsUsed;
++    GlyphSet glyphSet;
++};
++
++struct _XRCacheCellInfo {
++    XRGlyphCacheInfo *cacheInfo;
++    GlyphInfo *glyphInfo;
++    unsigned short glyphID;
++    jint timesRendered;
++    jint width;
++    jint height;
++    jint xOff;
++    jint yOff;
++    jboolean pinned;
++};
++
++#ifndef HEADLESS
++XRGlyphCacheInfo* XRGlyphCache_Init(XRenderPictFormat* glyphSetPictFormat);
++jboolean XRGlyphCache_CacheGlyphs(XRGlyphCacheInfo *cache, jlong *glyphPtrs, jint glyphCount, jint *ids);
++void dumpCache(XRGlyphCacheInfo *cache);
++#endif
++
++#endif /* XRGlyphCache_h_Included */
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,223 @@
++/*
++ * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++#include <stdlib.h>
++#include <jni.h>
++#include <jlong.h>
++#include "X11SurfaceData.h"
++#include "XRSurfaceData.h"
++#include "Region.h"
++#include "MaskBuffer.h"
++#include "Trace.h"
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRPMBlitLoops_nativeRenderBlit
++    (JNIEnv *env, jclass xsd,
++     jlong srcData, jlong dstData,
++     jint srcx, jint srcy,
++     jint dstx, jint dsty,
++     jint width, jint height)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_nativeRenderBlit");
++
++    X11SDOps *srcXsdo, *dstXsdo;
++    SurfaceDataBounds span, srcBounds;
++
++    if (width <= 0 || height <= 0) {
++        return;
++    }
++
++    srcXsdo = (X11SDOps *)jlong_to_ptr(srcData);
++    if (srcXsdo == NULL) {
++        return;
++    }
++    dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
++    if (dstXsdo == NULL) {
++        return;
++    }
++
++#ifdef MITSHM
++    if (srcXsdo->isPixmap) {
++        X11SD_UnPuntPixmap(srcXsdo);
++    }
++#endif /* MITSHM */
++
++/*   printf("src: %d, dst: %d", srcXsdo->xrData.xrPic, dstXsdo->xrData.xrPic);
++   fflush(stdout);*/
++
++/*XTransform xf = {{{XDoubleToFixed (0.5), 0, 0 },
++{0, XDoubleToFixed (0.5), 0 },
++{XDoubleToFixed (0), XDoubleToFixed (0), XDoubleToFixed (1.0)}}};
++
++XRenderSetPictureTransform(awt_display, dstXsdo->xrData.xrPic, &xf);
++XRenderSetPictureFilter(awt_display, dstXsdo->xrData.xrPic, "good", NULL, 0);*/
++
++   XRenderComposite (awt_display, xrSrcData.compRule, srcXsdo->xrPic, xrSrcData.alphaMask, dstXsdo->xrPic, srcx, srcy, 0, 0, dstx, dsty, width, height); 
++
++#ifdef MITSHM
++    if (srcXsdo->shmPMData.usingShmPixmap) {
++        srcXsdo->shmPMData.xRequestSent = JNI_TRUE;
++    }
++#endif /* MITSHM */
++    X11SD_DirectRenderNotify(env, dstXsdo);
++#endif /* !HEADLESS */
++}
++
++#ifndef HEADLESS
++static Picture prepareMaskPM(JNIEnv *env, X11SDOps *alphaXsdo, jbyteArray maskArray, jint maskoff, jint maskscan, jint w, jint h)
++{
++    int line, pix;
++    unsigned char *mask;
++    SurfaceDataOps *alphaOps = &alphaXsdo->sdOps;
++
++    jboolean useEA = (xrSrcData.src != xrSrcData.solid && xrSrcData.extraAlpha != 1.0f);
++
++    if (maskArray != NULL) {
++    		SurfaceDataRasInfo alphaInfo;
++    		alphaInfo.bounds.x1 = 0;
++    		alphaInfo.bounds.y1 = 0;
++    		alphaInfo.bounds.x2 = w;
++    		alphaInfo.bounds.y2 = h;
++
++		if (alphaOps->Lock(env, alphaOps, &alphaInfo, SD_LOCK_WRITE) != SD_SUCCESS) {
++			SurfaceData_InvokeUnlock(env, alphaOps, &alphaInfo);
++			return None;
++		}
++                mask = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, maskArray, NULL);
++
++		alphaOps->GetRasInfo(env, alphaOps, &alphaInfo);
++
++              if(useEA && (w > MASK_TILE_SIZE || h > MASK_TILE_SIZE))
++              {
++		for(line=0; line < h; line++) {
++		  for(pix=0; pix < w; pix++) {
++  		     ((unsigned char*)alphaInfo.rasBase)[line*alphaInfo.scanStride + pix] = (unsigned char) (mask[maskscan*line + pix + maskoff] * xrSrcData.extraAlpha);  
++		  }
++		}
++             }else
++             {
++		for(line=0; line < h; line++) {
++		  for(pix=0; pix < w; pix++) {
++  		     ((unsigned char*)alphaInfo.rasBase)[line*alphaInfo.scanStride + pix] = (unsigned char) (mask[maskscan*line + pix + maskoff]);  
++		  }
++		}
++             }
++
++                SurfaceData_InvokeRelease(env, alphaOps, &alphaInfo);
++                SurfaceData_InvokeUnlock(env, alphaOps, &alphaInfo);
++                (*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT);
++
++	if(useEA) {
++                XRenderComposite (awt_display, PictOpOver, alphaXsdo->xrPic, xrSrcData.alphaMask, maskBuffer->maskPicture, 0, 0, 0, 0, 0, 0, w, h); 
++                return maskBuffer->maskPicture;
++          }else
++          {
++             return alphaXsdo->xrPic;
++          }
++    }else
++    {
++      if(useEA) {
++        return xrSrcData.alphaMask;
++      }
++    }
++
++    return None;
++}
++
++static void cleanMask(Picture mask, int w, int h)
++{
++  if(mask == maskBuffer->maskPicture)
++  {
++     XRenderColor color_black={.red=0, .green=0, .blue=0, .alpha=0xffff};
++     XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->maskPicture, &color_black, 0, 0, w, h);
++  }
++}
++#endif
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRMaskFill_maskFill
++     (JNIEnv *env, jobject joSelf, 
++      jlong dstData, jlong alphaData,
++      jint x, jint y, jint w, jint h,
++      jint maskoff, jint maskscan, 
++      jint masklen, jbyteArray maskArray)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_maskFill");
++
++    Picture maskPic;
++    X11SDOps *dstXsdo, *alphaXsdo;
++    dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
++    alphaXsdo = (X11SDOps *)jlong_to_ptr(alphaData);
++    if (dstXsdo == NULL || alphaXsdo == NULL) {
++        return;
++    }
++
++    maskPic = prepareMaskPM(env, alphaXsdo, maskArray, maskoff, maskscan, w, h);
++
++    XRComposite(maskPic, dstXsdo->xrPic, x, y, 0, 0, x, y, w, h);
++
++    cleanMask(maskPic, w, h);
++
++    X11SD_DirectRenderNotify(env, dstXsdo);
++#endif
++}
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRMaskBlit_maskBlit
++     (JNIEnv *env, jobject joSelf, 
++      jlong srcData, jlong dstData, jlong alphaData,
++      jint srcx, jint srcy,
++      jint dstx, jint dsty, jint w, jint h,
++      jint maskoff, jint maskscan, 
++      jint masklen, jbyteArray maskArray)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_maskBlit");
++
++    Picture maskPic;
++    X11SDOps *srcXsdo, *dstXsdo, *alphaXsdo;
++    srcXsdo = (X11SDOps *)jlong_to_ptr(srcData);
++    dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
++    alphaXsdo = (X11SDOps *)jlong_to_ptr(alphaData);
++    if (srcXsdo == NULL || dstXsdo == NULL || alphaXsdo == NULL) {
++        return;
++    }
++
++    maskPic = prepareMaskPM(env, alphaXsdo, maskArray, maskoff, maskscan, w, h);
++    XRenderComposite (awt_display, xrSrcData.compRule, srcXsdo->xrPic, maskPic, dstXsdo->xrPic, srcx, srcy, 0, 0, dstx, dsty, w, h); 
++    cleanMask(maskPic, w, h);
++
++    X11SD_DirectRenderNotify(env, dstXsdo);
++
++    #ifdef MITSHM
++    if (srcXsdo->isPixmap) {
++        X11SD_UnPuntPixmap(srcXsdo);
++    }
++    #endif /* MITSHM */
++#endif
++}
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,318 @@
++/*
++ * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++#include "X11SurfaceData.h"
++#include "XRSurfaceData.h"
++#include "SpanIterator.h"
++#include "Trace.h"
++#include "ProcessPath.h"
++#include "GraphicsPrimitiveMgr.h"
++#include <math.h>
++#include <stdint.h>
++
++#include <jlong.h>
++
++#define POLYTEMPSIZE    (int)(256 / sizeof(XPoint))
++#define ABS(n)          (((n) < 0) ? -(n) : (n))
++
++#define MAX_SHORT 32767
++#define MIN_SHORT (-32768)
++
++#define CLAMP_TO_SHORT(x) (((x) > MAX_SHORT)                            \
++                           ? MAX_SHORT                                  \
++                           : ((x) < MIN_SHORT)                          \
++                               ? MIN_SHORT                              \
++                               : (x))
++
++#define CLAMP_TO_USHORT(x)  (((x) > 65535) ? 65535 : ((x) < 0) ? 0 : (x))
++
++
++JNIEXPORT void JNICALL XRDrawLines(Picture dst, XPoint * points, int npoints)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_XRDrawLines");
++
++    int i;
++    XPoint *start = &points[0], *end;
++    for(i=1; i < npoints; i++)
++    {
++      end = &points[i];
++      addLine(maskBuffer, start->x, start->y, end->x, end->y);
++      start = end;
++    }
++#endif
++}
++
++/*
++ * Class:     sun_java2d_xr_XRRenderer
++ * Method:    XDrawLine
++ * Signature: (IJIIII)V
++ */
++JNIEXPORT void JNICALL Java_sun_java2d_xr_XRRenderer_XRDrawLine
++    (JNIEnv *env, jobject xr, jlong pXSData, jint x1, jint y1, jint x2, jint y2)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_XRDrawLine");
++    X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++
++    if (xsdo == NULL) {
++        return;
++    }
++
++    addLine(maskBuffer, x1, y1, x2, y2);
++    fillMask(maskBuffer, xsdo->xrPic);
++
++    X11SD_DirectRenderNotify(env, xsdo);
++#endif /* !HEADLESS */
++}
++
++static void storeLine(DrawHandler* hnd,
++                      jint x0, jint y0, jint x1, jint y1)
++{
++#ifndef HEADLESS
++   addLine(maskBuffer, x0, y0, x1, y1);
++#endif /* !HEADLESS */
++}
++
++static void storePoint(DrawHandler* hnd, jint x0, jint y0) {
++#ifndef HEADLESS
++    addRect(maskBuffer, x0, y0, 1, 1);
++#endif /* !HEADLESS */
++}
++
++static void drawSubPath(ProcessHandler* hnd) {
++#ifndef HEADLESS
++#endif /* !HEADLESS */
++}
++
++static void drawScanline(DrawHandler* hnd, jint x0, jint x1, jint y0)
++{
++#ifndef HEADLESS
++   addRect(maskBuffer, x0, y0, x1-x0 + 1, 1);
++#endif /* !HEADLESS */
++}
++
++/*
++ * Class:     sun_java2d_xr_XRRenderer
++ * Method:    XDoPath
++ * Signature: (Lsun/java2d/SunGraphics2D;JJIILjava/awt/geom/Path2D/Float;Z)V
++ */
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRRenderer_XRDoPath
++    (JNIEnv *env, jobject self, jobject sg2d, jlong pXSData,
++     jint transX, jint transY, jobject p2df, jboolean isFill)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_XRDoPath");
++
++    X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++    jarray typesArray;
++    jobject pointArray;
++    jarray coordsArray;
++    jint numTypes;
++    jint fillRule;
++    jint maxCoords;
++    jbyte *types;
++    jfloat *coords;
++
++    DrawHandler drawHandler = {
++        NULL, NULL, NULL,
++        MIN_SHORT, MIN_SHORT, MAX_SHORT, MAX_SHORT,
++        0, 0, 0, 0,
++        NULL
++    };
++    PHStroke stroke;
++
++    if (xsdo == NULL) {
++        return;
++    }
++
++    if (isFill) {
++        fillRule = (*env)->GetIntField(env, p2df, path2DWindingRuleID);
++    }
++
++    typesArray = (jarray)(*env)->GetObjectField(env, p2df, path2DTypesID);
++    coordsArray = (jarray)(*env)->GetObjectField(env, p2df,
++                                                 path2DFloatCoordsID);
++    if (coordsArray == NULL) {
++        JNU_ThrowNullPointerException(env, "coordinates array");
++        return;
++    }
++    numTypes = (*env)->GetIntField(env, p2df, path2DNumTypesID);
++    if ((*env)->GetArrayLength(env, typesArray) < numTypes) {
++        JNU_ThrowArrayIndexOutOfBoundsException(env, "types array");
++        return;
++    }
++
++
++    drawHandler.pData = NULL;
++
++    stroke = (((*env)->GetIntField(env, sg2d, sg2dStrokeHintID) ==
++               sunHints_INTVAL_STROKE_PURE)
++              ? PH_STROKE_PURE
++              : PH_STROKE_DEFAULT);
++
++    maxCoords = (*env)->GetArrayLength(env, coordsArray);
++    coords = (jfloat*)
++        (*env)->GetPrimitiveArrayCritical(env, coordsArray, NULL);
++    if (coords != NULL) {
++        types = (jbyte*)
++            (*env)->GetPrimitiveArrayCritical(env, typesArray, NULL);
++        if (types != NULL) {
++            jboolean ok;
++
++            if (isFill) {
++                drawHandler.pDrawScanline = &drawScanline;
++                ok = doFillPath(&drawHandler,
++                                transX, transY,
++                                coords, maxCoords,
++                                types, numTypes,
++                                stroke, fillRule);
++            } else {
++                drawHandler.pDrawLine = &storeLine;
++                drawHandler.pDrawPixel = &storePoint;
++                ok = doDrawPath(&drawHandler, &drawSubPath,
++                                transX, transY,
++                                coords, maxCoords,
++                                types, numTypes,
++                                stroke);
++            }
++            if (!ok) {
++                JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array");
++            }
++            (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types,
++                                                  JNI_ABORT);
++        }
++        (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords,
++                                              JNI_ABORT);
++    }
++
++
++    fillMask(maskBuffer, xsdo->xrPic);
++
++    X11SD_DirectRenderNotify(env, xsdo);
++#endif /* !HEADLESS */
++}
++
++JNIEXPORT void JNICALL Java_sun_java2d_xr_XRRenderer_XRFillRect
++    (JNIEnv *env, jobject xr,
++     jlong pXSData,
++     jint x, jint y, jint w, jint h)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_XRFillRect");
++    X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++
++    if (xsdo == NULL) {
++        return;
++    }
++ 
++    addRect(maskBuffer, x, y, w, h);
++    fillMask(maskBuffer, xsdo->xrPic);
++
++    X11SD_DirectRenderNotify(env, xsdo);
++#endif /* !HEADLESS */
++}
++
++JNIEXPORT void JNICALL Java_sun_java2d_xr_XRRenderer_XRFillSpans
++    (JNIEnv *env, jobject xr,
++     jlong pXSData,
++     jobject si, jlong pIterator,
++     jint transx, jint transy)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_XRFillSpans");
++
++    SpanIteratorFuncs *pFuncs = (SpanIteratorFuncs *) jlong_to_ptr(pIterator);
++    void *srData;
++    jint x, y, w, h;
++    jint spanbox[4];
++    X11SDOps *xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++
++    if (xsdo == NULL) {
++        return;
++    }
++
++    if (JNU_IsNull(env, si)) {
++        JNU_ThrowNullPointerException(env, "span iterator");
++        return;
++    }
++    if (pFuncs == NULL) {
++        JNU_ThrowNullPointerException(env, "native iterator not supplied");
++        return;
++    }
++
++    srData = (*pFuncs->open)(env, si);
++    while ((*pFuncs->nextSpan)(srData, spanbox)) {
++        x = spanbox[0] + transx;
++        y = spanbox[1] + transy;
++        w = spanbox[2] - spanbox[0];
++        h = spanbox[3] - spanbox[1];
++
++        addRect(maskBuffer, x, y, w, h);
++    }
++
++    fillMask(maskBuffer, xsdo->xrPic);
++
++    (*pFuncs->close)(env, srData);
++    X11SD_DirectRenderNotify(env, xsdo);
++#endif /* !HEADLESS */
++}
++
++/*
++ * Class:     sun_java2d_xr_XRRenderer
++ * Method:    devCopyArea
++ * Signature: (Lsun/java2d/SurfaceData;IIIIII)V
++ */
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRRenderer_devCopyArea
++    (JNIEnv *env, jobject xr,
++     jlong xsd, jlong gc,
++     jint srcx, jint srcy,
++     jint dstx, jint dsty,
++     jint width, jint height)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRRenderer_devCopyArea");
++
++    X11SDOps *xsdo;
++    GC xgc;
++
++    xsdo = (X11SDOps *) jlong_to_ptr(xsd);
++    if (xsdo == NULL) {
++        return;
++    }
++
++    xgc = (GC) jlong_to_ptr(gc);
++    if (xgc == NULL) {
++        return;
++    }
++
++    XCopyArea(awt_display, xsdo->drawable, xsdo->drawable, xgc,
++              srcx, srcy, width, height, dstx, dsty);
++
++    X11SD_DirectRenderNotify(env, xsdo);
++#endif /* !HEADLESS */
++}
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,519 @@
++#include "GraphicsPrimitiveMgr.h"
++#include "Region.h"
++#include "Trace.h"
++#include "X11SurfaceData.h"
++
++#ifndef HEADLESS
++SrcSurfaceData xrSrcData;
++MaskBuffer *maskBuffer;
++#endif /* !HEADLESS */
++
++#define BUILD_TRANSFORM_MATRIX(TRANSFORM, M00, M01, M02, M10, M11, M12)                        \
++    {                                                                                          \
++      TRANSFORM.matrix[0][0] = M00;                                                            \
++      TRANSFORM.matrix[0][1] = M01;                                                            \
++      TRANSFORM.matrix[0][2] = M02;                                                            \
++      TRANSFORM.matrix[1][0] = M10;                                                            \
++      TRANSFORM.matrix[1][1] = M11;                                                            \
++      TRANSFORM.matrix[1][2] = M12;                                                            \
++      TRANSFORM.matrix[2][0] = 0;                                                              \
++      TRANSFORM.matrix[2][1] = 0;                                                              \
++      TRANSFORM.matrix[2][2] = 1<<16;                                                          \
++    }
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_initOps(JNIEnv *env, jobject xsd,
++                                           jobject peer,
++                                           jobject graphicsConfig, jint depth)
++{
++   J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initOps");
++
++   Java_sun_java2d_x11_X11SurfaceData_initOps(env, xsd, peer, graphicsConfig, depth);
++}
++
++JNIEXPORT jlong JNICALL Java_sun_java2d_xr_XRSurfaceData_XCreateGC (JNIEnv *env, jclass xsd, jlong pXSData)
++{
++   J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XCreateGC");
++
++   return Java_sun_java2d_x11_X11SurfaceData_XCreateGC (env, xsd, pXSData);
++}
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)
++{
++  J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_flushNativeSurface");
++
++  Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(env, xsd);
++}
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_setInvalid(JNIEnv *env, jobject xsd)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_setInvalid");
++    X11SDOps *xsdo = (X11SDOps *) SurfaceData_GetOps(env, xsd);
++
++    if (xsdo != NULL) {
++        xsdo->invalid = JNI_TRUE;
++    }
++#endif /* !HEADLESS */
++}
++
++JNIEXPORT jboolean JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRIsDrawableValid(JNIEnv *env, jobject this)
++{
++    jboolean ret = JNI_FALSE;
++
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRIsDrawableValid");
++    X11SDOps *xsdo = X11SurfaceData_GetOps(env, this);
++
++    if (xsdo->drawable != 0 || X11SD_InitWindow(env, xsdo) == SD_SUCCESS) {
++        ret = JNI_TRUE;
++    }
++
++#endif /* !HEADLESS */
++
++    return ret;
++}
++
++
++JNIEXPORT void JNICALL
++   Java_sun_java2d_xr_XRSurfaceData_XRInitXRender(JNIEnv *env, jobject xsd, jlong pXSData, jint pictFormat)
++{
++#ifndef HEADLESS
++  J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initXRender");
++  X11SDOps *xsdo;
++  xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++  if (xsdo == NULL) {
++      return;
++  }
++
++  if(xsdo->xrPic == None)
++  {
++    XRenderPictureAttributes pict_attr;
++    pict_attr.repeat = RepeatNone; 
++    XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, pictFormat);
++    xsdo->xrPic = XRenderCreatePicture(awt_display, xsdo->drawable, fmt, CPRepeat, &pict_attr);
++  }
++
++  if(maskBuffer == NULL) 
++  {
++    maskBuffer = initMaskBuffer(xsdo->drawable);
++
++    XRenderPictureAttributes pict_attr;
++    pict_attr.repeat = 1;
++
++    /*Init solid color pen*/
++    XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, PictStandardARGB32);
++    Pixmap solidPixmap = XCreatePixmap(awt_display, xsdo->drawable, 1, 1, 32);
++    xrSrcData.solid = XRenderCreatePicture(awt_display, solidPixmap, fmt, CPRepeat, &pict_attr);
++
++    /*Init extra-alpha mask*/
++    fmt = XRenderFindStandardFormat(awt_display, PictStandardA8);
++    Pixmap alphaPixmap = XCreatePixmap(awt_display, xsdo->drawable, 1, 1, 8);
++    xrSrcData.alphaMaskPict = XRenderCreatePicture(awt_display, alphaPixmap, fmt, CPRepeat, &pict_attr);
++  }
++#endif /* !HEADLESS */
++}
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_initIDs(JNIEnv *env, jclass xsd, jboolean gradCacheEnabled)
++{
++#ifndef HEADLESS
++  J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initIDs");
++
++  xrSrcData.src = None;
++  xrSrcData.solid = None;
++  xrSrcData.texture = None;
++  xrSrcData.gradient = None;
++  xrSrcData.alphaMask = None;
++  xrSrcData.alphaMaskPict = None;
++  xrSrcData.compRule = PictOpOver;
++  xrSrcData.extraAlpha = 1.0f;
++  xrSrcData.compRequired = JNI_FALSE;
++
++  xrSrcData.alphaColor.alpha = 0xffff;
++  xrSrcData.alphaColor.red = 0xffff;
++  xrSrcData.alphaColor.green = 0xffff;
++  xrSrcData.alphaColor.blue = 0xffff;
++
++  xrSrcData.gradCacheEnabled = gradCacheEnabled;
++
++  maskBuffer = NULL;
++
++  XShared_initIDs(env);
++#endif /* !HEADLESS */
++}
++
++
++void XRComposite(Picture mask, Picture dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, unsigned int width, unsigned int height)
++{ 
++  Picture cachedSrc = xrSrcData.src;
++  int cachedX = srcX;
++  int cachedY = srcY;
++
++  if(xrSrcData.src == xrSrcData.gradient && xrSrcData.gradCacheEnabled)
++  {
++    XRenderComposite(awt_display, PictOpSrc, xrSrcData.gradient, None, maskBuffer->gradPict, srcX, srcY, 0, 0, 0, 0, width, height);
++    cachedX = 0;
++    cachedY = 0; 
++    cachedSrc = maskBuffer->gradPict;
++  }
++
++   XRenderComposite (awt_display, xrSrcData.compRule, cachedSrc, mask, dest, cachedX, cachedY, maskX, maskY, dstX, dstY, width, height);
++}
++
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRInitSurface(JNIEnv *env, jclass xsd,
++                                               jint depth,
++                                               jint width, jint height,
++                                               jlong drawable, jint pictFormat)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initSurface");
++
++    jboolean success = JNI_FALSE;
++    X11SDOps *xsdo = X11SurfaceData_GetOps(env, xsd);
++    if (xsdo == NULL) {
++        return;
++    }
++
++    if(XShared_initSurface(env, xsdo, depth, width, height, drawable))
++    {
++      XRenderPictureAttributes pict_attr;
++      XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, pictFormat); 
++      xsdo->xrPic = XRenderCreatePicture(awt_display, xsdo->drawable, fmt, 0, &pict_attr);
++    }
++#endif /* !HEADLESS */
++}
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRResetPaint
++    (JNIEnv *env, jclass xsd)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRResetPaint");
++    xrSrcData.src = xrSrcData.solid;
++#endif /* !HEADLESS */
++}
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRSetRepeat
++    (JNIEnv *env, jclass xsd, jlong pXSData, jint repeat)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetRepeat");
++    X11SDOps *xsdo;
++    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++    if (xsdo == NULL) {
++        return;
++    }
++
++    XRenderPictureAttributes pict_attr;
++    pict_attr.repeat = repeat;
++    XRenderChangePicture (awt_display, xsdo->xrPic, CPRepeat, &pict_attr);
++#endif /* !HEADLESS */
++}
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRSetLinearGradientPaint
++    (JNIEnv *env, jclass xsd, jfloatArray fractionsArray, jintArray pixelsArray, jint x1, jint y1, jint x2, jint y2, jint numStops, jint cycleMethod, jboolean useMask, jboolean linear, jint m00, jint m01, jint m02, jint m10, jint m11, jint m12)
++{
++#ifndef HEADLESS
++   J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetLinearGradientPaint");
++
++   jint i;
++   jint* pixels;
++   jfloat* fractions;
++
++   if((pixels = (jint *) (*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) {
++     return;
++   }
++   if((fractions = (jfloat *) (*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL)) == NULL) {
++     return; //TODO release pixels first
++   }
++
++   if(xrSrcData.gradient != None) {
++      XRenderFreePicture(awt_display, xrSrcData.gradient);
++      xrSrcData.gradient = None;
++   }
++
++    XLinearGradient grad;
++    XRenderColor colors[numStops];
++    XFixed stops[numStops];
++
++    grad.p1.x = x1;
++    grad.p1.y = y1;
++    grad.p2.x = x2;
++    grad.p2.y = y2;
++
++    for(i=0; i < numStops; i++) {
++      stops[i] = XDoubleToFixed(fractions[i]);
++      decodeRenderColorPre(pixels[i], &colors[i]);
++    }
++
++    xrSrcData.gradient = XRenderCreateLinearGradient(awt_display, &grad, &stops[0], &colors[0], numStops);
++    xrSrcData.src = xrSrcData.gradient;
++
++    XTransform tr;
++    BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
++    XRenderSetPictureTransform (awt_display, xrSrcData.gradient, &tr);
++
++    XRenderPictureAttributes pict_attr;
++    pict_attr.repeat = cycleMethod;
++    XRenderChangePicture (awt_display, xrSrcData.gradient, CPRepeat, &pict_attr);
++
++   (*env)->ReleasePrimitiveArrayCritical(env, pixelsArray, pixels, JNI_ABORT);
++   (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, fractions, JNI_ABORT);
++#endif /* !HEADLESS */
++}
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRSetRadialGradientPaint
++    (JNIEnv *env, jclass xsd, jfloatArray fractionsArray, jintArray pixelsArray, jint fx, jint numStops, jint cycleMethod, jboolean useMask, jboolean linear, jint innerRadius, jint outerRadius, jint m00, jint m01, jint m02, jint m10, jint m11, jint m12)
++{
++#ifndef HEADLESS
++   J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetRadialGradientPaint");
++   jint i;
++   jint* pixels;
++   jfloat* fractions;
++
++   if((pixels = (jint *) (*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) {
++     return;
++   }
++   if((fractions = (jfloat *) (*env)->GetPrimitiveArrayCritical(env, fractionsArray, NULL)) == NULL) {
++     return;
++   }
++
++   if(xrSrcData.gradient != None) {
++      XRenderFreePicture(awt_display, xrSrcData.gradient);
++      xrSrcData.gradient = None;
++   }
++
++    XRadialGradient grad;
++    XRenderColor colors[numStops];
++    XFixed stops[numStops];
++
++    grad.inner.x = 0;
++    grad.inner.y = 0;
++    grad.inner.radius = innerRadius;
++    grad.outer.x = 0;
++    grad.outer.y = 0;
++    grad.outer.radius = outerRadius;
++
++    for(i=0; i < numStops; i++) {
++      stops[i] = XDoubleToFixed(fractions[i]);
++      decodeRenderColorPre(pixels[i], &colors[i]);
++    }
++
++    xrSrcData.gradient = XRenderCreateRadialGradient(awt_display, &grad, &stops[0], &colors[0], numStops);
++    xrSrcData.src = xrSrcData.gradient;
++
++    XTransform tr;
++    BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
++    XRenderSetPictureTransform (awt_display, xrSrcData.gradient, &tr);
++
++    XRenderPictureAttributes pict_attr;
++    pict_attr.repeat = cycleMethod;
++    XRenderChangePicture (awt_display, xrSrcData.gradient, CPRepeat, &pict_attr);
++
++   (*env)->ReleasePrimitiveArrayCritical(env, pixelsArray, pixels, JNI_ABORT);
++   (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, fractions, JNI_ABORT);
++#endif /* !HEADLESS */
++}
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRSetTexturePaint
++    (JNIEnv *env, jclass xsd, jlong pXSData)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetTexturePaint");
++
++    X11SDOps *xsdo;
++    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++    if (xsdo == NULL) {
++        return;
++    }
++
++    xrSrcData.texture = xsdo->xrPic;
++    xrSrcData.src = xrSrcData.texture;
++#endif /* !HEADLESS */
++}
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRSetComposite
++    (JNIEnv *env, jclass xsd, jint compRule, jfloat eAlpha)
++{
++#ifndef HEADLESS
++  J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetComposite");
++
++  xrSrcData.compRule = compRule;
++  xrSrcData.extraAlpha = eAlpha;
++
++  if(eAlpha != 1.0f) {
++    unsigned short alphaValue = XDoubleToUShort(eAlpha);
++    xrSrcData.alphaColor.alpha = alphaValue;
++    xrSrcData.alphaColor.red = alphaValue;
++    xrSrcData.alphaColor.green = alphaValue;
++    xrSrcData.alphaColor.blue = alphaValue;
++    XRenderFillRectangle (awt_display, PictOpSrc, xrSrcData.alphaMaskPict, &xrSrcData.alphaColor, 0, 0, 1, 1);
++    xrSrcData.alphaMask = xrSrcData.alphaMaskPict;
++  }else {
++    xrSrcData.alphaMask = None;
++  }
++#endif /* !HEADLESS */
++}
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRSetClip
++    (JNIEnv *env, jclass xsd, jlong pXSData,
++     jint x1, jint y1, jint x2, jint y2,
++     jobject complexclip)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetClip");
++
++    int numrects;
++    XRectangle rects[256];
++    XRectangle *pRect = rects;
++    X11SDOps *xsdo;
++
++    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++    if (xsdo == NULL) {
++        return;
++    }
++
++    numrects = RegionToYXBandedRectangles(env,
++            x1, y1, x2, y2, complexclip,
++            &pRect, 256);
++
++
++     XRenderSetPictureClipRectangles (awt_display, xsdo->xrPic, 0, 0, pRect, numrects);
++
++    if (pRect != rects) {
++        free(pRect);
++    }
++#endif /* !HEADLESS */
++}
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRResetClip
++    (JNIEnv *env, jclass xsd, jlong pXSData)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRResetClip");
++    X11SDOps *xsdo;
++
++    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++    if (xsdo == NULL) {
++        return;
++    }
++
++    XRectangle clip;
++    clip.x = 0;
++    clip.y = 0;
++    clip.width = 32767;
++    clip.height = 32767;
++
++    XRenderSetPictureClipRectangles (awt_display, xsdo->xrPic, 0, 0, &clip, 1);
++#endif /* !HEADLESS */
++}
++
++
++	//private static native void XRSetTransform(long xsdo, double m00, double m01, double m02, double m10, double m11, double m12);
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRSetTransformNative
++    (JNIEnv *env, jclass xsd, jlong pXSData, jint m00, jint m01, jint m02, jint m10, jint m11, jint m12)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetTransformNative");
++    X11SDOps *xsdo;
++
++    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++    if (xsdo == NULL) {
++        return;
++    }
++
++    XTransform tr;
++    BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
++
++    XRenderSetPictureTransform (awt_display, xsdo->xrPic, &tr);
++#endif /* !HEADLESS */
++}
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRSetForeground
++    (JNIEnv *env, jclass xsd, jint pixel)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetForeground");
++
++    decodeRenderColor(pixel, &xrSrcData.solidColor);
++    XRenderFillRectangle (awt_display, PictOpSrc, xrSrcData.solid, &xrSrcData.solidColor, 0, 0, 1, 1);
++#endif /* !HEADLESS */
++}
++
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRSurfaceData_XRSetFilter
++    (JNIEnv *env, jclass xsd, jlong pXSData, jint filter)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRSetFilter");
++    X11SDOps *xsdo;
++
++    xsdo = (X11SDOps *) jlong_to_ptr(pXSData);
++    if (xsdo == NULL) {
++        return;
++    }
++
++    switch(filter)
++    {
++      case 0:
++        XRenderSetPictureFilter(awt_display, xsdo->xrPic, "fast", NULL, 0);
++        break;
++
++      case 1:
++        XRenderSetPictureFilter(awt_display, xsdo->xrPic, "good", NULL, 0);
++        break;
++
++      case 2:
++        XRenderSetPictureFilter(awt_display, xsdo->xrPic, "best", NULL, 0);
++        break;
++    }
++#endif /* !HEADLESS */
++}
++
++static void decodeRenderColor(jint pixel, XRenderColor *color)
++{ 
++   /*Extract color values from pixel, premultiply values. TODO: shouldn't this be done at the Java-level?*/
++    XFixed alpha = (((pixel & 0xFF000000) >> 16) + 255); /*REMIND: We rely on optimizations that this is 0xffff for opaque colors*/
++    XFixed red =   (((pixel & 0x00FF0000) >> 8)  + 255);
++    XFixed green = (((pixel & 0x0000FF00) >> 0)  + 255);
++    XFixed blue =  (((pixel & 0x000000FF) << 8)  + 255);
++
++    XDouble alphaMult = XFixedToDouble(alpha);
++    color->alpha = alpha;
++    color->red = (XFixed) red*alphaMult;
++    color->green = (XFixed) green*alphaMult;
++    color->blue = (XFixed) blue*alphaMult;
++}
++
++static void decodeRenderColorPre(jint pixel, XRenderColor *color)
++{ 
++    color->alpha = (((pixel & 0xFF000000) >> 16) + 255); /*REMIND: We rely on optimizations that this is 0xffff for opaque colors*/
++    color->red =   (((pixel & 0x00FF0000) >> 8)  + 255);
++    color->green = (((pixel & 0x0000FF00) >> 0)  + 255);
++    color->blue =  (((pixel & 0x000000FF) << 8)  + 255);
++}
+\ No newline at end of file
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,33 @@
++#ifndef XRSurfaceData_h_Included
++#define XRSurfaceData_h_Included
++
++#define XDoubleToUShort(f)    ((unsigned short) ((f) * 65535))
++
++typedef struct {
++  Picture src;
++  jboolean compRequired;
++  XRenderColor alphaColor;
++
++  Picture solid;
++  XRenderColor solidColor;
++  Picture texture;
++  Picture gradient;
++
++  jint compRule;
++  jfloat extraAlpha;
++  Picture alphaMask; //Only !None when eA turned on
++
++  Picture alphaMaskPict;
++  jboolean gradCacheEnabled;
++} SrcSurfaceData;
++
++extern SrcSurfaceData xrSrcData;
++extern MaskBuffer *maskBuffer;
++
++void XRComposite(Picture mask, Picture dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, unsigned int width, unsigned int height);
++
++static void decodeRenderColor(jint pixel, XRenderColor *color);
++
++static void decodeRenderColorPre(jint pixel, XRenderColor *color);
++
++#endif //XRSurfaceData_h_Included
+diff -r dc592ff5af5e jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c	Sat Nov 29 19:56:09 2008 +0100
+@@ -0,0 +1,171 @@
++/*
++ * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
++#include "GlyphImageRef.h"
++
++#ifdef HEADLESS
++#include "SurfaceData.h"
++#else
++#include "X11SurfaceData.h"
++#include "XRSurfaceData.h"
++#include "GraphicsPrimitiveMgr.h"
++#include "glyphblitting.h"
++#include "sunfontids.h"
++#include "fontscalerdefs.h"
++#include "AccelGlyphCache.h"
++#include "sunfontids.h"
++#include "XRGlyphCache.h"
++#include "Trace.h"
++#endif /* !HEADLESS */
++#include <jlong.h>
++
++#define TEXT_BM_WIDTH   1024
++#define TEXT_BM_HEIGHT  32
++
++
++#define FLOOR_ASSIGN(l, r)\
++ if ((r)<0) (l) = ((int)floor(r)); else (l) = ((int)(r))
++
++#ifndef HEADLESS
++static XRGlyphCacheInfo* grayCache = NULL;
++static XRGlyphCacheInfo* lcdCache = NULL;
++#endif
++
++JNIEXPORT void JNICALL
++XRT_DrawGlyphList(JNIEnv *env, jobject xtr,
++                 jlong dstData, jint numGlyphs, jboolean subPixPos, jboolean rgbOrder, jint lcdContrast,
++                 jboolean usePositions, jfloat xOrigin, jfloat yOrigin, jlong *images, jfloat *positions)
++{
++#ifndef HEADLESS
++  J2dTraceLn(J2D_TRACE_INFO, "XRTextRenderer_md: XRT_DrawGlyphList");
++
++  jint i;
++  jboolean grayscale = JNI_TRUE;
++
++  X11SDOps *xsdo = (X11SDOps *)jlong_to_ptr(dstData);
++  if (xsdo == NULL) {  
++      J2dTraceLn(J2D_TRACE_INFO, "XRTextRenderer_md: Destination-Pointer null!");
++      return;
++    }
++
++  if (numGlyphs > 0) {
++      GlyphInfo *ginfo = (GlyphInfo *)jlong_to_ptr(images[0]);
++      grayscale = (ginfo->rowBytes == ginfo->width);
++      subPixPos = subPixPos && (!grayscale);
++  }
++
++  if(grayCache == NULL && grayscale == JNI_TRUE) {
++    grayCache = XRGlyphCache_Init(XRenderFindStandardFormat(awt_display, PictStandardA8));
++  }else
++  if(lcdCache == NULL && grayscale == JNI_FALSE) {
++    lcdCache = XRGlyphCache_Init(XRenderFindStandardFormat(awt_display, PictStandardARGB32));
++  }
++
++   int eltCnt = -1;
++   jint ids[numGlyphs]; 
++   XGlyphElt32 elts[numGlyphs];
++
++   float advX = xOrigin; //xOrigin;/*Contains all advance-corrections summed up*/
++   float advY = yOrigin; //yOrigin; 
++   int oldPosX = 0, oldPosY = 0; /*Stored to be able to caluclate integer-advance to last glyph*/
++
++   if(subPixPos == JNI_TRUE) {
++     advX += 0.1666667f;
++     advY += 0.1666667f;
++   }else {
++     advX += 0.5f;
++     advY += 0.5f;
++  }
++
++   XRGlyphCacheInfo *glyphCache = (grayscale == JNI_TRUE) ?  grayCache : lcdCache;
++   jboolean cacheResult = XRGlyphCache_CacheGlyphs(glyphCache, images, numGlyphs, &ids[0]);
++   if(cacheResult == JNI_FALSE){
++      J2dTraceLn(J2D_TRACE_INFO, "XRTextRenderer_md: Glyph caching failed");
++      return;
++   }
++
++   for(i=0; i < numGlyphs; i++)
++   {
++      GlyphInfo *jginfo = (GlyphInfo *)jlong_to_ptr(images[i]);
++      XRCacheCellInfo *cellInfo = (XRCacheCellInfo *) jginfo->cellInfo;
++
++	/** If the cached and the required relative position is equal (implies integer value), we can reuse
++	 *  the existing ELT, and let XRender do the positioning.
++	 *  If it does not match the positioning information stored on the server, create a new ELT.
++	 *  advX/Y and posX/Y contain all advance-corrections summed up, so that we don't forget rounding errors happend in the past.
++         *  The actual advance is computed from the difference to the last integer-correction-position.
++         *  TODO: Spaeter mit cache vergleichen, statt einfach mit X-Werten
++	 */
++	int posX = 0, posY = 0;
++	if(usePositions || (jginfo->advanceX != ((float)cellInfo->xOff) || jginfo->advanceY != ((float)cellInfo->yOff)) || eltCnt == -1) 
++        {
++          /*Setup the next elt*/
++	  eltCnt++; 
++	  elts[eltCnt].glyphset = glyphCache->glyphSet;
++          elts[eltCnt].chars = (unsigned int*) &ids[i];
++	  elts[eltCnt].nchars = 1;
++
++  	  if(usePositions)
++	  {
++            /*In this case advX only stores rounding errors*/
++            jfloat x = positions[i*2] + advX;
++            jfloat y = positions[i*2 + 1] + advY;
++            FLOOR_ASSIGN(posX, x);
++            FLOOR_ASSIGN(posY, y);
++ 	    advX -= cellInfo->xOff;
++ 	    advY -= cellInfo->yOff;
++          }else
++          {
++	    /* 
++             * Calculate next glyph's position in the case of relative positioning.
++             * In XRender we can only position glyphs using integer coordinates, therefor
++             * we sum all the advances up as float, and convert them to integer later.
++             * This way rounding-error can be corrected,
++             * and is required to be consistent with the software loops.
++             */
++             FLOOR_ASSIGN(posX, advX);
++             FLOOR_ASSIGN(posY, advY);
++             //Advance of ELT = difference between stored relative positioning information and required float.
++	     advX += (jginfo->advanceX - cellInfo->xOff);
++	     advY += (jginfo->advanceY - cellInfo->yOff);
++          }
++
++            /*Offset of the current glyph is the difference to the last glyph and this one*/
++	    elts[eltCnt].xOff = (posX - oldPosX);
++	    elts[eltCnt].yOff = (posY - oldPosY);
++
++	    oldPosX = posX;
++	    oldPosY = posY;
++	}else
++	{
++           elts[eltCnt].nchars++;
++	}
++   }
++
++  /*TODO: Also integrate into MaskBuffer??*/
++  XRenderCompositeText32(awt_display, PictOpOver, xrSrcData.src, xsdo->xrPic, None, 0, 0, 0, 0, &elts[0], eltCnt+1);
++#endif
++}
++
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-002.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,5199 @@
+# HG changeset patch
+# User ceisserer
+# Date 1217623431 -7200
+# Node ID 4b11af86e814b7d62e9e1e19788d527987bb209c
+# Parent  6d294fa2bd421e3c8978730855d7300af692b271
+Summary: Comments, bug fixes, initial solaris work
+
+diff -r 6d294fa2bd42 -r 4b11af86e814 make/sun/xawt/Makefile
+--- openjdk/jdk/make/sun/xawt/Makefile	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/make/sun/xawt/Makefile	Fri Aug 01 22:43:51 2008 +0200
+@@ -86,7 +86,7 @@
+ vpath %.c   $(PLATFORM_SRC)/native/sun/java2d/opengl
+ vpath %.c   $(PLATFORM_SRC)/native/sun/java2d/x11
+ 
+-OTHER_LDLIBS = $(LIBM) -lawt -lXext -lX11 -lXrender -ldl \
++OTHER_LDLIBS = $(LIBM) -lawt -lXext -lX11 -lXrender -ldl -lm \
+                    $(LDFLAGS_COMMON) $(AWT_RUNPATH) $(OTHER_LDFLAGS) -lXtst -lXi
+ 
+ ifeq  ($(PLATFORM), solaris)
+diff -r 6d294fa2bd42 -r 4b11af86e814 make/sun/xawt/mapfile-vers
+--- openjdk/jdk/make/sun/xawt/mapfile-vers	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/make/sun/xawt/mapfile-vers	Fri Aug 01 22:43:51 2008 +0200
+@@ -314,6 +314,15 @@
+         Java_sun_java2d_opengl_GLXSurfaceData_initOps;
+         Java_sun_java2d_opengl_GLXSurfaceData_initPbuffer;
+ 
++        Java_sun_java2d_x11_XSurfaceData_initOps;
++        Java_sun_java2d_x11_XSurfaceData_XCreateGC;
++        Java_sun_java2d_x11_XSurfaceData_XResetClip;
++        Java_sun_java2d_x11_XSurfaceData_XSetClip;
++        Java_sun_java2d_x11_XSurfaceData_flushNativeSurface;
++	Java_sun_java2d_x11_XSurfaceData_isDrawableValid;
++        Java_sun_java2d_x11_XSurfaceData_setInvalid;
++        Java_sun_java2d_x11_XSurfaceData_XSetGraphicsExposures;
++
+         Java_sun_java2d_x11_X11PMBlitBgLoops_nativeBlitBg;
+         Java_sun_java2d_x11_X11PMBlitLoops_nativeBlit;
+         Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask;
+@@ -331,20 +340,12 @@
+ 	Java_sun_java2d_x11_X11Renderer_XFillRect;
+ 	Java_sun_java2d_x11_X11Renderer_XFillRoundRect;
+         Java_sun_java2d_x11_X11Renderer_devCopyArea;
+-        Java_sun_java2d_x11_X11SurfaceData_setInvalid;
+         Java_sun_java2d_x11_X11SurfaceData_initIDs;
+-	Java_sun_java2d_x11_X11SurfaceData_isDrawableValid;
+         Java_sun_java2d_x11_X11SurfaceData_isDgaAvailable;
+-        Java_sun_java2d_x11_X11SurfaceData_initOps;
+         Java_sun_java2d_x11_X11SurfaceData_initSurface;
+-        Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface;
+-        Java_sun_java2d_x11_X11SurfaceData_XCreateGC;
+-        Java_sun_java2d_x11_X11SurfaceData_XResetClip;
+-        Java_sun_java2d_x11_X11SurfaceData_XSetClip;
+         Java_sun_java2d_x11_X11SurfaceData_XSetCopyMode;
+         Java_sun_java2d_x11_X11SurfaceData_XSetXorMode;
+         Java_sun_java2d_x11_X11SurfaceData_XSetForeground;
+-        Java_sun_java2d_x11_X11SurfaceData_XSetGraphicsExposures;
+ 
+         Java_sun_java2d_xr_XRSurfaceData_flushNativeSurface;
+         Java_sun_java2d_xr_XRSurfaceData_XRIsDrawableValid;
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/font/XRTextRenderer.java
+--- openjdk/jdk/src/solaris/classes/sun/font/XRTextRenderer.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/font/XRTextRenderer.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -25,7 +25,7 @@
+ 
+ package sun.font;
+ 
+-import sun.awt.SunToolkit;
++import sun.awt.*;
+ import sun.java2d.SunGraphics2D;
+ import sun.java2d.pipe.GlyphListPipe;
+ import sun.java2d.xr.*;
+@@ -33,21 +33,22 @@
+ /**
+  * A delegate pipe of SG2D for drawing any text to a XRender surface
+  */
+-public class XRTextRenderer extends GlyphListPipe {
+-    
+-    native void doDrawGlyphList(long dstData, int numGlyphs, boolean subPixPos, boolean rgbOrder, int lcdContrast, boolean usePositions, float xOrigin, float yOrigin, long[] imgArray, float[] posArray);
+-    
+-    protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) 
+-    {
+-        try 
+-        {
+-            SunToolkit.awtLock();
+-            XRSurfaceData x11sd = (XRSurfaceData)sg2d.surfaceData;
+-    		x11sd.validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
+-            
+-            doDrawGlyphList(x11sd.getNativeOps(), gl.getNumGlyphs(), gl.isSubPixPos(), gl.isRGBOrder(), sg2d.lcdTextContrast, gl.usePositions(), gl.getX(), gl.getY(), gl.getImages(), gl.getPositions());
+-        } finally {
+-            SunToolkit.awtUnlock();
+-        }
+-    }
++public class XRTextRenderer extends GlyphListPipe
++{
++	native void doDrawGlyphList(long dstData, int numGlyphs, boolean subPixPos, boolean rgbOrder, int lcdContrast, boolean usePositions, float xOrigin, float yOrigin, long[] imgArray, float[] posArray);
++
++	protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl)
++	{
++		try
++		{
++			SunToolkit.awtLock();
++			XRSurfaceData x11sd = (XRSurfaceData) sg2d.surfaceData;
++			x11sd.validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
++
++			doDrawGlyphList(x11sd.getNativeOps(), gl.getNumGlyphs(), gl.isSubPixPos(), gl.isRGBOrder(), sg2d.lcdTextContrast, gl.usePositions(), gl.getX(), gl.getY(), gl.getImages(), gl.getPositions());
++		} finally
++		{
++			SunToolkit.awtUnlock();
++		}
++	}
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/x11/X11SurfaceData.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -60,7 +60,7 @@
+ import sun.java2d.pipe.TextPipe;
+ import sun.java2d.pipe.Region;
+ 
+-public abstract class X11SurfaceData extends SurfaceData {
++public abstract class X11SurfaceData extends XSurfaceData {
+     X11ComponentPeer peer;
+     X11GraphicsConfig graphicsConfig;
+     private RenderLoops solidloops;
+@@ -70,8 +70,6 @@
+     private static native void initIDs(Class xorComp, boolean tryDGA);  //OK
+     protected native void initSurface(int depth, int width, int height,
+                                       long drawable);
+-    native boolean isDrawableValid();
+-    protected native void flushNativeSurface();
+ 
+     public static final String
+         DESC_INT_BGR_X11        = "Integer BGR Pixmap";
+@@ -405,12 +403,6 @@
+                                         cm, drawable, transparency);
+     }
+ 
+-    /**
+-     * Initializes the native Ops pointer.
+-     */
+-    private native void initOps(X11ComponentPeer peer,
+-                                X11GraphicsConfig gc, int depth);
+-
+     protected X11SurfaceData(X11ComponentPeer peer,
+                              X11GraphicsConfig gc,
+                              SurfaceType sType,
+@@ -568,8 +560,6 @@
+         return sType;
+     }
+ 
+-    public native void setInvalid();
+-
+     public void invalidate() {
+         if (isValid()) {
+             setInvalid();
+@@ -581,18 +571,10 @@
+      * The following methods and variables are used to keep the Java-level
+      * context state in sync with the native X11 GC associated with this
+      * X11SurfaceData object.
+-     */
+-
+-    private static native long XCreateGC(long pXSData);
+-    private static native void XResetClip(long xgc);
+-    private static native void XSetClip(long xgc,
+-                                        int lox, int loy, int hix, int hiy,
+-                                        Region complexclip);
++     */ 
+     private static native void XSetCopyMode(long xgc);
+     private static native void XSetXorMode(long xgc);
+     private static native void XSetForeground(long xgc, int pixel);
+-    private static native void XSetGraphicsExposures(long xgc,
+-                                                     boolean needExposures);
+ 
+     private long xgc;
+     private Region validatedClip;
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/x11/XSurfaceData.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/src/solaris/classes/sun/java2d/x11/XSurfaceData.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -0,0 +1,35 @@
++package sun.java2d.x11;
++
++import java.awt.image.*;
++
++import sun.awt.*;
++import sun.java2d.*;
++import sun.java2d.loops.*;
++import sun.java2d.pipe.*;
++
++public abstract class XSurfaceData extends SurfaceData
++{
++	public XSurfaceData(SurfaceType surfaceType, ColorModel cm)
++	{
++		super(surfaceType, cm);
++	}
++	
++    protected native void initOps(X11ComponentPeer peer, X11GraphicsConfig gc, int depth);
++	
++    protected static native long XCreateGC(long pXSData);
++    
++    protected static native void XResetClip(long xgc);
++    
++    protected static native void XSetClip(long xgc,
++                                        int lox, int loy, int hix, int hiy,
++                                        Region complexclip);
++    
++    protected native void flushNativeSurface();
++    
++    protected native boolean isDrawableValid();
++    
++    protected native void setInvalid();
++    
++    protected static native void XSetGraphicsExposures(long xgc,
++            boolean needExposures);
++}
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRDrawImage.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -7,44 +7,36 @@
+ import sun.java2d.loops.*;
+ import sun.java2d.pipe.*;
+ 
+-
+ public class XRDrawImage extends DrawImage {
+ 
+     @Override
+     protected void renderImageXform(SunGraphics2D sg, Image img,
+-                                    AffineTransform tx, int interpType,
+-                                    int sx1, int sy1, int sx2, int sy2,
+-                                    Color bgColor)
+-    {    	
+-            SurfaceData dstData = sg.surfaceData;
+-            SurfaceData srcData =
+-                dstData.getSourceSurfaceData(img,
+-                                             sg.TRANSFORM_GENERIC,
+-                                             sg.imageComp,
+-                                             bgColor);
++	    AffineTransform tx, int interpType, int sx1, int sy1, int sx2,
++	    int sy2, Color bgColor) {
++	SurfaceData dstData = sg.surfaceData;
++	SurfaceData srcData = dstData.getSourceSurfaceData(img,
++		SunGraphics2D.TRANSFORM_GENERIC, sg.imageComp, bgColor);
+ 
+-            if (srcData != null && !isBgOperation(srcData, bgColor) && srcData instanceof XRSurfaceData)
+-            {
+-                SurfaceType srcType = srcData.getSurfaceType();
+-                SurfaceType dstType = dstData.getSurfaceType();
+-                
+-                ((XRSurfaceData) srcData).setPreferredInterpolation(XRUtils.ATransOpToXRQuality(interpType));
+-                
+-                TransformBlit blit = TransformBlit.getFromCache(srcType,
+-                                                                sg.imageComp,
+-                                                                dstType);
++	if (srcData != null && !isBgOperation(srcData, bgColor)
++		&& srcData instanceof XRSurfaceData) {
++	    SurfaceType srcType = srcData.getSurfaceType();
++	    SurfaceType dstType = dstData.getSurfaceType();
+ 
+-                if (blit != null) {
+-                    blit.Transform(srcData, dstData,
+-                                   sg.composite, sg.getCompClip(),
+-                                   tx, interpType,
+-                                   sx1, sy1, 0, 0, sx2-sx1, sy2-sy1);
+-                    return;
+-                }
+-       
+-        }
++	    ((XRSurfaceData) srcData).setPreferredInterpolation(XRUtils
++		    .ATransOpToXRQuality(interpType));
+ 
+-        super.renderImageXform(sg, img, tx, interpType,  sx1, sy1, sx2, sy2, bgColor);
++	    TransformBlit blit = TransformBlit.getFromCache(srcType,
++		    sg.imageComp, dstType);
++
++	    if (blit != null) {
++		blit.Transform(srcData, dstData, sg.composite,
++			sg.getCompClip(), tx, interpType, sx1, sy1, 0, 0, sx2
++				- sx1, sy2 - sy1);
++		return;
++	    }
++	}
++
++	super.renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2,
++		bgColor);
+     }
+ }
+-
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRGraphicsConfig.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -10,33 +10,31 @@
+ import sun.java2d.*;
+ 
+ /**
+- *
++ * Just a seperate
+  * @author ce
+  */
+-public class XRGraphicsConfig extends X11GraphicsConfig
+-implements SurfaceManager.ProxiedGraphicsConfig
+-{
+-	private XRGraphicsConfig(X11GraphicsDevice device, int visualnum, int depth, int colormap, boolean doubleBuffer)
+-    {
+-		super(device, visualnum, depth, colormap, doubleBuffer);
++public class XRGraphicsConfig extends X11GraphicsConfig implements
++	SurfaceManager.ProxiedGraphicsConfig {
++    private XRGraphicsConfig(X11GraphicsDevice device, int visualnum,
++	    int depth, int colormap, boolean doubleBuffer) {
++	super(device, visualnum, depth, colormap, doubleBuffer);
+     }
+-    
++
+     public SurfaceData createSurfaceData(X11ComponentPeer peer) {
+-        return XRSurfaceData.createData(peer);
++	return XRSurfaceData.createData(peer);
+     }
+-	
++
+     public static XRGraphicsConfig getConfig(X11GraphicsDevice device,
+-            int visualnum, int depth,
+-            int colormap, boolean doubleBuffer)
+-    {
+-        if (!X11GraphicsEnvironment.isXRenderAvailable()) {
+-            return null;
+-        }
+-        
+-        return new XRGraphicsConfig(device, visualnum, depth, colormap, doubleBuffer);
++	    int visualnum, int depth, int colormap, boolean doubleBuffer) {
++	if (!X11GraphicsEnvironment.isXRenderAvailable()) {
++	    return null;
++	}
++
++	return new XRGraphicsConfig(device, visualnum, depth, colormap,
++		doubleBuffer);
+     }
+-    
++
+     public Object getProxyKey() {
+-        return this;
++	return this;
+     }
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRMaskBlit.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -2,11 +2,9 @@
+ 
+ import static sun.java2d.loops.CompositeType.SrcNoEa;
+ import static sun.java2d.loops.CompositeType.SrcOver;
+-import static sun.java2d.loops.SurfaceType.IntArgb;
+ import static sun.java2d.loops.SurfaceType.IntArgbPre;
+ import static sun.java2d.loops.SurfaceType.IntRgb;
+ 
+-import java.awt.AlphaComposite;
+ import java.awt.Composite;
+ 
+ import sun.awt.*;
+@@ -14,58 +12,52 @@
+ import sun.java2d.loops.*;
+ import sun.java2d.pipe.Region;
+ 
+-public class XRMaskBlit extends MaskBlit
+-{
+-	static void register()
+-	{
+-		GraphicsPrimitive[] primitives = 
+-		{ 
+-				new XRMaskBlit(IntArgbPre, SrcOver, IntArgbPre), 
+-				new XRMaskBlit(IntRgb, SrcOver, IntRgb), 
+-				new XRMaskBlit(IntArgbPre, SrcNoEa, IntRgb), 
+-				new XRMaskBlit(IntRgb, SrcNoEa, IntArgbPre)
++/**
++ * For XRender there is no "blit", everything is just a fill with Repeat of Not.
++ * So basically this just quite the same as MaskFill.
++ * @author Clemens Eisserer
++ */
++public class XRMaskBlit extends MaskBlit {
++    static void register() {
++	GraphicsPrimitive[] primitives = {
++		new XRMaskBlit(IntArgbPre, SrcOver, IntArgbPre),
++		new XRMaskBlit(IntRgb, SrcOver, IntRgb),
++		new XRMaskBlit(IntArgbPre, SrcNoEa, IntRgb),
++		new XRMaskBlit(IntRgb, SrcNoEa, IntArgbPre) 
+ 		};
+-		GraphicsPrimitiveMgr.register(primitives);
++	GraphicsPrimitiveMgr.register(primitives);
++    }
++
++    public XRMaskBlit(SurfaceType srcType, CompositeType compType,
++	    SurfaceType dstType) {
++	super(srcType, CompositeType.AnyAlpha, dstType);
++    }
++
++    protected native void maskBlit(long srcXsdo, long dstxsdo, int srcx,
++	    int srcy, int dstx, int dsty, int w, int h, int maskoff,
++	    int maskscan, int masklen, byte[] mask);
++
++    public void MaskBlit(SurfaceData src, SurfaceData dst, Composite comp,
++	    Region clip, int srcx, int srcy, int dstx, int dsty, int width,
++	    int height, byte[] mask, int maskoff, int maskscan) {
++	if (width <= 0 || height <= 0) {
++	    return;
+ 	}
+ 
+-	public XRMaskBlit(SurfaceType srcType, CompositeType compType, SurfaceType dstType)
+-	{
+-		super(srcType, CompositeType.AnyAlpha, dstType);
++	try {
++	    SunToolkit.awtLock();
++
++	    XRSurfaceData x11sd = (XRSurfaceData) src;
++	    x11sd.validateAsSource(null, XRUtils.RepeatNone);
++
++	    XRSurfaceData x11dst = (XRSurfaceData) dst;
++	    x11dst.validate(clip, comp, null, null, null, 0);
++
++	    maskBlit(src.getNativeOps(), dst.getNativeOps(), srcx, srcy, dstx,
++		    dsty, width, height, maskoff, maskscan,
++		    mask != null ? mask.length : 0, mask);
++	} finally {
++	    SunToolkit.awtUnlock();
+ 	}
+-
+-	protected native void maskBlit(long srcXsdo, long dstxsdo, long alphaXsdo, int srcx, int srcy, int dstx, int dsty, int w, int h, int maskoff, int maskscan, int masklen, byte[] mask);
+-
+-	
+-	static XRSurfaceData alphaPM;
+-	static int alphaWidth = 0, alphaHeight = 0;
+-	public void MaskBlit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int srcx, int srcy, int dstx, int dsty, int width, int height, byte[] mask, int maskoff, int maskscan)
+-	{
+-		if (width <= 0 || height <= 0)
+-		{
+-			return;
+-		}
+-
+-		try
+-		{
+-			SunToolkit.awtLock();
+-			
+-			if (alphaPM == null || alphaWidth < width || alphaHeight < height)
+-			{
+-				alphaPM = XRSurfaceData.createData(((XRSurfaceData) dst).graphicsConfig, width, height);
+-				alphaWidth = width;
+-				alphaHeight = height;
+-			}
+-
+-			XRSurfaceData x11sd = (XRSurfaceData) src;
+-			x11sd.validateAsSource(null, XRUtils.RepeatNone);
+-			
+-			XRSurfaceData x11dst = (XRSurfaceData) dst;
+-			x11dst.validate(clip, comp, null, null, null, 0);
+-			
+-			maskBlit(src.getNativeOps(), dst.getNativeOps(), alphaPM.getNativeOps(), srcx, srcy, dstx, dsty, width, height, maskoff, maskscan, mask != null ? mask.length : 0, mask);
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
+-		}
+-	}
++    }
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRMaskFill.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -12,64 +12,75 @@
+ import static sun.java2d.loops.SurfaceType.OpaqueTexturePaint;
+ import static sun.java2d.loops.SurfaceType.RadialGradientPaint;
+ import static sun.java2d.loops.SurfaceType.TexturePaint;
+-import static sun.java2d.pipe.BufferedOpCodes.MASK_FILL;
+ 
+ import java.awt.*;
+-import java.awt.geom.*;
+-import java.awt.geom.Rectangle2D.Float;
+-import java.awt.image.*;
+-
+ import sun.awt.*;
+ import sun.java2d.*;
+ import sun.java2d.loops.*;
+-import sun.java2d.opengl.*;
+-import sun.java2d.pipe.*;
+ 
+-public class XRMaskFill extends MaskFill
+-{
+-	static void register()
+-	{
+-		GraphicsPrimitive[] primitives = { new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueColor, SrcNoEa, XRSurfaceData.IntRgbX11), new XRMaskFill(GradientPaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueGradientPaint, SrcNoEa, XRSurfaceData.IntRgbX11),
+-				new XRMaskFill(LinearGradientPaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueLinearGradientPaint, SrcNoEa, XRSurfaceData.IntRgbX11), new XRMaskFill(RadialGradientPaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueRadialGradientPaint, SrcNoEa, XRSurfaceData.IntRgbX11),
+-				new XRMaskFill(TexturePaint, SrcOver, XRSurfaceData.IntRgbX11), new XRMaskFill(OpaqueTexturePaint, SrcNoEa, XRSurfaceData.IntRgbX11),
++public class XRMaskFill extends MaskFill {
++    static void register() {
++	GraphicsPrimitive[] primitives = {
++		new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntRgbX11),
++		new XRMaskFill(OpaqueColor, SrcNoEa, XRSurfaceData.IntRgbX11),
++		new XRMaskFill(GradientPaint, SrcOver, XRSurfaceData.IntRgbX11),
++		new XRMaskFill(OpaqueGradientPaint, SrcNoEa,
++			XRSurfaceData.IntRgbX11),
++		new XRMaskFill(LinearGradientPaint, SrcOver,
++			XRSurfaceData.IntRgbX11),
++		new XRMaskFill(OpaqueLinearGradientPaint, SrcNoEa,
++			XRSurfaceData.IntRgbX11),
++		new XRMaskFill(RadialGradientPaint, SrcOver,
++			XRSurfaceData.IntRgbX11),
++		new XRMaskFill(OpaqueRadialGradientPaint, SrcNoEa,
++			XRSurfaceData.IntRgbX11),
++		new XRMaskFill(TexturePaint, SrcOver, XRSurfaceData.IntRgbX11),
++		new XRMaskFill(OpaqueTexturePaint, SrcNoEa,
++			XRSurfaceData.IntRgbX11),
+ 
+-				new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueColor, SrcNoEa, XRSurfaceData.IntArgbX11), new XRMaskFill(GradientPaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueGradientPaint, SrcNoEa, XRSurfaceData.IntArgbX11),
+-				new XRMaskFill(LinearGradientPaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueLinearGradientPaint, SrcNoEa, XRSurfaceData.IntArgbX11), new XRMaskFill(RadialGradientPaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueRadialGradientPaint, SrcNoEa, XRSurfaceData.IntArgbX11),
+-				new XRMaskFill(TexturePaint, SrcOver, XRSurfaceData.IntArgbX11), new XRMaskFill(OpaqueTexturePaint, SrcNoEa, XRSurfaceData.IntArgbX11) };
++		new XRMaskFill(AnyColor, SrcOver, XRSurfaceData.IntArgbX11),
++		new XRMaskFill(OpaqueColor, SrcNoEa, XRSurfaceData.IntArgbX11),
++		new XRMaskFill(GradientPaint, SrcOver, XRSurfaceData.IntArgbX11),
++		new XRMaskFill(OpaqueGradientPaint, SrcNoEa,
++			XRSurfaceData.IntArgbX11),
++		new XRMaskFill(LinearGradientPaint, SrcOver,
++			XRSurfaceData.IntArgbX11),
++		new XRMaskFill(OpaqueLinearGradientPaint, SrcNoEa,
++			XRSurfaceData.IntArgbX11),
++		new XRMaskFill(RadialGradientPaint, SrcOver,
++			XRSurfaceData.IntArgbX11),
++		new XRMaskFill(OpaqueRadialGradientPaint, SrcNoEa,
++			XRSurfaceData.IntArgbX11),
++		new XRMaskFill(TexturePaint, SrcOver, XRSurfaceData.IntArgbX11),
++		new XRMaskFill(OpaqueTexturePaint, SrcNoEa,
++			XRSurfaceData.IntArgbX11) 
++		};
+ 
+-		GraphicsPrimitiveMgr.register(primitives);
++	GraphicsPrimitiveMgr.register(primitives);
++    }
++
++    protected XRMaskFill(SurfaceType srcType, CompositeType compType,
++	    SurfaceType surfaceType) {
++	super(srcType, compType, surfaceType);
++    }
++
++    protected native void maskFill(long xsdo, int x, int y, int w, int h,
++	    int maskoff, int maskscan, int masklen, byte[] mask);
++
++    public void MaskFill(SunGraphics2D sg2d, SurfaceData sData, Composite comp,
++	    final int x, final int y, final int w, final int h,
++	    final byte[] mask, final int maskoff, final int maskscan) {
++	try {
++	    SunToolkit.awtLock();
++
++	    XRSurfaceData x11sd = (XRSurfaceData) sData;
++	    x11sd.validate(sg2d.getCompClip(), sg2d.getComposite(), sg2d
++		    .getTransform(), sg2d.getPaint(), sg2d, 0);
++
++	    maskFill(sData.getNativeOps(), x, y, w, h, maskoff, maskscan,
++		    mask != null ? mask.length : 0, mask);
++	} finally {
++	    SunToolkit.awtUnlock();
+ 	}
+-
+-	protected XRMaskFill(SurfaceType srcType, CompositeType compType, SurfaceType surfaceType)
+-	{
+-		super(srcType, compType, surfaceType);
+-	}
+-
+-	protected native void maskFill(long xsdo, long alphaXsdo, int x, int y, int w, int h, int maskoff, int maskscan, int masklen, byte[] mask);
+-
+-	static XRSurfaceData alphaPM;
+-	static int alphaWidth = 0, alphaHeight = 0;
+-
+-	public void MaskFill(SunGraphics2D sg2d, SurfaceData sData, Composite comp, final int x, final int y, final int w, final int h, final byte[] mask, final int maskoff, final int maskscan)
+-	{
+-		try
+-		{
+-			SunToolkit.awtLock();
+-
+-			XRSurfaceData x11sd = (XRSurfaceData) sData;
+-			x11sd.validate(sg2d.getCompClip(), sg2d.getComposite(), sg2d.getTransform(), sg2d.getPaint(), sg2d, 0);
+-
+-			if (alphaPM == null || alphaWidth < w || alphaHeight < h)
+-			{
+-				alphaPM = XRSurfaceData.createData(((XRSurfaceData) sData).graphicsConfig, w, h);
+-				alphaWidth = w;
+-				alphaHeight = h;
+-			}
+-
+-			maskFill(sData.getNativeOps(), alphaPM.getNativeOps(), x, y, w, h, maskoff, maskscan, mask != null ? mask.length : 0, mask);
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
+-		}
+-	}
++    }
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -27,180 +27,177 @@
+ 
+ import sun.awt.SunToolkit;
+ import sun.java2d.loops.*;
+-import sun.java2d.opengl.*;
+ import sun.java2d.pipe.Region;
+ import sun.java2d.SurfaceData;
+ import java.awt.*;
+ import java.awt.geom.*;
+-import java.awt.image.*;
+ 
+ /**
+- * X11PMBlitLoops
+- *
+- * This class accelerates Blits between two surfaces of types *PM.  Since
+- * the onscreen surface is of that type and some of the offscreen surfaces
+- * may be of that type (if they were created via X11OffScreenImage), then
+- * this type of Blit will accelerated double-buffer copies between those
+- * two surfaces.
+-*/
+-public class XRPMBlitLoops
+-{
++ * XRPMBlitLoops
++ * 
++ * This class accelerates Blits between two surfaces of types *PM.s
++ */
++public class XRPMBlitLoops {
+ 
+-	public static void register()
+-	{
+-		GraphicsPrimitive[] primitives = {
+-		
+-				new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11), new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11), new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
++    public static void register() {
++	GraphicsPrimitive[] primitives = {
+ 
+-				new X11PMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), new X11PMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11), new X11PMScaledBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11), new X11PMScaledBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
++		new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),
++		new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11),
++		new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11),
++		new X11PMBlit(XRSurfaceData.IntArgbX11,
++			XRSurfaceData.IntArgbX11),
+ 
+-				new X11PMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), new X11PMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11), new X11PMTransformedBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11), new X11PMTransformedBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntRgbX11,
++			XRSurfaceData.IntRgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntRgbX11,
++			XRSurfaceData.IntArgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntArgbX11,
++			XRSurfaceData.IntRgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntArgbX11,
++			XRSurfaceData.IntArgbX11),
+ 
+-				/*TODO Allow blits from argb surfaces too*/
+-		};
+-		GraphicsPrimitiveMgr.register(primitives);
+-	}
++		new X11PMTransformedBlit(XRSurfaceData.IntRgbX11,
++			XRSurfaceData.IntRgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntRgbX11,
++			XRSurfaceData.IntArgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntArgbX11,
++			XRSurfaceData.IntRgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntArgbX11,
++			XRSurfaceData.IntArgbX11),
++	};
++	GraphicsPrimitiveMgr.register(primitives);
++    }
+ 
+-	/**
+-	 * Blit
+-	 * This native method is where all of the work happens in the
+-	 * accelerated Blit.
+-	 */
+-	public static native void nativeRenderBlit(long srcData, long dstData, int sx, int sy, int dx, int dy, int w, int h);
+-
+-	static AffineTransform identityTransform = AffineTransform.getTranslateInstance(0, 0);
+-	static double[] tmpCoord = new double[4];
++    public static native void nativeRenderBlit(long srcData, long dstData,
++	    int sx, int sy, int dx, int dy, int w, int h);
+ }
+ 
+-class X11PMBlit extends Blit
+-{
+-	public X11PMBlit(SurfaceType srcType, SurfaceType dstType)
+-	{
+-		super(srcType, CompositeType.AnyAlpha, dstType);
++class X11PMBlit extends Blit {
++    public X11PMBlit(SurfaceType srcType, SurfaceType dstType) {
++	super(srcType, CompositeType.AnyAlpha, dstType);
++    }
++
++    public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
++	    Region clip, int sx, int sy, int dx, int dy, int w, int h) {
++	try {
++	    SunToolkit.awtLock();
++
++	    XRSurfaceData x11sdDst = (XRSurfaceData) dst;
++	    x11sdDst.validate(clip, comp, null, null, null, 0);
++	    XRSurfaceData x11sdSrc = (XRSurfaceData) src;
++
++	    x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);
++
++	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst
++		    .getNativeOps(), sx, sy, dx, dy, w, h);
++	} finally {
++	    SunToolkit.awtUnlock();
+ 	}
+-
+-	public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h)
+-	{
+-		try
+-		{
+-			SunToolkit.awtLock();
+-
+-			XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+-			x11sdDst.validate(clip, comp, null, null, null, 0);
+-			XRSurfaceData x11sdSrc = (XRSurfaceData) src;
+-	
+-			x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);
+-
+-			XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), sx, sy, dx, dy, w, h);
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
+-		}
+-	}
++    }
+ }
+ 
+-class X11PMScaledBlit extends ScaledBlit
+-{
+-	public X11PMScaledBlit(SurfaceType srcType, SurfaceType dstType)
+-	{
+-		super(srcType, CompositeType.AnyAlpha, dstType);
++class X11PMScaledBlit extends ScaledBlit {
++    public X11PMScaledBlit(SurfaceType srcType, SurfaceType dstType) {
++	super(srcType, CompositeType.AnyAlpha, dstType);
++    }
++
++    public void Scale(SurfaceData src, SurfaceData dst, Composite comp,
++	    Region clip, int sx1, int sy1, int sx2, int sy2, double dx1,
++	    double dy1, double dx2, double dy2) {
++	try {
++	    SunToolkit.awtLock();
++
++	    XRSurfaceData x11sdDst = (XRSurfaceData) dst;
++	    x11sdDst.validate(clip, comp, null, null, null, 0);
++	    XRSurfaceData x11sdSrc = (XRSurfaceData) src;
++
++	    double xScale = (dx2 - dx1) / (sx2 - sx1);
++	    double yScale = (dy2 - dy1) / (sy2 - sy1);
++
++	    sx1 *= xScale;
++	    sx2 *= xScale;
++	    sy1 *= yScale;
++	    sy2 *= yScale;
++
++	    AffineTransform xForm = AffineTransform.getScaleInstance(
++		    1 / xScale, 1 / yScale);
++
++	    x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST);
++
++	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst
++		    .getNativeOps(), (int) sx1, (int) sy1, (int) dx1,
++		    (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));
++
++	} finally {
++	    SunToolkit.awtUnlock();
+ 	}
+-
+-	public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1, double dx2, double dy2)
+-	{
+-		try
+-		{
+-			SunToolkit.awtLock();
+-
+-			XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+-			x11sdDst.validate(clip, comp, null, null, null, 0);
+-			XRSurfaceData x11sdSrc = (XRSurfaceData) src;
+-
+-			double xScale = (dx2 - dx1) / (sx2 - sx1);
+-			double yScale = (dy2 - dy1) / (sy2 - sy1);
+-
+-			sx1 *= xScale;
+-			sx2 *= xScale;
+-			sy1 *= yScale;
+-			sy2 *= yScale;
+-
+-			AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale);
+-
+-			x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST);
+-
+-			XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));
+-
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
+-		}
+-	}
++    }
+ }
+ 
+ /**
+  * Called also if scale+transform is set
++ * 
+  * @author Clemens Eisserer
+  */
+-class X11PMTransformedBlit extends TransformBlit
+-{
+-	public X11PMTransformedBlit(SurfaceType srcType, SurfaceType dstType)
+-	{
+-		super(srcType, CompositeType.AnyAlpha, dstType);
++class X11PMTransformedBlit extends TransformBlit {
++    public X11PMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
++	super(srcType, CompositeType.AnyAlpha, dstType);
++    }
++
++    public void Transform(SurfaceData src, SurfaceData dst, Composite comp,
++	    Region clip, AffineTransform xform, int hint, int srcx, int srcy,
++	    int dstx, int dsty, int width, int height) {
++	try {
++	    SunToolkit.awtLock();
++
++	    XRSurfaceData x11sdDst = (XRSurfaceData) dst;
++	    x11sdDst.validate(clip, comp, null, null, null, 0);
++	    XRSurfaceData x11sdSrc = (XRSurfaceData) src;
++
++	    boolean needClip = (xform.getScaleX() != 0.0f)
++		    || (xform.getShearY() != 0.0f);
++	    try {
++		/* Calculate area which will be covered by the transform-blit */
++		Rectangle2D.Float rect = new Rectangle2D.Float(dstx, dsty,
++			width, height);
++		Shape shp = xform.createTransformedShape(rect);
++		Rectangle bounds = shp.getBounds();
++
++		AffineTransform sourceTrans = (AffineTransform) xform.clone();
++		sourceTrans.translate(-srcx, -srcy);
++
++		try
++		{
++		     sourceTrans.invert();
++		}catch(NoninvertibleTransformException ex)
++		{
++		    sourceTrans.setToIdentity();
++		}
++
++		x11sdSrc.validateAsSource(sourceTrans, XRUtils.RepeatNone);
++
++		if (needClip) {
++		    x11sdDst.setShapeClip(shp);
++		}
++
++		XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst
++			.getNativeOps(), 0, 0, 0, 0, bounds.x + bounds.width,
++			bounds.y + bounds.height);// bounds.x, bounds.y,
++						    // bounds.width,
++						    // bounds.height);//(int)
++						    // (maxX - minX), (int)
++						    // (maxY - minY));
++
++		if (needClip) {
++		    x11sdDst.resetShapeClip();
++		}
++
++	    } catch (Exception ex) {
++		ex.printStackTrace();
++	    }
++	} finally {
++	    SunToolkit.awtUnlock();
+ 	}
+-
+-	public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy, int dstx, int dsty, int width, int height)
+-	{
+-		try
+-		{			
+-			SunToolkit.awtLock();
+-
+-			XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+-			x11sdDst.validate(clip, comp, null, null, null, 0);
+-			XRSurfaceData x11sdSrc = (XRSurfaceData) src;
+-
+-			boolean needClip =  (xform.getScaleX() != 0.0f) || (xform.getShearY() != 0.0f);
+-			try
+-			{				
+-				/*Calculate area which will be covered by the transform-blit*/
+-				Rectangle2D.Float rect = new Rectangle2D.Float(dstx, dsty, width, height);
+-				Shape shp = xform.createTransformedShape(rect);
+-				Rectangle bounds = shp.getBounds();
+-				
+-				AffineTransform sourceTrans = (AffineTransform) xform.clone();
+-				sourceTrans.translate(-srcx, -srcy);
+-			
+-//				System.out.println("srcx "+srcx+" srcy:"+srcy+" dstx:"+dstx+" dsty:"+dsty+" width:"+width+" height:"+height);
+-//				System.out.println("Dest-Translation: x:"+xform.getTranslateX()+" y:"+xform.getTranslateY());
+-				
+-				//AffineTransform sourceTransform = new AffineTransform(xform.getScaleX(), xform.getShearY(), xform.getShearX(), xform.getScaleY(), 0, 0);
+-				//sourceTransform.translate(-srcx, -srcy);
+-				
+-				sourceTrans.invert();
+-			    
+-				
+-			    //x11sdSrc.validateAsSource(sourceTrans, XRUtils.RepeatPad); /*Pad avoids smearing, but falls back to software*/
+-				x11sdSrc.validateAsSource(sourceTrans, XRUtils.RepeatNone);
+-
+-				
+-				if(needClip)
+-				{
+-			        x11sdDst.setShapeClip(shp);
+-				}
+-				
+-			    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), 0, 0, 0, 0, bounds.x + bounds.width, bounds.y + bounds.height);// bounds.x, bounds.y, bounds.width, bounds.height);//(int) (maxX - minX), (int) (maxY - minY));
+-		
+-			    if(needClip)
+-			    {
+-			        x11sdDst.resetShapeClip();
+-			    }
+-			   
+-			} catch (Exception ex)
+-			{
+-				ex.printStackTrace();
+-			}
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
+-		}
+-	}
++    }
+ }
+\ No newline at end of file
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRRenderer.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -13,243 +13,222 @@
+ import sun.java2d.pipe.ShapeSpanIterator;
+ import sun.java2d.pipe.LoopPipe;
+ 
+-public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe
+-{
+-	public XRRenderer()
+-	{}
++/**
++ * XRender provides only accalerated rectangles and lines with some tricks.
++ * To emulate higher geometry we have to pass everything else to DoPath/FillSpans.
++ * 
++ * TODO: DrawRect could be instrified
++ * @author Clemens Eisserer
++ */
+ 
+-	public static XRRenderer getInstance()
+-	{
+-		return new XRRenderer();
+-		//	return (GraphicsPrimitive.tracingEnabled() ? new X11TracingRenderer() : new X11Renderer());
++public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
++    public XRRenderer() {
++    }
++
++    public static XRRenderer getInstance() {
++	return new XRRenderer();
++    }
++
++    /**
++     * Common validate method, used by all XRRender functions to
++     * validate the destination context.
++     */
++    private final void validate(SunGraphics2D sg2d) {
++	XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
++	xrsd.validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform,
++		sg2d.paint, sg2d, 0);
++    }
++
++    native void XRDrawLine(long pXSData, int x1, int y1, int x2, int y2);
++
++    public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) {
++	try {
++	    SunToolkit.awtLock();
++
++	    validate(sg2d);
++	    int transx = sg2d.transX;
++	    int transy = sg2d.transY;
++	    XRDrawLine(sg2d.surfaceData.getNativeOps(), x1 + transx, y1
++		    + transy, x2 + transx, y2 + transy);
++	} finally {
++	    SunToolkit.awtUnlock();
++	}
++    }
++
++    public void drawRect(SunGraphics2D sg2d, int x, int y, int width, int height) {
++	draw(sg2d, new Rectangle2D.Float(x, y, width, height));
++    }
++
++    public void drawPolyline(SunGraphics2D sg2d, int xpoints[], int ypoints[],
++	    int npoints) {
++	Path2D.Float p2d = new Path2D.Float();
++	if (npoints > 1) {
++	    p2d.moveTo(xpoints[0], ypoints[0]);
++	    for (int i = 1; i < npoints; i++) {
++		p2d.lineTo(xpoints[i], ypoints[i]);
++	    }
+ 	}
+ 
+-	private final void validate(SunGraphics2D sg2d)
+-	{
+-		// NOTE: getCompClip() will revalidateAll() if the
+-		// surfaceData is invalid.  This should ensure that
+-		// the clip and pixel that we are validating against
+-		// are the most current.
+-		//
+-		// The assumption is that the pipeline after that
+-		// revalidation will either be another X11 pipe
+-		// (because the drawable format never changes on X11)
+-		// or a null pipeline if the surface is disposed.
+-		//
+-		// Since we do not get the ops structure of the SurfaceData
+-		// until the actual call down to the native level we will
+-		// pick up the most recently validated copy.
+-		// Note that if the surface is disposed, a NullSurfaceData
+-		// (with null native data structure) will be set in
+-		// sg2d, so we have to protect against it in native code.
++	draw(sg2d, p2d);
++    }
+ 
+-		XRSurfaceData x11sd = (XRSurfaceData) sg2d.surfaceData;
+-		x11sd.validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
++    public void drawPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[],
++	    int npoints) {
++	draw(sg2d, new Polygon(xpoints, ypoints, npoints));
++    }
++
++    native void XRFillRect(long pXSData, int x, int y, int width, int height);
++
++    public void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height) {
++	SunToolkit.awtLock();
++	try {
++	    validate(sg2d);
++
++	    x += sg2d.transform.getTranslateX();
++	    y += sg2d.transform.getTranslateY();
++	    XRFillRect(sg2d.surfaceData.getNativeOps(), x, y, width, height);
++	} finally {
++	    SunToolkit.awtUnlock();
++	}
++    }
++
++    public void fillPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[],
++	    int npoints) {
++	fill(sg2d, new Polygon(xpoints, ypoints, npoints));
++    }
++
++    public void drawRoundRect(SunGraphics2D sg2d, int x, int y, int width,
++	    int height, int arcWidth, int arcHeight) {
++	draw(sg2d, new RoundRectangle2D.Float(x, y, width, height, arcWidth,
++		arcHeight));
++    }
++
++    public void fillRoundRect(SunGraphics2D sg2d, int x, int y, int width,
++	    int height, int arcWidth, int arcHeight) {
++	fill(sg2d, new RoundRectangle2D.Float(x, y, width, height, arcWidth,
++		arcHeight));
++    }
++
++    public void drawOval(SunGraphics2D sg2d, int x, int y, int width, int height) {
++	draw(sg2d, new Ellipse2D.Float(x, y, width, height));
++    }
++
++    public void fillOval(SunGraphics2D sg2d, int x, int y, int width, int height) {
++	fill(sg2d, new Ellipse2D.Float(x, y, width, height));
++    }
++
++    public void drawArc(SunGraphics2D sg2d, int x, int y, int width,
++	    int height, int startAngle, int arcAngle) {
++	draw(sg2d, new Arc2D.Float(x, y, width, height, startAngle, arcAngle,
++		Arc2D.OPEN));
++    }
++
++    public void fillArc(SunGraphics2D sg2d, int x, int y, int width,
++	    int height, int startAngle, int arcAngle) {
++	fill(sg2d, new Arc2D.Float(x, y, width, height, startAngle, arcAngle,
++		Arc2D.PIE));
++    }
++
++    native void XRFillSpans(long pXSData, SpanIterator si, long iterator,
++	    int transx, int transy);
++
++    native void XRDoPath(SunGraphics2D sg2d, long pXSData, int transX,
++	    int transY, Path2D.Float p2df, boolean isFill);
++
++    private void doPath(SunGraphics2D sg2d, Shape s, boolean isFill) {
++	Path2D.Float p2df;
++	int transx, transy;
++	if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE) {
++	    if (s instanceof Path2D.Float) {
++		p2df = (Path2D.Float) s;
++	    } else {
++		p2df = new Path2D.Float(s);
++	    }
++	    transx = sg2d.transX;
++	    transy = sg2d.transY;
++	} else {
++	    p2df = new Path2D.Float(s, sg2d.transform);
++	    transx = 0;
++	    transy = 0;
+ 	}
+ 
+-	native void XRDrawLine(long pXSData, int x1, int y1, int x2, int y2);
++	try {
++	    SunToolkit.awtLock();
++	    validate(sg2d);
++	    XRDoPath(sg2d, sg2d.surfaceData.getNativeOps(), transx, transy,
++		    p2df, isFill);
++	} finally {
++	    SunToolkit.awtUnlock();
++	}
++    }
+ 
+-	public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2)
+-	{
+-		try
+-		{
+-			SunToolkit.awtLock();
+-			
+-			validate(sg2d);
+-			int transx = sg2d.transX;
+-			int transy = sg2d.transY;
+-			XRDrawLine(sg2d.surfaceData.getNativeOps(), x1 + transx, y1 + transy, x2 + transx, y2 + transy);
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
+-		}
++    public void draw(SunGraphics2D sg2d, Shape s) {
++
++	if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
++	    doPath(sg2d, s, false);
++	    return;
+ 	}
+ 
+-	public void drawRect(SunGraphics2D sg2d, int x, int y, int width, int height)
+-	{
+-		draw(sg2d, new Rectangle2D.Float(x, y, width, height));
++	if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM) {
++	    ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
++	    try {
++		try {
++		    SunToolkit.awtLock();
++		    validate(sg2d);
++		    XRFillSpans(sg2d.surfaceData.getNativeOps(), si, si
++			    .getNativeIterator(), 0, 0);
++		} finally {
++		    SunToolkit.awtUnlock();
++		}
++	    } finally {
++		si.dispose();
++	    }
++	} else {
++	    fill(sg2d, sg2d.stroke.createStrokedShape(s));
++	}
++    }
++
++    public void fill(SunGraphics2D sg2d, Shape s) {
++	if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
++	    doPath(sg2d, s, true);
++	    return;
+ 	}
+ 
+-	public void drawPolyline(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
+-	{
+-		throw new RuntimeException("Not implemented");
++	AffineTransform at;
++	int transx, transy;
++	if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
++	    // Transform (translation) will be done by XFillSpans
++	    at = null;
++	    transx = sg2d.transX;
++	    transy = sg2d.transY;
++	} else {
++	    // Transform will be done by the PathIterator
++	    at = sg2d.transform;
++	    transx = transy = 0;
+ 	}
+ 
+-	public void drawPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
+-	{
+-		draw(sg2d, new Polygon(xpoints, ypoints, npoints));
++	ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
++	try {
++	    // Subtract transx/y from the SSI clip to match the
++	    // (potentially untranslated) geometry fed to it
++	    Region clip = sg2d.getCompClip();
++	    ssi.setOutputAreaXYXY(clip.getLoX() - transx, clip.getLoY()
++		    - transy, clip.getHiX() - transx, clip.getHiY() - transy);
++	    ssi.appendPath(s.getPathIterator(at));
++	    try {
++		SunToolkit.awtLock();
++
++		validate(sg2d);
++		XRFillSpans(sg2d.surfaceData.getNativeOps(), ssi, ssi
++			.getNativeIterator(), transx, transy);
++	    } finally {
++		SunToolkit.awtUnlock();
++	    }
++	} finally {
++	    ssi.dispose();
+ 	}
++    }
+ 
+-	native void XRFillRect(long pXSData, int x, int y, int width, int height);
+-
+-	public void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height)
+-	{
+-		SunToolkit.awtLock();
+-		try
+-		{
+-			validate(sg2d);
+-
+-			x += sg2d.transform.getTranslateX();
+-			y += sg2d.transform.getTranslateY();
+-			XRFillRect(sg2d.surfaceData.getNativeOps(), x, y, width, height);
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
+-		}
+-	}
+-
+-	public void fillPolygon(SunGraphics2D sg2d, int xpoints[], int ypoints[], int npoints)
+-	{
+-		fill(sg2d, new Polygon(xpoints, ypoints, npoints));
+-	}
+-
+-	public void drawRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight)
+-	{
+-		draw(sg2d, new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
+-	}
+-
+-	public void fillRoundRect(SunGraphics2D sg2d, int x, int y, int width, int height, int arcWidth, int arcHeight)
+-	{
+-		fill(sg2d, new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
+-	}
+-
+-	public void drawOval(SunGraphics2D sg2d, int x, int y, int width, int height)
+-	{
+-		draw(sg2d, new Ellipse2D.Float(x, y, width, height));
+-	}
+-
+-	public void fillOval(SunGraphics2D sg2d, int x, int y, int width, int height)
+-	{
+-		fill(sg2d, new Ellipse2D.Float(x, y, width, height));
+-	}
+-
+-	public void drawArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle)
+-	{
+-		draw(sg2d, new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.OPEN));
+-	}
+-
+-	public void fillArc(SunGraphics2D sg2d, int x, int y, int width, int height, int startAngle, int arcAngle)
+-	{
+-		fill(sg2d, new Arc2D.Float(x, y, width, height, startAngle, arcAngle, Arc2D.PIE));
+-	}
+-
+-	native void XRFillSpans(long pXSData, SpanIterator si, long iterator, int transx, int transy);
+-
+-	native void XRDoPath(SunGraphics2D sg2d, long pXSData, int transX, int transY, Path2D.Float p2df, boolean isFill);
+-
+-	private void doPath(SunGraphics2D sg2d, Shape s, boolean isFill)
+-	{
+-		Path2D.Float p2df;
+-		int transx, transy;
+-		if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE)
+-		{
+-			if (s instanceof Path2D.Float)
+-			{
+-				p2df = (Path2D.Float) s;
+-			} else
+-			{
+-				p2df = new Path2D.Float(s);
+-			}
+-			transx = sg2d.transX;
+-			transy = sg2d.transY;
+-		} else
+-		{
+-			p2df = new Path2D.Float(s, sg2d.transform);
+-			transx = 0;
+-			transy = 0;
+-		}
+-		
+-		try
+-		{
+-			SunToolkit.awtLock();
+-			validate(sg2d);
+-			XRDoPath(sg2d, sg2d.surfaceData.getNativeOps(), transx, transy, p2df, isFill);
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
+-		}
+-	}
+-
+-	public void draw(SunGraphics2D sg2d, Shape s)
+-	{
+-
+-		if (sg2d.strokeState == sg2d.STROKE_THIN)
+-		{
+-			doPath(sg2d, s, false);
+-			return;
+-		}
+-		
+-		if (sg2d.strokeState < sg2d.STROKE_CUSTOM)
+-		{
+-			ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
+-			try
+-			{
+-				try
+-				{
+-					SunToolkit.awtLock();
+-					validate(sg2d);
+-					XRFillSpans(sg2d.surfaceData.getNativeOps(), si, si.getNativeIterator(), 0, 0);
+-				} finally
+-				{
+-					SunToolkit.awtUnlock();
+-				}
+-			} finally
+-			{
+-				si.dispose();
+-			}
+-		} else
+-		{
+-			fill(sg2d, sg2d.stroke.createStrokedShape(s));
+-		}
+-	}
+-
+-	public void fill(SunGraphics2D sg2d, Shape s)
+-	{
+-		if (sg2d.strokeState == sg2d.STROKE_THIN)
+-		{
+-			doPath(sg2d, s, true);
+-			return;
+-		}
+-
+-		AffineTransform at;
+-		int transx, transy;
+-		if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE)
+-		{
+-			// Transform (translation) will be done by XFillSpans
+-			at = null;
+-			transx = sg2d.transX;
+-			transy = sg2d.transY;
+-		} else
+-		{
+-			// Transform will be done by the PathIterator
+-			at = sg2d.transform;
+-			transx = transy = 0;
+-		}
+-
+-		ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
+-		try
+-		{
+-			// Subtract transx/y from the SSI clip to match the
+-			// (potentially untranslated) geometry fed to it
+-			Region clip = sg2d.getCompClip();
+-			ssi.setOutputAreaXYXY(clip.getLoX() - transx, clip.getLoY() - transy, clip.getHiX() - transx, clip.getHiY() - transy);
+-			ssi.appendPath(s.getPathIterator(at));
+-			try
+-			{
+-				SunToolkit.awtLock();
+-				
+-				validate(sg2d);
+-				XRFillSpans(sg2d.surfaceData.getNativeOps(), ssi, ssi.getNativeIterator(), transx, transy);
+-			} finally
+-			{
+-				SunToolkit.awtUnlock();
+-			}
+-		} finally
+-		{
+-			ssi.dispose();
+-		}
+-	}
+-
+-	native void devCopyArea(long sdOps, long xgc, int srcx, int srcy, int dstx, int dsty, int w, int h);
+-
++    native void devCopyArea(long sdOps, long xgc, int srcx, int srcy, int dstx,
++	    int dsty, int w, int h);
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRSurfaceData.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -31,7 +31,6 @@
+ import java.awt.geom.*;
+ import java.awt.image.*;
+ import sun.awt.*;
+-import sun.awt.image.PixelConverter;
+ import sun.font.*;
+ import sun.java2d.InvalidPipeException;
+ import sun.java2d.SunGraphics2D;
+@@ -39,979 +38,931 @@
+ import sun.java2d.SurfaceDataProxy;
+ import sun.java2d.loops.*;
+ import sun.java2d.pipe.*;
++import sun.java2d.x11.*;
+ import static sun.java2d.xr.XRUtils.XDoubleToFixed;
+ 
+-public abstract class XRSurfaceData extends SurfaceData
+-{
+-	X11ComponentPeer peer;
+-	XRGraphicsConfig graphicsConfig;
+-	private RenderLoops solidloops;
++public abstract class XRSurfaceData extends XSurfaceData {
++    X11ComponentPeer peer;
++    XRGraphicsConfig graphicsConfig;
++    private RenderLoops solidloops;
+ 
+-	protected int depth;
++    protected int depth;
+ 
+-	private static native void initIDs(boolean gradCache);
++    private static native void initIDs(boolean gradCache);
+ 
+-	protected native void XRInitSurface(int depth, int width, int height, long drawable, int pictFormat);
++    protected native void XRInitSurface(int depth, int width, int height,
++	    long drawable, int pictFormat);
+ 
+-	native boolean XRIsDrawableValid();
++    native void XRInitXRender(long xsdo, int pictForm);
+ 
+-	protected native void flushNativeSurface();
++    public static final String DESC_BYTE_A8_X11 = "Byte A8 Pixmap";
++    public static final String DESC_INT_RGB_X11 = "Integer RGB Pixmap";
++    public static final String DESC_INT_ARGB_X11 = "Integer ARGB-Pre Pixmap";
+ 
+-	native void XRInitXRender(long xsdo, int pictForm);
++    public static final SurfaceType ByteA8X11 = SurfaceType.ByteGray.deriveSubType(DESC_BYTE_A8_X11);
++    public static final SurfaceType IntRgbX11 = SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_X11);
++    public static final SurfaceType IntArgbX11 = SurfaceType.IntArgbPre.deriveSubType(DESC_INT_ARGB_X11);
+ 
+-	public static final String DESC_BYTE_A8_X11 = "Byte A8 Pixmap";
+-	public static final String DESC_INT_RGB_X11 = "Integer RGB Pixmap";
+-	public static final String DESC_INT_ARGB_X11 = "Integer ARGB-Pre Pixmap";
++    public Raster getRaster(int x, int y, int w, int h) {
++	throw new InternalError("not implemented yet");
++    }
+ 
+-	public static final SurfaceType ByteA8X11 = SurfaceType.ByteGray.deriveSubType(DESC_BYTE_A8_X11);
+-	public static final SurfaceType IntRgbX11 = SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_X11);
+-	public static final SurfaceType IntArgbX11 = SurfaceType.IntArgbPre.deriveSubType(DESC_INT_ARGB_X11);
++    protected XRRenderer xrpipe;
++    protected PixelToShapeConverter xrtxpipe;
++    protected TextPipe xrtextpipe;
++    protected XRDrawImage xrDrawImage;
+ 
+-	public Raster getRaster(int x, int y, int w, int h)
+-	{
+-		throw new InternalError("not implemented yet");
++    public static void initXRSurfaceData() {
++	if (!X11GraphicsEnvironment.isX11SurfaceDataInitialized()) {
++	    boolean cacheGradients = true;
++	    String xProp = System.getProperty("sun.java2d.xrgradcache");
++	    if (xProp != null) {
++		cacheGradients = !(xProp.equalsIgnoreCase("false") || xProp.equalsIgnoreCase("f"));
++	    }
++	    initIDs(cacheGradients);
++
++	    XRPMBlitLoops.register();
++	    XRMaskFill.register();
++	    XRMaskBlit.register();
++
++	    X11GraphicsEnvironment.setX11SurfaceDataInitialized();
++	}
++    }
++
++    /**
++     * Synchronized accessor method for isDrawableValid.
++     */
++    protected boolean isXRDrawableValid() {
++	try {
++	    SunToolkit.awtLock();
++	    return isDrawableValid();
++	} finally {
++	    SunToolkit.awtUnlock();
++	}
++    }
++
++    @Override
++    public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
++	return XRSurfaceDataProxy.createProxy(srcData, graphicsConfig);
++    }
++
++    public void validatePipe(SunGraphics2D sg2d) {
++	TextPipe textpipe;
++	boolean validated = false;
++
++	/* The textpipe for now can't handle TexturePaint when extra-alpha is specified nore XOR mode*/
++	if (sg2d.compositeState < SunGraphics2D.COMP_XOR
++		&& (sg2d.paintState < SunGraphics2D.PAINT_TEXTURE
++		|| sg2d.composite == null
++		|| !(sg2d.composite instanceof AlphaComposite)
++		|| ((AlphaComposite) sg2d.composite).getAlpha() == 1.0f)) {
++	    textpipe = xrtextpipe;
++	} else {
++	    super.validatePipe(sg2d);
++	    textpipe = sg2d.textpipe;
++	    validated = true;
+ 	}
+ 
+-	protected XRRenderer x11pipe;
+-	protected PixelToShapeConverter x11txpipe;
+-	protected TextPipe x11textpipe;
+-	protected XRDrawImage xrDrawImage;
++	PixelToShapeConverter txPipe = null;
++	XRRenderer nonTxPipe = null;
+ 
+-	public static void initXRSurfaceData()
+-	{
+-		if (!X11GraphicsEnvironment.isX11SurfaceDataInitialized())
+-		{
+-			boolean cacheGradients = true;
+-			String xProp = System.getProperty("sun.java2d.xrgradcache");
+-			if (xProp != null)
+-			{
+-				cacheGradients = !(xProp.equalsIgnoreCase("false") || xProp.equalsIgnoreCase("f"));
+-			}
+-
+-			initIDs(cacheGradients);
+-
+-			XRPMBlitLoops.register();
+-			XRMaskFill.register();
+-			XRMaskBlit.register();
+-
+-			X11GraphicsEnvironment.setX11SurfaceDataInitialized();
++	if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) {
++	    if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
++		if (sg2d.compositeState < SunGraphics2D.COMP_XOR) {
++		    txPipe = xrtxpipe;
++		    nonTxPipe = xrpipe;
+ 		}
++	    } else if (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
++		if (isPaintValid(sg2d)) {
++		    txPipe = xrtxpipe;
++		    nonTxPipe = xrpipe;
++		}
++		// custom paints handled by super.validatePipe() below
++	    }
+ 	}
+ 
+-	protected boolean isDrawableValid()
+-	{
+-		try
+-		{
+-			SunToolkit.awtLock();
+-			return XRIsDrawableValid();
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
++	if (txPipe != null) {
++	    if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
++		sg2d.drawpipe = txPipe;
++		sg2d.fillpipe = txPipe;
++	    } else if (sg2d.strokeState != SunGraphics2D.STROKE_THIN) {
++		sg2d.drawpipe = txPipe;
++		sg2d.fillpipe = nonTxPipe;
++	    } else {
++		sg2d.drawpipe = nonTxPipe;
++		sg2d.fillpipe = nonTxPipe;
++	    }
++	    sg2d.shapepipe = nonTxPipe;
++	} else {
++	    if (!validated) {
++		super.validatePipe(sg2d);
++	    }
++	}
++
++	// install the text pipe based on our earlier decision
++	sg2d.textpipe = textpipe;
++
++	// always override the image pipe with the specialized OGL pipe
++	sg2d.imagepipe = xrDrawImage;
++    }
++
++    /**
++     * Returns an accalerated MaskFill object if the current paint
++     *  is supported by the pipeline.
++     */
++    protected MaskFill getMaskFill(SunGraphics2D sg2d) {
++	if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR && !isPaintValid(sg2d)) {
++	    return null;
++	}
++	return super.getMaskFill(sg2d);
++    }
++
++    public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
++	if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR
++		&& sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
++	    return solidloops;
++	}
++
++	return super.getRenderLoops(sg2d);
++    }
++
++    public GraphicsConfiguration getDeviceConfiguration() {
++	return graphicsConfig;
++    }
++
++    /**
++     * Method for instantiating a Window SurfaceData
++     */
++    public static XRWindowSurfaceData createData(X11ComponentPeer peer) {
++	XRGraphicsConfig gc = getGC(peer);
++	return new XRWindowSurfaceData(peer, gc, gc.getSurfaceType());
++    }
++
++    /**
++     * Method for instantiating a Pixmap SurfaceData (offscreen).
++     * If the surface is opaque a 24-bit/RGB surface is chosen, 
++     * otherwise a 32-bit ARGB surface.
++     */
++    public static XRPixmapSurfaceData createData(XRGraphicsConfig gc,
++	    int width, int height, ColorModel cm, Image image, long drawable,
++	    int transparency) {
++	int depth = transparency > Transparency.OPAQUE ? 32 : 24;
++	if (depth == 24) {
++	    cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00, 0x000000FF);
++	} else {
++	    cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00,
++		    0x000000FF, 0xFF000000);
++	}
++
++	return new XRPixmapSurfaceData(gc, width, height, image,
++		getSurfaceType(gc, transparency), cm, drawable, transparency,
++		XRUtils.getPictureFormatForTransparency(transparency), depth);
++    }
++
++    protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc,
++	    SurfaceType sType, ColorModel cm, int depth, int transparency) {
++	super(sType, cm);
++	this.peer = peer;
++	this.graphicsConfig = gc;
++	this.solidloops = graphicsConfig.getSolidLoops(sType);
++	this.depth = depth;
++	initOps(peer, graphicsConfig, depth);
++
++	setBlitProxyKey(gc.getProxyKey());
++    }
++
++    /**
++     * Inits the XRender-data-structures which belong to the XRSurfaceData.
++     * @param pictureFormat
++     */
++    public void initXRender(int pictureFormat) {
++	try {
++	    SunToolkit.awtLock();
++	    XRInitXRender(getNativeOps(), pictureFormat);
++	} finally {
++	    SunToolkit.awtUnlock();
++	}
++    }
++
++    public static XRGraphicsConfig getGC(X11ComponentPeer peer) {
++	if (peer != null) {
++	    return (XRGraphicsConfig) peer.getGraphicsConfiguration();
++	} else {
++	    GraphicsEnvironment env = GraphicsEnvironment
++		    .getLocalGraphicsEnvironment();
++	    GraphicsDevice gd = env.getDefaultScreenDevice();
++	    return (XRGraphicsConfig) gd.getDefaultConfiguration();
++	}
++    }
++
++    /**
++     * Returns a boolean indicating whether or not a copyArea from the given
++     * rectangle source coordinates might be incomplete and result in X11
++     * GraphicsExposure events being generated from XCopyArea. This method
++     * allows the SurfaceData copyArea method to determine if it needs to set
++     * the GraphicsExposures attribute of the X11 GC to True or False to receive
++     * or avoid the events.
++     * 
++     * @return true if there is any chance that an XCopyArea from the given
++     *         source coordinates could produce any X11 Exposure events.
++     */
++    public abstract boolean canSourceSendExposures(int x, int y, int w, int h);
++
++    /**
++     * CopyArea is implemented using the "old" X11 GC, 
++     * therefor clip and needExposures have to be validated against that GC.
++     * Pictures and GCs don't share state.
++     */
++    public void validateCopyAreaGC(Region gcClip, boolean needExposures) {
++	if (validatedGCClip != gcClip) {
++	    if (gcClip != null) {
++		XSetClip(xgc, gcClip.getLoX(), gcClip.getLoY(),
++			gcClip.getHiX(), gcClip.getHiY(), 
++			gcClip.isRectangular() ? null : gcClip);
++	    } else {
++		XResetClip(xgc);
++	    }
++	    validatedGCClip = gcClip;
++	}
++
++	if (validatedExposures != needExposures) {
++	    validatedExposures = needExposures;
++	    XSetGraphicsExposures(xgc, needExposures);
++	}
++    }
++
++    public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
++	    int dx, int dy) {
++	if (xrpipe == null) {
++	    if (!isXRDrawableValid()) {
++		return true;
++	    }
++	    makePipes();
++	}
++	CompositeType comptype = sg2d.imageComp;
++	if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE
++		&& (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa
++			.equals(comptype))) {
++	    x += sg2d.transX;
++	    y += sg2d.transY;
++	    try {
++		SunToolkit.awtLock();
++		boolean needExposures = canSourceSendExposures(x, y, w, h);
++		validateCopyAreaGC(sg2d.getCompClip(), needExposures);
++		xrpipe.devCopyArea(getNativeOps(), xgc, x, y, x + dx, y + dy,
++			w, h);
++	    } finally {
++		SunToolkit.awtUnlock();
++	    }
++	    return true;
++	}
++	return false;
++    }
++
++    /**
++     * Returns the XRender SurfaceType which is able to fullfill the
++     * specified transparency requirement.
++     */
++    public static SurfaceType getSurfaceType(XRGraphicsConfig gc,
++	    int transparency) {
++	SurfaceType sType = null;
++
++	switch (transparency) {
++	case Transparency.OPAQUE:
++	    sType = XRSurfaceData.IntRgbX11;
++	    break;
++
++	case Transparency.BITMASK:
++	case Transparency.TRANSLUCENT:
++	    sType = XRSurfaceData.IntArgbX11;
++	    break;
++	}
++
++	return sType;
++    }
++
++    public void invalidate() {
++	if (isValid()) {
++	    setInvalid();
++	    super.invalidate();
++	}
++    }
++
++    /**
++     * Native methods used to set the state of the native XRender surface
++     */
++    private static native void XRSetForeground(int pixel);
++
++    private static native void XRSetComposite(int compRule, float eAlpha);
++
++    private static native void XRSetClip(long xsdo, int lox, int loy, int hix,
++	    int hiy, Region complexclip);
++
++    private static native void XRResetClip(long xsdo);
++
++    private static native void XRSetTransformNative(long xsdo, int m00,
++	    int m01, int m02, int m10, int m11, int m12);
++
++    private static native void XRSetTexturePaint(long xsdo);
++
++    private static native void XRResetPaint();
++
++    private static native void XRSetRepeat(long xsdo, int repeat);
++    
++    private static native void XRSetFilter(long xsdo, int value);
++    
++    private static native void XRSetLinearGradientPaint(float[] fractions,
++	    int[] pixels, int x1, int y1, int x2, int y2, int numStops,
++	    int cycleMethod, boolean useMask, boolean linear, int m00, int m01,
++	    int m02, int m10, int m11, int m12);
++    
++    private native static void XRSetRadialGradientPaint(float[] fractions,
++	    int[] pixels, int fx, int numStops, int cycleMethod,
++	    boolean useMask, boolean linear, int innerRadius, int outerRadius,
++	    int m00, int m01, int m02, int m10, int m11, int m12);
++
++    private void XRSetTransform(AffineTransform transform) {
++	double[] transformData = new double[6];
++	transform.getMatrix(transformData);
++
++	XRSetTransformNative(getNativeOps(), XDoubleToFixed(transformData[0]),
++		XDoubleToFixed(transformData[2]),
++		XDoubleToFixed(transformData[4]),
++		XDoubleToFixed(transformData[1]),
++		XDoubleToFixed(transformData[3]),
++		XDoubleToFixed(transformData[5]));
++    }
++
++    private long xgc; //GC is still used for copyArea
++
++    public static int validatedPixel = -1;
++    public static int validatedPaintState = -1;
++    private static Composite validatedComp;
++    public static Paint validatedPaint;
++
++    private Region validatedClip;
++    private Region validatedGCClip;
++    private boolean validatedExposures = true;
++    private float validatedExtraAlpha = 1.0f;
++    private int validatedFlags;
++
++    private boolean transformInUse = false;
++    private AffineTransform validatedSourceTransform = new AffineTransform();
++    private int validatedRepeat = XRUtils.RepeatNone;
++    private int validatedInterpolation = -1;
++    /*Used if API does not allow to pass interpolation value at the level needed*/
++    private int preferredInterpolation = -1;
++
++    public void setPreferredInterpolation(int interpolation) {
++	this.preferredInterpolation = interpolation;
++    }
++    
++    
++    /*
++     * For now those shape-clips are used for transformed images,
++     * because transformed image for now would invalidate a much larger area that they are intended to do.
++     * However as soon as the transformed-mask approach I am working on turns out
++     * to work well, those will be dropped.
++     */
++    public void setShapeClip(Shape shape) {
++	Region shapeClip = Region.getInstance(validatedClip, shape, null);
++	XRSetClip(getNativeOps(), shapeClip.getLoX(), shapeClip.getLoY(),
++		shapeClip.getHiX(), shapeClip.getHiY(), shapeClip
++			.isRectangular() ? null : shapeClip);
++    }
++
++    public void resetShapeClip() {
++	XRSetClip(getNativeOps(), validatedClip.getLoX(), validatedClip
++		.getLoY(), validatedClip.getHiX(), validatedClip.getHiY(),
++		validatedClip.isRectangular() ? null : validatedClip);
++    }
++
++    /**
++     * Validate the source with the preferred interpolation set sometimes earlier.
++     * @param sxForm
++     * @param repeat
++     */
++    void validateAsSource(AffineTransform sxForm, int repeat) {
++	validateAsSource(sxForm, repeat, preferredInterpolation);
++    }
++
++    /**
++     * Validates an XRSurfaceData when used as source.
++     * Note that the clip is applied when used as source as well as destination.
++     */
++    void validateAsSource(AffineTransform sxForm, int repeat, int interpolation) {
++	if (validatedClip != null) {
++	    validatedClip = null;
++	    XRResetClip(getNativeOps());
++	}
++
++	if (validatedRepeat != repeat) {
++	    validatedRepeat = repeat;
++	    XRSetRepeat(getNativeOps(), repeat);
++	}
++
++	if (sxForm == null) {
++	    if (transformInUse) {
++		validatedSourceTransform.setToIdentity();
++		XRSetTransform(validatedSourceTransform);
++		transformInUse = false;
++	    }
++	} else {
++	    if (!transformInUse
++		 || (transformInUse && !sxForm.equals(validatedSourceTransform))) {
++		
++		validatedSourceTransform.setTransform(sxForm.getScaleX(),
++			sxForm.getShearY(), sxForm.getShearX(), sxForm
++				.getScaleY(), sxForm.getTranslateX(), sxForm
++				.getTranslateY());
++		
++		XRSetTransform(validatedSourceTransform);
++		transformInUse = true;
++	    }
++	}
++
++	if (interpolation != validatedInterpolation) {
++	    XRSetFilter(getNativeOps(), interpolation);
++	    validatedInterpolation = interpolation;
++	}
++    }
++
++    /**
++     * Utility method for setting the Composite,
++     * passing down the arguments to the native method.
++     * @param comp
++     */
++    private void setComposite(Composite comp) {
++	if (comp instanceof AlphaComposite) {
++	    AlphaComposite aComp = (AlphaComposite) comp;
++	    validatedExtraAlpha = aComp.getAlpha();
++
++	    XRSetComposite(XRUtils.j2dAlphaCompToXR(aComp.getRule()),
++		    validatedExtraAlpha);
++	} else {
++	    throw new InternalError(
++		    "Composite accaleration not implemented for: "
++			    + comp.getClass().getName());
++	}
++    }
++
++    /**
++     * @see: BufferedPaints
++     */
++    public int[] convertToIntArgbPixels(Color[] colors, boolean linear) {
++	int[] pixels = new int[colors.length];
++	for (int i = 0; i < colors.length; i++) {
++	    pixels[i] = colorToIntArgbPixel(colors[i], linear);
++	}
++	return pixels;
++    }
++
++    /**
++     * @see: BufferedPaints
++     */
++    public int colorToIntArgbPixel(Color c, boolean linear) {
++	int rgb = c.getRGB();
++
++	int a = rgb >>> 24;
++	int r = (rgb >> 16) & 0xff;
++	int g = (rgb >> 8) & 0xff;
++	int b = (rgb) & 0xff;
++	if (linear) {
++	    r = BufferedPaints.convertSRGBtoLinearRGB(r);
++	    g = BufferedPaints.convertSRGBtoLinearRGB(g);
++	    b = BufferedPaints.convertSRGBtoLinearRGB(b);
++	}
++
++	a *= validatedExtraAlpha;
++
++	return ((a << 24) | (r << 16) | (g << 8) | (b));
++    }
++    
++    /**
++     * The currently only known paint XRender can't support are
++     * radial gradients where focus and center paint differ.
++     */
++    public static boolean isPaintValid(SunGraphics2D sg2d) {
++	if (sg2d.paintState == SunGraphics2D.PAINT_RAD_GRADIENT) {
++	    RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint;
++	    return grad.getFocusPoint().equals(grad.getCenterPoint());
++	}
++	return true;
++    }
++
++    /**
++     * Sets a 2-stop gradient.
++     * Utility method generating the by the native method expected
++     * parameters and calling it.
++     */
++    private void setGradientPaint(SunGraphics2D sg2d, GradientPaint paint,
++	    boolean useMask) {
++	int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(),
++		paint.getColor2() }, false);
++
++	float fractions[] = new float[2];
++	fractions[0] = 0;
++	fractions[1] = 1;
++
++	Point2D pt1 = paint.getPoint1();
++	Point2D pt2 = paint.getPoint2();
++
++	AffineTransform at = (AffineTransform) sg2d.transform.clone();
++	try {
++	    at.invert();
++	} catch (NoninvertibleTransformException ex) {
++	    ex.printStackTrace();
++	}
++
++	double[] transformData = new double[6];
++	at.getMatrix(transformData);
++
++	int repeat = paint.isCyclic() ? XRUtils.RepeatReflect
++		: XRUtils.RepeatPad;
++
++	XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()),
++		XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()),
++		XDoubleToFixed(pt2.getY()), 2, repeat, useMask, false,
++		XDoubleToFixed(transformData[0]),
++		XDoubleToFixed(transformData[2]),
++		XDoubleToFixed(transformData[4]),
++		XDoubleToFixed(transformData[1]),
++		XDoubleToFixed(transformData[3]),
++		XDoubleToFixed(transformData[5]));
++    }
++    
++    /**
++     * Sets a n-stop linear gradient.
++     * Utility method generating the by the native method expected
++     * parameters and calling it.
++     */
++    public void setLinearGradientPaint(SunGraphics2D sg2d,
++	    LinearGradientPaint paint, boolean useMask) {
++	boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
++	Color[] colors = paint.getColors();
++	int numStops = colors.length;
++	Point2D pt1 = paint.getStartPoint();
++	Point2D pt2 = paint.getEndPoint();
++
++	AffineTransform at = paint.getTransform();
++	at.preConcatenate(sg2d.transform);
++
++	int cycleMethod = XRUtils.getRepeatForCycleMethod(paint
++		.getCycleMethod());
++	float[] fractions = paint.getFractions();
++	int[] pixels = convertToIntArgbPixels(colors, linear);
++
++	try {
++	    at.invert();
++	} catch (NoninvertibleTransformException ex) {
++	    ex.printStackTrace();
++	}
++
++	double[] transformData = new double[6];
++	at.getMatrix(transformData);
++
++	XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()),
++		XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()),
++		XDoubleToFixed(pt2.getY()), numStops, cycleMethod, useMask,
++		linear, XDoubleToFixed(transformData[0]),
++		XDoubleToFixed(transformData[2]),
++		XDoubleToFixed(transformData[4]),
++		XDoubleToFixed(transformData[1]),
++		XDoubleToFixed(transformData[3]),
++		XDoubleToFixed(transformData[5]));
++    }
++
++    /**
++     * Sets a Radial Gradient where focus and center point match.
++     * Utility method generating the by the native method expected
++     * parameters and calling it.
++     */
++    public void setRadialGradientPaint(SunGraphics2D sg2d,
++	    RadialGradientPaint paint) {
++	boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
++	Color[] colors = paint.getColors();
++	int numStops = colors.length;
++	Point2D center = paint.getCenterPoint();
++	Point2D focus = paint.getFocusPoint();
++
++	int cycleMethod = XRUtils.getRepeatForCycleMethod(paint
++		.getCycleMethod());
++	float[] fractions = paint.getFractions();
++	int[] pixels = convertToIntArgbPixels(colors, linear);
++	float radius = paint.getRadius();
++
++	// save original (untransformed) center and focus points
++	double cx = center.getX();
++	double cy = center.getY();
++	double fx = focus.getX();
++	double fy = focus.getY();
++
++	AffineTransform at = paint.getTransform();
++	at.preConcatenate(sg2d.transform);
++	focus = at.transform(focus, focus);
++
++	// transform unit circle to gradient coords; we start with the
++	// unit circle (center=(0,0), focus on positive x-axis, radius=1)
++	// and then transform into gradient space
++	at.translate(cx, cy);
++	at.rotate(fx - cx, fy - cy);
++	// at.scale(radius, radius);
++
++	// invert to get mapping from device coords to unit circle
++	try {
++	    at.invert();
++	} catch (Exception e) {
++	    at.setToScale(0.0, 0.0);
++	}
++	focus = at.transform(focus, focus);
++
++	// clamp the focus point so that it does not rest on, or outside
++	// of, the circumference of the gradient circle
++	fx = Math.min(focus.getX(), 0.99);
++
++	double[] transformData = new double[6];
++	at.getMatrix(transformData);
++
++	XRSetRadialGradientPaint(fractions, pixels, XDoubleToFixed(fx),
++		numStops, cycleMethod, false, linear, XDoubleToFixed(0),
++		XDoubleToFixed(radius), XDoubleToFixed(transformData[0]),
++		XDoubleToFixed(transformData[2]),
++		XDoubleToFixed(transformData[4]),
++		XDoubleToFixed(transformData[1]),
++		XDoubleToFixed(transformData[3]),
++		XDoubleToFixed(transformData[5]));
++    }
++
++    private TexturePaint setTexturePaint(SunGraphics2D sg2d,
++	    TexturePaint paint, boolean useMask) {
++	BufferedImage bi = paint.getImage();
++	SurfaceData dstData = sg2d.surfaceData;
++	SurfaceData srcData = dstData.getSourceSurfaceData(bi,
++		SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
++
++	// REMIND: this hack tries to ensure that we have a cached texture
++	if (!(srcData instanceof XRSurfaceData)) {
++	    srcData = dstData.getSourceSurfaceData(paint.getImage(),
++		    SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver,
++		    null);
++	    if (!(srcData instanceof XRSurfaceData)) {
++		return null;
++	    }
++	}
++
++	XRSurfaceData x11SrcData = (XRSurfaceData) srcData;
++
++	AffineTransform at = (AffineTransform) sg2d.transform.clone();
++	Rectangle2D anchor = paint.getAnchorRect();
++	at.translate(anchor.getX(), anchor.getY());
++	at.scale(anchor.getWidth() / ((double) bi.getWidth()), 
++		anchor.getHeight() / ((double) bi.getHeight()));
++	
++	try {
++	    at.invert();
++	} catch (NoninvertibleTransformException ex) {
++	    at.setToIdentity(); /* TODO: Right thing to do in this case? */
++	}
++
++	x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, 
++		XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
++
++	XRSetTexturePaint(srcData.getNativeOps());
++
++	return paint;
++    }
++
++    /**
++     * Sets the paint as source.
++     * Checks the type of paint and calls the appropriate set*Paint method.
++     * @param sg2d
++     * @param paint
++     */
++    public void setPaint(SunGraphics2D sg2d, Paint paint) {
++	if (sg2d != null) {
++	    if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) {
++		XRResetPaint();
++	    } else {
++		switch (sg2d.paintState) {
++		case SunGraphics2D.PAINT_GRADIENT:
++		    setGradientPaint(sg2d, (GradientPaint) paint, false);
++		    validatedPaint = paint;
++		    break;
++
++		case SunGraphics2D.PAINT_LIN_GRADIENT:
++		    setLinearGradientPaint(sg2d, (LinearGradientPaint) paint,
++			    false);
++		    validatedPaint = paint;
++		    break;
++
++		case SunGraphics2D.PAINT_RAD_GRADIENT:
++		    setRadialGradientPaint(sg2d, (RadialGradientPaint) paint);
++		    validatedPaint = paint;
++		    break;
++
++		case SunGraphics2D.PAINT_TEXTURE:
++		    validatedPaint = setTexturePaint(sg2d,
++			    (TexturePaint) paint, false);
++		    break;
++
++		default:
++		    throw new InternalError("should not reach");
+ 		}
++	    }
++	}
++    }
++
++    /**
++     * Validates the Surface when used as destination, 
++     * takes care that the native surface has the same state as expected, 
++     * changing it it not.
++     */
++    public void validate(Region clip, Composite comp, AffineTransform xform,
++	    Paint paint, SunGraphics2D sg2d, int flags) {
++	boolean updateClip = (clip != validatedClip);
++	boolean updatePaint = (paint != validatedPaint) || paint == null;
++
++	if (!isValid()) {
++	    throw new InvalidPipeException("bounds changed");
++	}
++
++	// validate clip
++	if (updateClip) {
++	    if (clip != null) {
++		XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip
++			.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
++	    } else {
++		XRResetClip(getNativeOps());
++	    }
++	    validatedClip = clip;
++	}
++
++	// validate composite (note that a change in the context flags
++	// may require us to update the composite state, even if the
++	// composite has not changed)
++	if ((comp != validatedComp) || (flags != validatedFlags)) {
++	    if (comp != null) {
++		setComposite(comp);
++	    } else {
++		comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
++		setComposite(comp);
++	    }
++	    // the paint state is dependent on the composite state, so make
++	    // sure we update the color below
++	    updatePaint = true;
++	    validatedComp = comp;
++	    validatedFlags = flags;
++	}
++
++	if (sg2d != null && validatedPixel != sg2d.pixel) {
++	    validatedPixel = sg2d.pixel;
++	    XRSetForeground(validatedPixel);
++	}
++
++	// validate paint
++	if (updatePaint) {
++	    if (paint != null) {
++		setPaint(sg2d, paint);
++	    } else {
++		XRResetPaint();
++	    }
++	    validatedPaint = paint;
++	}
++    }
++
++    public void makePipes() { /*TODO: Why was this synchronized, but access not?*/
++	if (xrpipe == null) {
++	    try {
++		SunToolkit.awtLock();
++		xgc = XCreateGC(getNativeOps());
++
++		xrpipe = XRRenderer.getInstance();
++		xrtxpipe = new PixelToShapeConverter(xrpipe);
++		xrtextpipe = new XRTextRenderer();
++		xrDrawImage = new XRDrawImage();
++	    } finally {
++		SunToolkit.awtUnlock();
++	    }
++	}
++    }
++
++    public static class XRWindowSurfaceData extends XRSurfaceData {
++	public XRWindowSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc,
++		SurfaceType sType) {
++	    super(peer, gc, sType, peer.getColorModel(), peer.getColorModel()
++		    .getPixelSize(), Transparency.OPAQUE);
++
++	    if (isXRDrawableValid()) {
++		initXRender(XRUtils
++			.getPictureFormatForTransparency(Transparency.OPAQUE));
++		makePipes();
++	    }
++	}
++
++	public SurfaceData getReplacement() {
++	    return peer.getSurfaceData();
++	}
++
++	public Rectangle getBounds() {
++	    Rectangle r = peer.getBounds();
++	    r.x = r.y = 0;
++	    return r;
+ 	}
+ 
+ 	@Override
+-	public SurfaceDataProxy makeProxyFor(SurfaceData srcData)
+-	{
+-		return XRSurfaceDataProxy.createProxy(srcData, graphicsConfig);
+-	}
+-
+-	public void validatePipe(SunGraphics2D sg2d)
+-	{
+-	        TextPipe textpipe;
+-	        boolean validated = false;
+-
+-	        if (/* CompositeType.SrcNoEa (any color) */
+-	            (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY &&
+-	             sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR)        ||
+-
+-	            /* CompositeType.SrcOver (any color) */
+-	            (sg2d.compositeState == SunGraphics2D.COMP_ALPHA    &&
+-	             sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&
+-	             (((AlphaComposite)sg2d.composite).getRule() ==
+-	              AlphaComposite.SRC_OVER)))
+-	        {
+-	            textpipe = x11textpipe;
+-	        } else {
+-	            // do this to initialize textpipe correctly; we will attempt
+-	            // to override the non-text pipes below
+-	            super.validatePipe(sg2d);
+-	            textpipe = sg2d.textpipe;
+-	            validated = true;
+-	        }
+-
+-	        PixelToShapeConverter txPipe = null;
+-	        XRRenderer nonTxPipe = null;
+-
+-	        if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) 
+-	        {
+-	            if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) {
+-	                if (sg2d.compositeState < sg2d.COMP_XOR) {
+-	                    txPipe = x11txpipe;
+-	                    nonTxPipe = x11pipe;
+-	                }
+-	            } else if (sg2d.compositeState <= sg2d.COMP_ALPHA) {
+-	                if (isPaintValid(sg2d)) {
+-	                    txPipe = x11txpipe;
+-	                    nonTxPipe = x11pipe;
+-	                }
+-	                // custom paints handled by super.validatePipe() below
+-	            }
+-	        }
+-
+-	        if (txPipe != null) {
+-	            if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
+-	                sg2d.drawpipe = txPipe;
+-	                sg2d.fillpipe = txPipe;
+-	            } else if (sg2d.strokeState != sg2d.STROKE_THIN) {
+-	                sg2d.drawpipe = txPipe;
+-	                sg2d.fillpipe = nonTxPipe;
+-	            } else {
+-	                sg2d.drawpipe = nonTxPipe;
+-	                sg2d.fillpipe = nonTxPipe;
+-	            }
+-	            sg2d.shapepipe = nonTxPipe;
+-	        } else {
+-	            if (!validated) {
+-	                super.validatePipe(sg2d);
+-	            }
+-	        }
+-
+-	        // install the text pipe based on our earlier decision
+-	        sg2d.textpipe = textpipe;
+-
+-	        // always override the image pipe with the specialized OGL pipe
+-	        sg2d.imagepipe = xrDrawImage;
+-		
+-//		
+-//		if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON && /*sg2d.paintState <= sg2d.PAINT_ALPHACOLOR &&*/(sg2d.compositeState <= sg2d.COMP_ALPHA || sg2d.compositeState == sg2d.COMP_XOR))
+-//		{
+-//			if (x11txpipe == null)
+-//			{
+-//				/*
+-//				 * Note: this is thread-safe since x11txpipe is the
+-//				 * second of the two pipes constructed in makePipes().
+-//				 * In the rare case we are racing against another
+-//				 * thread making new pipes, setting lazypipe is a
+-//				 * safe alternative to waiting for the other thread.
+-//				 */
+-//				sg2d.drawpipe = lazypipe;
+-//				sg2d.fillpipe = lazypipe;
+-//				sg2d.shapepipe = lazypipe;
+-//				sg2d.imagepipe = lazypipe;
+-//				sg2d.textpipe = lazypipe;
+-//				return;
+-//			}
+-//
+-//			if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE)
+-//			{
+-//				sg2d.drawpipe = x11txpipe;
+-//				sg2d.fillpipe = x11txpipe;
+-//			} else if (sg2d.strokeState != sg2d.STROKE_THIN)
+-//			{
+-//				sg2d.drawpipe = x11txpipe;
+-//				sg2d.fillpipe = x11pipe;
+-//			} else
+-//			{
+-//				sg2d.drawpipe = x11pipe;
+-//				sg2d.fillpipe = x11pipe;
+-//			}
+-//			sg2d.shapepipe = x11pipe;
+-//			sg2d.imagepipe = new XRDrawImage();
+-//		} else
+-//		{
+-//			super.validatePipe(sg2d);
+-//		}
+-//
+-//		//		 if (sg2d.compositeState <= sg2d.COMP_ALPHA) {
+-//		//             if (XRPaints.isValid(sg2d)) {
+-//		//                 sg2d.drawpipe = x11pipe;
+-//		//                 sg2d.fillpipe = x11pipe;
+-//		//             }
+-//		//		 }
+-//
+-//		sg2d.textpipe = x11textpipe;
+-
+-	}
+-	
+-
+-    @Override
+-    protected MaskFill getMaskFill(SunGraphics2D sg2d) {
+-        if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR && !isPaintValid(sg2d)) {
+-            	return null;
+-        }
+-        return super.getMaskFill(sg2d);
+-    }
+-
+-	public RenderLoops getRenderLoops(SunGraphics2D sg2d)
+-	{
+-		if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && sg2d.compositeState <= sg2d.COMP_ALPHA)
+-		{
+-			return solidloops;
+-		}
+-		
+-		return super.getRenderLoops(sg2d);
+-	}
+-
+-	public GraphicsConfiguration getDeviceConfiguration()
+-	{
+-		return graphicsConfig;
++	public boolean canSourceSendExposures(int x, int y, int w, int h) {
++	    return true;
+ 	}
+ 
+ 	/**
+-	 * Method for instantiating a Window SurfaceData
++	 * Returns destination Component associated with this SurfaceData.
+ 	 */
+-	public static XRWindowSurfaceData createData(X11ComponentPeer peer)
+-	{
+-		XRGraphicsConfig gc = getGC(peer);
+-		return new XRWindowSurfaceData(peer, gc, gc.getSurfaceType());
++	public Object getDestination() {
++	    return peer.getTarget();
++	}
++    }
++
++    public static class XRPixmapSurfaceData extends XRSurfaceData {
++	Image offscreenImage;
++	int width;
++	int height;
++	int transparency;
++
++	public XRPixmapSurfaceData(XRGraphicsConfig gc, int width, int height,
++		Image image, SurfaceType sType, ColorModel cm, long drawable,
++		int transparency, int pictFormat, int depth) {
++	    super(null, gc, sType, cm, depth, transparency);
++	    this.width = width;
++	    this.height = height;
++	    offscreenImage = image;
++	    this.transparency = transparency;
++	    initSurface(depth, width, height, drawable, pictFormat);
++	    makePipes();
++	}
++
++	public void initSurface(int depth, int width, int height,
++		long drawable, int pictFormat) {
++	    try {
++		SunToolkit.awtLock();
++		XRInitSurface(depth, width, height, drawable, pictFormat);
++	    } finally {
++		SunToolkit.awtUnlock();
++	    }
++	}
++
++	public SurfaceData getReplacement() {
++	    return restoreContents(offscreenImage);
+ 	}
+ 
+ 	/**
+-	 * Method for instantiating a Pixmap SurfaceData (offscreen)
++	 * Need this since the surface data is created with the color model of
++	 * the target GC, which is always opaque. But in SunGraphics2D.blitSD we
++	 * choose loops based on the transparency on the source SD, so it could
++	 * choose wrong loop (blit instead of blitbg, for example).
+ 	 */
+-	public static XRPixmapSurfaceData createData(XRGraphicsConfig gc, int width, int height, ColorModel cm, Image image, long drawable, int transparency)
+-	{
+-		int depth = transparency > Transparency.OPAQUE ? 32 : 24;
+-		if (depth == 24)
+-		{
+-			cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00, 0x000000FF);
+-		} else
+-		{
+-			cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+-		}
+-
+-		return new XRPixmapSurfaceData(gc, width, height, image, getSurfaceType(gc, transparency), cm, drawable, transparency, XRUtils.getPictureFormatForTransparency(transparency), depth);
++	public int getTransparency() {
++	    return transparency;
+ 	}
+ 
+-	public static XRPixmapSurfaceData createData(XRGraphicsConfig gc, int width, int height)
+-	{
+-		/*TODO - may I really pass this XRGraphicsConfig down, although depth is different??*/
+-		return new XRPixmapSurfaceData(gc, width, height, null, ByteA8X11, new DirectColorModel(8, 0x00000000, 0x00000000, 0x00000000, 0x000000FF), 0, Transparency.OPAQUE, XRUtils.PictStandardA8, 8);
++	public Rectangle getBounds() {
++	    return new Rectangle(width, height);
+ 	}
+ 
+-	//	/**
+-	//	 * Initializes the native Ops pointer.
+-	//	 */
+-	private native void initOps(X11ComponentPeer peer, XRGraphicsConfig gc, int depth);
+-
+-	protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, SurfaceType sType, ColorModel cm, int depth, int transparency)
+-	{
+-		super(sType, cm);
+-		this.peer = peer;
+-		this.graphicsConfig = gc;
+-		this.solidloops = graphicsConfig.getSolidLoops(sType);
+-		this.depth = depth;
+-		initOps(peer, graphicsConfig, depth);
+-
+-		setBlitProxyKey(gc.getProxyKey());
++	@Override
++	public boolean canSourceSendExposures(int x, int y, int w, int h) {
++	    return (x < 0 || y < 0 || (x + w) > width || (y + h) > height);
+ 	}
+ 
+-	public void initXRender(int pictureFormat)
+-	{
+-		try
+-		{
+-			SunToolkit.awtLock();
+-			XRInitXRender(getNativeOps(), pictureFormat);
+-		} finally
+-		{
+-			SunToolkit.awtUnlock();
+-		}
+-	}
+-
+-	public static XRGraphicsConfig getGC(X11ComponentPeer peer)
+-	{
+-		if (peer != null)
+-		{
+-			return (XRGraphicsConfig) peer.getGraphicsConfiguration();
+-		} else
+-		{
+-			GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+-			GraphicsDevice gd = env.getDefaultScreenDevice();
+-			return (XRGraphicsConfig) gd.getDefaultConfiguration();
+-		}
++	public void flush() {
++	    /*
++	     * We need to invalidate the surface before disposing the native
++	     * Drawable and Picture. This way if an application tries to render to an
++	     * already flushed XRSurfaceData, we will notice in the validate()
++	     * method above that it has been invalidated, and we will avoid
++	     * using those native resources that have already been disposed.
++	     */
++	    invalidate();
++	    flushNativeSurface();
+ 	}
+ 
+ 	/**
+-	 * Returns a boolean indicating whether or not a copyArea from
+-	 * the given rectangle source coordinates might be incomplete
+-	 * and result in X11 GraphicsExposure events being generated
+-	 * from XCopyArea.
+-	 * This method allows the SurfaceData copyArea method to determine
+-	 * if it needs to set the GraphicsExposures attribute of the X11 GC
+-	 * to True or False to receive or avoid the events.
+-	 * @return true if there is any chance that an XCopyArea from the
+-	 *              given source coordinates could produce any X11
+-	 *              Exposure events.
++	 * Returns destination Image associated with this SurfaceData.
+ 	 */
+-	public abstract boolean canSourceSendExposures(int x, int y, int w, int h);
+-	
+-	public void validateCopyAreaGC(Region gcClip)
+-	{
+-		if (validatedGCClip != gcClip)
+-		{
+-			if (gcClip != null)
+-			{
+-				//XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
+-			} else
+-			{
+-				//XRResetClip(getNativeOps());
+-			}
+-			validatedGCClip = gcClip;
+-		}
++	public Object getDestination() {
++	    return offscreenImage;
+ 	}
++    }
+ 
+-	public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy)
+-	{
+-		if (x11pipe == null)
+-		{
+-			if (!isDrawableValid())
+-			{
+-				return true;
+-			}
+-			makePipes();
+-		}
+-		CompositeType comptype = sg2d.imageComp;
+-		if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE && (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa.equals(comptype)))
+-		{
+-			x += sg2d.transX;
+-			y += sg2d.transY;
+-			SunToolkit.awtLock();
+-			try
+-			{
+-				validateCopyAreaGC(sg2d.getCompClip());
+-				//validate(sg2d.getCompClip(), sg2d.composite, sg2d.transform, sg2d.paint, sg2d, 0);
+-				//						boolean needExposures = canSourceSendExposures(x, y, w, h);
+-				//						long xgc = getBlitGC(sg2d.getCompClip(), needExposures);
+-				
+-				
+-				x11pipe.devCopyArea(getNativeOps(), xgc, x, y, x + dx, y + dy, w, h);
+-				//X11PMBlitLoops.nativeRenderBlit(getNativeOps(), getNativeOps(), x, y, dx, dy, w, h);
+-			} finally
+-			{
+-				SunToolkit.awtUnlock();
+-			}
+-			return true;
+-		}
++    private static LazyPipe lazypipe = new LazyPipe();
++
++    public static class LazyPipe extends ValidatePipe {
++	public boolean validate(SunGraphics2D sg2d) {
++	    XRSurfaceData xsd = (XRSurfaceData) sg2d.surfaceData;
++	    if (!xsd.isXRDrawableValid()) {
+ 		return false;
++	    }
++	    xsd.makePipes();
++	    return super.validate(sg2d);
+ 	}
+-
+-	public static SurfaceType getSurfaceType(XRGraphicsConfig gc, int transparency)
+-	{
+-		SurfaceType sType = null;
+-
+-		switch (transparency)
+-		{
+-			case Transparency.OPAQUE:
+-				sType = XRSurfaceData.IntRgbX11;
+-				break;
+-
+-			case Transparency.BITMASK:
+-			case Transparency.TRANSLUCENT:
+-				sType = XRSurfaceData.IntArgbX11;
+-				break;
+-		}
+-
+-		return sType;
+-	}
+-
+-	public native void setInvalid();
+-
+-	public void invalidate()
+-	{
+-		if (isValid())
+-		{
+-			setInvalid();
+-			super.invalidate();
+-		}
+-	}
+-
+-	/**
+-	 * The following methods and variables are used to keep the Java-level
+-	 * context state in sync with the native X11 GC associated with this
+-	 * X11SurfaceData object.
+-	 */
+-
+-	private static native long XCreateGC(long pXSData);
+-
+-	private static native void XRSetForeground(int pixel);
+-
+-	private static native void XRSetComposite(int compRule, float eAlpha);
+-
+-	private static native void XRSetClip(long xsdo, int lox, int loy, int hix, int hiy, Region complexclip);
+-
+-	private static native void XRResetClip(long xsdo);
+-
+-	private static native void XRSetTransformNative(long xsdo, int m00, int m01, int m02, int m10, int m11, int m12);
+-
+-	private static native void XRSetTexturePaint(long xsdo);
+-
+-	private static native void XRResetPaint();
+-
+-	private static native void XRSetRepeat(long xsdo, int repeat);
+-
+-	private void XRSetTransform(AffineTransform transform)
+-	{
+-		double[] transformData = new double[6];
+-		transform.getMatrix(transformData);
+-
+-		XRSetTransformNative(getNativeOps(), XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]), XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
+-	}
+-
+-	//private long xgc;
+-
+-	public static int validatedPixel = -1;
+-	public static int validatedPaintState = -1;
+-	private static Composite validatedComp;
+-	public static Paint validatedPaint;
+-	private static int validatedTextureInterpolation = -1;
+-
+-	private Region validatedClip;
+-	private Region validatedGCClip;
+-	private boolean validatedExposures = true;
+-
+-	private int validatedFlags;
+-
+-	private boolean transformInUse = false;
+-	private AffineTransform validatedSourceTransform = new AffineTransform();
+-	private int validatedRepeat = XRUtils.RepeatNone;
+-	private int validatedInterpolation = -1;
+-
+-	private int preferredInterpolation = -1;
+-
+-	public void setPreferredInterpolation(int interpolation)
+-	{
+-		this.preferredInterpolation = interpolation;
+-	}
+-
+-	public void setShapeClip(Shape shape)
+-	{
+-		Region shapeClip = Region.getInstance(validatedClip, shape, null);
+-		XRSetClip(getNativeOps(), shapeClip.getLoX(), shapeClip.getLoY(), shapeClip.getHiX(), shapeClip.getHiY(), shapeClip.isRectangular() ? null : shapeClip);
+-	}
+-
+-	public void resetShapeClip()
+-	{
+-		XRSetClip(getNativeOps(), validatedClip.getLoX(), validatedClip.getLoY(), validatedClip.getHiX(), validatedClip.getHiY(), validatedClip.isRectangular() ? null : validatedClip);
+-	}
+-
+-	void validateAsSource(AffineTransform sxForm, int repeat)
+-	{
+-		validateAsSource(sxForm, repeat, preferredInterpolation);
+-	}
+-
+-	void validateAsSource(AffineTransform sxForm, int repeat, int interpolation)
+-	{
+-		if (validatedClip != null)
+-		{
+-			validatedClip = null;
+-			XRResetClip(getNativeOps());
+-		}
+-
+-		if (validatedRepeat != repeat)
+-		{
+-			validatedRepeat = repeat;
+-			XRSetRepeat(getNativeOps(), repeat);
+-		}
+-
+-		if (sxForm == null)
+-		{
+-			if (transformInUse)
+-			{
+-				validatedSourceTransform.setToIdentity();
+-				XRSetTransform(validatedSourceTransform);
+-				transformInUse = false;
+-			}
+-		} else
+-		{
+-			if (!transformInUse || (transformInUse && !sxForm.equals(validatedSourceTransform)))
+-			{
+-				validatedSourceTransform.setTransform(sxForm.getScaleX(), sxForm.getShearY(), sxForm.getShearX(), sxForm.getScaleY(), sxForm.getTranslateX(), sxForm.getTranslateY());
+-				XRSetTransform(validatedSourceTransform);
+-				transformInUse = true;
+-			}
+-		}
+-
+-		if (interpolation != validatedInterpolation)
+-		{
+-			XRSetFilter(getNativeOps(), interpolation);
+-			validatedInterpolation = interpolation;
+-		}
+-	}
+-
+-	public static native void XRSetFilter(long xsdo, int value);
+-
+-	private void setComposite(Composite comp)
+-	{
+-		if (comp instanceof AlphaComposite)
+-		{
+-			AlphaComposite aComp = (AlphaComposite) comp;
+-			float extraAlpha = aComp.getAlpha();
+-			//extraAlphaUsed = extraAlpha != 1.0f;
+-
+-			XRSetComposite(XRUtils.j2dAlphaCompToXR(aComp.getRule()), extraAlpha);
+-		} else if (comp instanceof XORComposite)
+-		{
+-
+-		} else
+-		{
+-			throw new InternalError("Composite accaleration not implemented for: " + comp.getClass().getName());
+-		}
+-	}
+-
+-	public static int[] convertToIntArgbPixels(Color[] colors, boolean linear)
+-	{
+-		int[] pixels = new int[colors.length];
+-		for (int i = 0; i < colors.length; i++)
+-		{
+-			pixels[i] = colorToIntArgbPixel(colors[i], linear);
+-		}
+-		return pixels;
+-	}
+-
+-	public static int colorToIntArgbPixel(Color c, boolean linear)
+-	{
+-		int rgb = c.getRGB();
+-		if (!linear && ((rgb >> 24) == -1))
+-		{
+-			return rgb;
+-		}
+-		int a = rgb >>> 24;
+-		int r = (rgb >> 16) & 0xff;
+-		int g = (rgb >> 8) & 0xff;
+-		int b = (rgb) & 0xff;
+-		if (linear)
+-		{
+-			r = BufferedPaints.convertSRGBtoLinearRGB(r);
+-			g = BufferedPaints.convertSRGBtoLinearRGB(g);
+-			b = BufferedPaints.convertSRGBtoLinearRGB(b);
+-		}
+-
+-		return ((a << 24) | (r << 16) | (g << 8) | (b));
+-	}
+-
+-	private static void setGradientPaint(SunGraphics2D sg2d, GradientPaint paint, boolean useMask)
+-	{
+-		int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(), paint.getColor2() }, false);
+-
+-		float fractions[] = new float[2];
+-		fractions[0] = 0;
+-		fractions[1] = 1;
+-
+-		Point2D pt1 = paint.getPoint1();
+-		Point2D pt2 = paint.getPoint2();
+-
+-		AffineTransform at = (AffineTransform) sg2d.transform.clone();
+-		try
+-		{
+-			at.invert();
+-		} catch (NoninvertibleTransformException ex)
+-		{
+-			ex.printStackTrace();
+-		}
+-
+-		double[] transformData = new double[6];
+-		at.getMatrix(transformData);
+-
+-		int repeat = paint.isCyclic() ? XRUtils.RepeatReflect : XRUtils.RepeatPad;
+-
+-		XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()), XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()), XDoubleToFixed(pt2.getY()), 2, repeat, useMask, false, XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]),
+-				XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
+-	}
+-
+-	public static boolean isPaintValid(SunGraphics2D sg2d)
+-	{
+-		if(sg2d.paintState == SunGraphics2D.PAINT_RAD_GRADIENT)
+-		{
+-			RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint;
+-			return grad.getFocusPoint().equals(grad.getCenterPoint());
+-		}
+-		
+-		return true;
+-	}
+-	
+-	public static void setRadialGradientPaint(SunGraphics2D sg2d, RadialGradientPaint paint)
+-	{
+-		boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
+-		Color[] colors = paint.getColors();
+-		int numStops = colors.length;
+-		Point2D center = paint.getCenterPoint();
+-		Point2D focus = paint.getFocusPoint();
+-
+-		int cycleMethod = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
+-		float[] fractions = paint.getFractions();
+-		int[] pixels = convertToIntArgbPixels(colors, linear);
+-		float radius = paint.getRadius();
+-
+-		// save original (untransformed) center and focus points
+-		double cx = center.getX();
+-		double cy = center.getY();
+-		double fx = focus.getX();
+-		double fy = focus.getY();
+-
+-		AffineTransform at = paint.getTransform();
+-		at.preConcatenate(sg2d.transform);
+-		focus = at.transform(focus, focus);
+-
+-		// transform unit circle to gradient coords; we start with the
+-		// unit circle (center=(0,0), focus on positive x-axis, radius=1)
+-		// and then transform into gradient space
+-		at.translate(cx, cy);
+-		at.rotate(fx - cx, fy - cy);
+-		//  at.scale(radius, radius);
+-
+-		// invert to get mapping from device coords to unit circle
+-		try
+-		{
+-			at.invert();
+-		} catch (Exception e)
+-		{
+-			at.setToScale(0.0, 0.0);
+-		}
+-		focus = at.transform(focus, focus);
+-
+-		// clamp the focus point so that it does not rest on, or outside
+-		// of, the circumference of the gradient circle
+-		fx = Math.min(focus.getX(), 0.99);
+-
+-		double[] transformData = new double[6];
+-		at.getMatrix(transformData);
+-
+-		XRSetRadialGradientPaint(fractions, pixels, XDoubleToFixed(fx), numStops, cycleMethod, false, linear, XDoubleToFixed(0), XDoubleToFixed(radius), XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]), XDoubleToFixed(transformData[3]),
+-				XDoubleToFixed(transformData[5]));
+-	}
+-
+-	public native static void XRSetRadialGradientPaint(float[] fractions, int[] pixels, int fx, int numStops, int cycleMethod, boolean useMask, boolean linear, int innerRadius, int outerRadius, int m00, int m01, int m02, int m10, int m11, int m12);
+-
+-	public static void setLinearGradientPaint(SunGraphics2D sg2d, LinearGradientPaint paint, boolean useMask)
+-	{
+-		boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
+-		Color[] colors = paint.getColors();
+-		int numStops = colors.length;
+-		Point2D pt1 = paint.getStartPoint();
+-		Point2D pt2 = paint.getEndPoint();
+-
+-		AffineTransform at = paint.getTransform();
+-		at.preConcatenate(sg2d.transform);
+-
+-		int cycleMethod = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
+-		float[] fractions = paint.getFractions();
+-		int[] pixels = convertToIntArgbPixels(colors, linear);
+-
+-		try
+-		{
+-			at.invert();
+-		} catch (NoninvertibleTransformException ex)
+-		{
+-			ex.printStackTrace();
+-		}
+-
+-		double[] transformData = new double[6];
+-		at.getMatrix(transformData);
+-
+-		XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()), XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()), XDoubleToFixed(pt2.getY()), numStops, cycleMethod, useMask, linear, XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]),
+-				XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
+-	}
+-
+-	private static native void XRSetLinearGradientPaint(float[] fractions, int[] pixels, int x1, int y1, int x2, int y2, int numStops, int cycleMethod, boolean useMask, boolean linear, int m00, int m01, int m02, int m10, int m11, int m12);
+-
+-	private static TexturePaint setTexturePaint(SunGraphics2D sg2d, TexturePaint paint, boolean useMask)
+-	{
+-		BufferedImage bi = paint.getImage();
+-		SurfaceData dstData = sg2d.surfaceData;
+-		SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
+-
+-		// REMIND: this hack tries to ensure that we have a cached texture
+-		if (!(srcData instanceof XRSurfaceData))
+-		{
+-			srcData = dstData.getSourceSurfaceData(paint.getImage(), SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
+-			if (!(srcData instanceof XRSurfaceData))
+-			{
+-				return null;
+-			}
+-		}
+-
+-		XRSurfaceData x11SrcData = (XRSurfaceData) srcData;
+-
+-		validatedTextureInterpolation = sg2d.interpolationType;
+-		XRSetFilter(x11SrcData.getNativeOps(), XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
+-
+-		AffineTransform at = (AffineTransform) sg2d.transform.clone();
+-		Rectangle2D anchor = paint.getAnchorRect();
+-		at.translate(anchor.getX(), anchor.getY());
+-		at.scale(anchor.getWidth() / ((double) bi.getWidth()), anchor.getHeight() / ((double) bi.getHeight()));
+-		try
+-		{
+-			at.invert();
+-		} catch (NoninvertibleTransformException ex)
+-		{
+-			ex.printStackTrace();
+-		}
+-
+-		x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType)); /*Todo - doesn't work if interpolation value is changed after texturepaint is "realized"*/
+-
+-		XRSetTexturePaint(srcData.getNativeOps());
+-
+-		return paint;
+-	}
+-
+-	public void setPaint(SunGraphics2D sg2d, Paint paint)
+-	{
+-		if (sg2d != null)
+-		{
+-			if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR)
+-			{
+-				XRResetPaint();
+-			} else
+-			{
+-				switch (sg2d.paintState)
+-				{
+-					case SunGraphics2D.PAINT_GRADIENT:
+-						setGradientPaint(sg2d, (GradientPaint) paint, false);
+-						validatedPaint = paint;
+-						break;
+-
+-					case SunGraphics2D.PAINT_LIN_GRADIENT:
+-						setLinearGradientPaint(sg2d, (LinearGradientPaint) paint, false);
+-						validatedPaint = paint;
+-						break;
+-
+-					case SunGraphics2D.PAINT_RAD_GRADIENT:
+-						setRadialGradientPaint(sg2d, (RadialGradientPaint) paint);
+-						validatedPaint = paint;
+-						break;
+-
+-					case SunGraphics2D.PAINT_TEXTURE:
+-						validatedPaint = setTexturePaint(sg2d, (TexturePaint) paint, false);
+-						break;
+-
+-					default:
+-						throw new InternalError("should not reach");
+-				}
+-			}
+-		}
+-	}
+-
+-	public void validate(Region clip, Composite comp, AffineTransform xform, Paint paint, SunGraphics2D sg2d, int flags)
+-	{
+-		boolean updateClip = (clip != validatedClip);
+-		boolean updatePaint = (paint != validatedPaint) || paint == null;
+-
+-		if (!isValid())
+-		{
+-			throw new InvalidPipeException("bounds changed");
+-		}
+-
+-		// validate clip
+-		if (updateClip)
+-		{
+-			if (clip != null)
+-			{
+-				XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
+-			} else
+-			{
+-				XRResetClip(getNativeOps());
+-			}
+-			validatedClip = clip;
+-		}
+-
+-		// validate composite (note that a change in the context flags
+-		// may require us to update the composite state, even if the
+-		// composite has not changed)
+-		if ((comp != validatedComp) || (flags != validatedFlags))
+-		{
+-			if (comp != null)
+-			{
+-				setComposite(comp);
+-			} else
+-			{
+-				comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
+-				setComposite(comp);
+-			}
+-			// the paint state is dependent on the composite state, so make
+-			// sure we update the color below
+-			updatePaint = true;
+-			validatedComp = comp;
+-			validatedFlags = flags;
+-		}
+-
+-		if (sg2d != null && validatedPixel != sg2d.pixel)
+-		{
+-			validatedPixel = sg2d.pixel;
+-			XRSetForeground(validatedPixel);
+-		}
+-
+-		// validate paint
+-		if (updatePaint)
+-		{
+-			if (paint != null)
+-			{
+-				setPaint(sg2d, paint);
+-			} else
+-			{
+-				XRResetPaint();
+-			}
+-			validatedPaint = paint;
+-		}
+-	}
+-
+-	long xgc;
+-
+-	public void makePipes()
+-	{
+-		if (x11pipe == null)
+-		{
+-			try
+-			{
+-				SunToolkit.awtLock();
+-				xgc = XCreateGC(getNativeOps());
+-
+-				x11pipe = XRRenderer.getInstance();
+-				x11txpipe = new PixelToShapeConverter(x11pipe);
+-				x11textpipe = new XRTextRenderer();
+-				xrDrawImage = new XRDrawImage();
+-			} finally
+-			{
+-				SunToolkit.awtUnlock();
+-			}
+-		}
+-	}
+-
+-	public static class XRWindowSurfaceData extends XRSurfaceData
+-	{
+-		public XRWindowSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, SurfaceType sType)
+-		{
+-			super(peer, gc, sType, peer.getColorModel(), peer.getColorModel().getPixelSize(), Transparency.OPAQUE);
+-
+-			if (isDrawableValid())
+-			{
+-				initXRender(XRUtils.getPictureFormatForTransparency(Transparency.OPAQUE));
+-				makePipes();
+-			}
+-		}
+-
+-		public SurfaceData getReplacement()
+-		{
+-			return peer.getSurfaceData();
+-		}
+-
+-		public Rectangle getBounds()
+-		{
+-			Rectangle r = peer.getBounds();
+-			r.x = r.y = 0;
+-			return r;
+-		}
+-
+-		@Override
+-		public boolean canSourceSendExposures(int x, int y, int w, int h)
+-		{
+-			return true;
+-		}
+-
+-		/**
+-		 * Returns destination Component associated with this SurfaceData.
+-		 */
+-		public Object getDestination()
+-		{
+-			return peer.getTarget();
+-		}
+-	}
+-
+-	public static class XRPixmapSurfaceData extends XRSurfaceData
+-	{
+-		Image offscreenImage;
+-		int width;
+-		int height;
+-		int transparency;
+-
+-		public XRPixmapSurfaceData(XRGraphicsConfig gc, int width, int height, Image image, SurfaceType sType, ColorModel cm, long drawable, int transparency, int pictFormat, int depth)
+-		{
+-			super(null, gc, sType, cm, depth, transparency);
+-			this.width = width;
+-			this.height = height;
+-			offscreenImage = image;
+-			this.transparency = transparency;
+-			initSurface(depth, width, height, drawable, pictFormat);
+-			makePipes();
+-		}
+-
+-		public void initSurface(int depth, int width, int height, long drawable, int pictFormat)
+-		{
+-			try
+-			{
+-				SunToolkit.awtLock();
+-				XRInitSurface(depth, width, height, drawable, pictFormat);
+-			} finally
+-			{
+-				SunToolkit.awtUnlock();
+-			}
+-		}
+-
+-		public SurfaceData getReplacement()
+-		{
+-			return restoreContents(offscreenImage);
+-		}
+-
+-		/**
+-		 * Need this since the surface data is created with
+-		 * the color model of the target GC, which is always
+-		 * opaque. But in SunGraphics2D.blitSD we choose loops
+-		 * based on the transparency on the source SD, so
+-		 * it could choose wrong loop (blit instead of blitbg,
+-		 * for example).
+-		 */
+-		public int getTransparency()
+-		{
+-			return transparency;
+-		}
+-
+-		public Rectangle getBounds()
+-		{
+-			return new Rectangle(width, height);
+-		}
+-
+-		@Override
+-		public boolean canSourceSendExposures(int x, int y, int w, int h)
+-		{
+-			return (x < 0 || y < 0 || (x + w) > width || (y + h) > height);
+-		}
+-
+-		public void flush()
+-		{
+-			/*
+-			 * We need to invalidate the surface before disposing the
+-			 * native Drawable and GC.  This way if an application tries
+-			 * to render to an already flushed X11SurfaceData, we will notice
+-			 * in the validate() method above that it has been invalidated,
+-			 * and we will avoid using those native resources that have
+-			 * already been disposed.
+-			 */
+-			invalidate();
+-			flushNativeSurface();
+-		}
+-
+-		/**
+-		 * Returns destination Image associated with this SurfaceData.
+-		 */
+-		public Object getDestination()
+-		{
+-			return offscreenImage;
+-		}
+-	}
+-
+-	private static LazyPipe lazypipe = new LazyPipe();
+-
+-	public static class LazyPipe extends ValidatePipe
+-	{
+-		public boolean validate(SunGraphics2D sg2d)
+-		{
+-			XRSurfaceData xsd = (XRSurfaceData) sg2d.surfaceData;
+-			if (!xsd.isDrawableValid())
+-			{
+-				return false;
+-			}
+-			xsd.makePipes();
+-			return super.validate(sg2d);
+-		}
+-	}
++    }
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceDataProxy.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -42,62 +42,51 @@
+ import sun.java2d.opengl.*;
+ 
+ /**
+- * The proxy class contains the logic for when to replace a
+- * SurfaceData with a cached X11 Pixmap and the code to create
+- * the accelerated surfaces.
++ * The proxy class contains the logic for when to replace a SurfaceData with a
++ * cached X11 Pixmap and the code to create the accelerated surfaces.
+  */
+-public class XRSurfaceDataProxy extends SurfaceDataProxy
+-    implements Transparency
+-{
++public class XRSurfaceDataProxy extends SurfaceDataProxy implements
++	Transparency {
+     public static SurfaceDataProxy createProxy(SurfaceData srcData,
+-                                               XRGraphicsConfig dstConfig)
+-    {
+-        if (srcData instanceof XRSurfaceData) {
+-            // srcData must be a VolatileImage which either matches
+-            // our visual or not - either way we do not cache it...
+-            return UNCACHED;
+-        }
+-        
+-        return new XRSurfaceDataProxy(dstConfig, srcData.getTransparency());
++	    XRGraphicsConfig dstConfig) {
++	
++	/*Don't cache already native surfaces*/
++	if (srcData instanceof XRSurfaceData) { 
++	    return UNCACHED;
++	}
++
++	return new XRSurfaceDataProxy(dstConfig, srcData.getTransparency());
+     }
+ 
+     XRGraphicsConfig xrgc;
+     int transparency;
+ 
+     public XRSurfaceDataProxy(XRGraphicsConfig x11gc) {
+-        this.xrgc = x11gc;
++	this.xrgc = x11gc;
+     }
+ 
+     @Override
+     public SurfaceData validateSurfaceData(SurfaceData srcData,
+-                                           SurfaceData cachedData,
+-                                           int w, int h)
+-    {
+-        if (cachedData == null) {
+-            // Bitmask will be created lazily during the blit phase
+-            cachedData = XRSurfaceData.createData(xrgc, w, h,
+-                                                   xrgc.getColorModel(),
+-                                                   null, 0, getTransparency());
+-        }
+-        return cachedData;
++	    SurfaceData cachedData, int w, int h) {
++	if (cachedData == null) {
++	    cachedData = XRSurfaceData.createData(xrgc, w, h, xrgc
++		    .getColorModel(), null, 0, getTransparency());
++	}
++	return cachedData;
+     }
+-    
++
+     public XRSurfaceDataProxy(XRGraphicsConfig x11gc, int transparency) {
+-        this.xrgc = x11gc;
+-        this.transparency = transparency;
++	this.xrgc = x11gc;
++	this.transparency = transparency;
+     }
+ 
+     @Override
+-    public boolean isSupportedOperation(SurfaceData srcData,
+-                                        int txtype,
+-                                        CompositeType comp,
+-                                        Color bgColor)
+-    {
+-        return (bgColor == null || transparency == Transparency.OPAQUE);
++    public boolean isSupportedOperation(SurfaceData srcData, int txtype,
++	    CompositeType comp, Color bgColor) {
++	return (bgColor == null || transparency == Transparency.TRANSLUCENT);
+     }
+ 
+-	public int getTransparency()
+-	{
+-		return transparency;
+-	}
++    public int getTransparency() {
++	return transparency;
++    }
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRUtils.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -6,137 +6,143 @@
+ import java.awt.MultipleGradientPaint.*;
+ import java.awt.image.*;
+ 
+-public class XRUtils
+-{
+-	/*Composition Operators*/
+-	public static final int PictOpClear = 0;
+-	public static final int PictOpSrc = 1;
+-	public static final int PictOpDst = 2;
+-	public static final int PictOpOver = 3;
+-	public static final int PictOpOverReverse = 4;
+-	public static final int PictOpIn = 5;
+-	public static final int PictOpInReverse = 6;
+-	public static final int PictOpOut = 7;
+-	public static final int PictOpOutReverse = 8;
+-	public static final int PictOpAtop = 9;
+-	public static final int PictOpAtopReverse = 10;
+-	public static final int PictOpXor = 11;
+-	public static final int PictOpAdd = 12;
+-	public static final int PictOpSaturate = 13;
++public class XRUtils {
++    /* Composition Operators */
++    public static final int PictOpClear = 0;
++    public static final int PictOpSrc = 1;
++    public static final int PictOpDst = 2;
++    public static final int PictOpOver = 3;
++    public static final int PictOpOverReverse = 4;
++    public static final int PictOpIn = 5;
++    public static final int PictOpInReverse = 6;
++    public static final int PictOpOut = 7;
++    public static final int PictOpOutReverse = 8;
++    public static final int PictOpAtop = 9;
++    public static final int PictOpAtopReverse = 10;
++    public static final int PictOpXor = 11;
++    public static final int PictOpAdd = 12;
++    public static final int PictOpSaturate = 13;
+ 
+-	/*Repeats*/
+-	public static final int RepeatNone = 0;
+-	public static final int RepeatNormal = 1;
+-	public static final int RepeatPad = 2;
+-	public static final int RepeatReflect = 3;
++    /* Repeats */
++    public static final int RepeatNone = 0;
++    public static final int RepeatNormal = 1;
++    public static final int RepeatPad = 2;
++    public static final int RepeatReflect = 3;
++
++    /* Interpolation qualities */
++    public static final int FAST = 0;
++    public static final int GOOD = 1;
++    public static final int BEST = 2;
++
++    /* PictFormats */
++    public static final int PictStandardARGB32 = 0;
++    public static final int PictStandardRGB24 = 1;
++    public static final int PictStandardA8 = 2;
++    public static final int PictStandardA4 = 3;
++    public static final int PictStandardA1 = 4;
++
++  /**
++   * Maps the specified affineTransformOp to the corresponding XRender
++   * image filter.
++   */
++    public static int ATransOpToXRQuality(int affineTranformOp) {
+ 	
+-	/*Interpolation qualities*/
+-	public static final int FAST = 0;
+-	public static final int GOOD = 1;
+-	public static final int BEST = 2;
+-	
+-	/*PictFormats*/
+-	public static final int PictStandardARGB32 = 0;
+-	public static final int PictStandardRGB24 = 1;
+-	public static final int PictStandardA8 = 2;
+-	public static final int PictStandardA4 = 3;
+-	public static final int PictStandardA1 = 4;
+-	
+-	public static int ATransOpToXRQuality(int affineTranformOp)
+-	{
+-		switch(affineTranformOp)
+-		{
+-			case AffineTransformOp.TYPE_NEAREST_NEIGHBOR:
+-				return FAST;
+-				
+-			case AffineTransformOp.TYPE_BILINEAR:
+-				return GOOD;
+-				
+-			case AffineTransformOp.TYPE_BICUBIC:
+-				return BEST;
+-		}
+-		
+-		return -1;
+-	}
+-	
+-	public static int getPictureFormatForTransparency(int transparency)
+-	{ 
+-		switch(transparency)
+-		{
+-			case Transparency.OPAQUE:
+-				return PictStandardRGB24;
+-				
+-			case Transparency.BITMASK:
+-			case Transparency.TRANSLUCENT:
+-				return PictStandardARGB32;
+-		}
+-		
+-		return -1;
++	switch (affineTranformOp) {
++	case AffineTransformOp.TYPE_NEAREST_NEIGHBOR:
++	    return FAST;
++
++	case AffineTransformOp.TYPE_BILINEAR:
++	    return GOOD;
++
++	case AffineTransformOp.TYPE_BICUBIC:
++	    return BEST;
+ 	}
+ 
+-	public static int getRepeatForCycleMethod(CycleMethod cycleMethod)
+-	{
+-		if (cycleMethod.equals(CycleMethod.NO_CYCLE))
+-		{
+-			return RepeatPad;
+-		} else if (cycleMethod.equals(CycleMethod.REFLECT))
+-		{
+-			return RepeatReflect;
+-		} else if (cycleMethod.equals(CycleMethod.REPEAT))
+-		{
+-			return RepeatNormal;
+-		}
++	return -1;
++    }
+ 
+-		return RepeatNone;
++    /**
++     * Returns the XRender picture Format which is 
++     * required to fullfill the Java2D transparency requirement.
++     */
++    public static int getPictureFormatForTransparency(int transparency) {
++	switch (transparency) {
++	case Transparency.OPAQUE:
++	    return PictStandardRGB24;
++
++	case Transparency.BITMASK:
++	case Transparency.TRANSLUCENT:
++	    return PictStandardARGB32;
+ 	}
+ 
+-	public static int XDoubleToFixed(double dbl)
+-	{
+-		return (int) (dbl * 65536);
++	return -1;
++    }
++
++    /**
++     * Maps the Java2D CycleMethod to XRender's Repeat properties.
++     */
++    public static int getRepeatForCycleMethod(CycleMethod cycleMethod) {
++	if (cycleMethod.equals(CycleMethod.NO_CYCLE)) {
++	    return RepeatPad;
++	} else if (cycleMethod.equals(CycleMethod.REFLECT)) {
++	    return RepeatReflect;
++	} else if (cycleMethod.equals(CycleMethod.REPEAT)) {
++	    return RepeatNormal;
+ 	}
+ 
+-	public static int j2dAlphaCompToXR(int j2dRule)
+-	{
+-		switch (j2dRule)
+-		{
+-			case CLEAR:
+-				return PictOpClear;
++	return RepeatNone;
++    }
+ 
+-			case SRC:
+-				//return PictOpOver;
+-				return PictOpSrc;
++    /**
++     * Converts a double into an XFixed.
++     */
++    public static int XDoubleToFixed(double dbl) {
++	return (int) (dbl * 65536);
++    }
+ 
+-			case DST:
+-				return PictOpDst;
++    /**
++     * Maps the specified Java2D composition rule, 
++     * to the corresponding XRender composition rule.
++     */
++    public static int j2dAlphaCompToXR(int j2dRule) {
++	switch (j2dRule) {
++	case CLEAR:
++	    return PictOpClear;
+ 
+-			case SRC_OVER:
+-				return PictOpOver;
++	case SRC:
++	    return PictOpSrc;
+ 
+-			case DST_OVER:
+-				return PictOpOverReverse;
++	case DST:
++	    return PictOpDst;
+ 
+-			case SRC_IN:
+-				return PictOpIn;
++	case SRC_OVER:
++	    return PictOpOver;
+ 
+-			case DST_IN:
+-				return PictOpInReverse;
++	case DST_OVER:
++	    return PictOpOverReverse;
+ 
+-			case SRC_OUT:
+-				return PictOpOut;
++	case SRC_IN:
++	    return PictOpIn;
+ 
+-			case DST_OUT:
+-				return PictOpOutReverse;
++	case DST_IN:
++	    return PictOpInReverse;
+ 
+-			case SRC_ATOP:
+-				return PictOpAtop;
++	case SRC_OUT:
++	    return PictOpOut;
+ 
+-			case DST_ATOP:
+-				return PictOpAtopReverse;
++	case DST_OUT:
++	    return PictOpOutReverse;
+ 
+-			case XOR:
+-				return PictOpXor;
+-		}
++	case SRC_ATOP:
++	    return PictOpAtop;
+ 
+-		throw new InternalError("No XRender equivalent available for requested java2d composition rule");
++	case DST_ATOP:
++	    return PictOpAtopReverse;
++
++	case XOR:
++	    return PictOpXor;
+ 	}
++
++	throw new InternalError("No XRender equivalent available for requested java2d composition rule");
++    }
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRVolatileSurfaceManager.java	Fri Aug 01 22:43:51 2008 +0200
+@@ -35,13 +35,7 @@
+ import sun.java2d.SurfaceData;
+ 
+ /**
+- * X11 platform implementation of the VolatileSurfaceManager class.
+- * The class attempts to create and use a pixmap-based SurfaceData
+- * object (X11PixmapSurfaceData).
+- * If this object cannot be created or re-created as necessary, the
+- * class falls back to a system memory based SurfaceData object
+- * (BufImgSurfaceData) that will be used until the accelerated
+- * SurfaceData can be restored.
++ * XRender platform implementation of the VolatileSurfaceManager class.
+  */
+ public class XRVolatileSurfaceManager extends VolatileSurfaceManager {
+ 
+@@ -80,13 +74,12 @@
+         return sData;
+     }
+ 
++   /**
++    * XRender should allow copies between different formats and depths.
++    * TODO: verify that this assumption is correct.
++    */
+     protected boolean isConfigValid(GraphicsConfiguration gc) {
+-        // REMIND: we might be too paranoid here, requiring that
+-        // the GC be exactly the same as the original one.  The
+-        // real answer is one that guarantees that pixmap copies
+-        // will be correct (which requires like bit depths and
+-        // formats).
+-        return ((gc == null) || (gc == vImg.getGraphicsConfig()));
++    	return true;
+     }
+ 
+     /**
+@@ -96,10 +89,8 @@
+     @Override
+     public ImageCapabilities getCapabilities(GraphicsConfiguration gc) {
+         if (isConfigValid(gc) && isAccelerationEnabled()) {
+-            // accelerated but not volatile
+             return new ImageCapabilities(true);
+         }
+-        // neither accelerated nor volatile
+         return new ImageCapabilities(false);
+     }
+ }
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/ArrayList.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -2,9 +2,7 @@
+ #include <string.h>
+ #include "ArrayList.h"
+ 
+-void initXRList(XrArrayList *list, jint capacity, size_t blkSize)
+-{
+-  //printf("Init XR LIst!\n");fflush(stdout);
++void initXRList(XrArrayList *list, jint capacity, size_t blkSize) {
+   list->used = 0;
+   list->capacity = capacity;
+ 
+@@ -15,10 +13,8 @@
+   }
+ }
+ 
+-void* getNewXR(XrArrayList *list, size_t blkSize)
+-{
+-  if((list->used+1) >= list->capacity)
+-  {
++void* getNewXR(XrArrayList *list, size_t blkSize) {
++  if((list->used+1) >= list->capacity) {
+     int newCapacity = list->capacity*2 + 10;
+     if(list->capacity > 0) {
+       list->elements = realloc(list->elements, newCapacity * blkSize);
+@@ -31,9 +27,7 @@
+   return list->elements + (list->used++ * blkSize);
+ }
+ 
+-void clearXRList(XrArrayList *list)
+-{
++void clearXRList(XrArrayList *list) {
+   list->used = 0;
+-  //memset(list->elements, 0, list->used);
+ }
+ 
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/ArrayList.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.h	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/ArrayList.h	Fri Aug 01 22:43:51 2008 +0200
+@@ -1,3 +1,8 @@
++/* Utility functions, providing some kind of growable array
++ * with the restriction that elements can only be added 
++ * at the end of the list 
++ */
++
+ #ifndef ArrayList_h_Included
+ #define ArrayList_h_Included
+ 
+@@ -9,10 +14,14 @@
+    jint used;
+ } XrArrayList;
+ 
++/* Initializes the list data strutures */
+ void initXRList(XrArrayList *list, jint capacity, size_t blkSize);
+ 
++/* Returns a pointer to a blksize large memory area, 
++   enlarging the underlaying array on demand */
+ void* getNewXR(XrArrayList *list, size_t blkSize);
+ 
++/* Clears the list content */
+ void clearXRList(XrArrayList *list);
+ 
+ #endif /* ArrayList_h_Included */
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/MaskBuffer.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -1,12 +1,13 @@
+ #include "MaskBuffer.h"
+ #include "XRSurfaceData.h"
+ #include "X11SurfaceData.h"
++#include "Trace.h"
++#include "awt_GraphicsEnv.h"
+ 
+ #define MAX(a,b) ((a) > (b) ? (a) : (b))
+ #define MIN(a,b) ((a) < (b) ? (a) : (b))
+ 
+-#define GET_DIRTY_LINE_REGION(X1, Y1, X2, Y2, RX1, RY1, RX2, RY2)        \
+-  {                                                                      \
++#define GET_DIRTY_LINE_REGION(X1, Y1, X2, Y2, RX1, RY1, RX2, RY2)  {     \
+     if(X1 < X2) {                                                        \
+       RX1 = X1;                                                          \
+       RX2 = X2;                                                          \
+@@ -25,8 +26,8 @@
+   }
+ 
+ #ifndef HEADLESS
+-MaskBuffer* initMaskBuffer(Window window)
+-{
++
++MaskBuffer* initMaskBuffer(Window window) {
+   MaskBuffer *buffer = malloc(sizeof(MaskBuffer));
+   initRegion(&buffer->region);
+  
+@@ -40,21 +41,16 @@
+   buffer->tiles = NULL;
+ 
+   XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, PictStandardA8);
+-  XRenderPictFormat *fmt32 = XRenderFindStandardFormat(awt_display, PictStandardARGB32);
+ 
+   buffer->maskPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 8);
+   buffer->lineMaskPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 8);
+-  buffer->gradPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 32);
+  
+   XRenderPictureAttributes pict_attr;
+   buffer->maskPicture = XRenderCreatePicture(awt_display, buffer->maskPixmap, fmt, 0, &pict_attr);
+   buffer->lineMaskPicture = XRenderCreatePicture(awt_display, buffer->lineMaskPixmap, fmt, 0, &pict_attr);
+-  buffer->gradPict = XRenderCreatePicture(awt_display, buffer->gradPixmap, fmt32, 0, &pict_attr);
+ 
+-  XRenderColor color_black={.red=0, .green=0, .blue=0, .alpha=0xffff};
+   XRenderFillRectangle (awt_display, PictOpClear, buffer->maskPicture, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
+   XRenderFillRectangle (awt_display, PictOpClear, buffer->lineMaskPicture, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
+-  XRenderFillRectangle (awt_display, PictOpClear, buffer->gradPict, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
+ 
+   buffer->validatedGCAlpha = 1.0f;
+   XGCValues values;
+@@ -63,16 +59,21 @@
+   /*Invisible GC for readback assistance*/
+   values.foreground = 0;
+   buffer->clearLineGC = XCreateGC(awt_display, buffer->lineMaskPixmap, GCForeground, &values);
++  buffer->maskGC = XCreateGC(awt_display, buffer->maskPixmap, 0, &values);
++ 
++  buffer->alphaData = malloc(32*32);
++  buffer->alphaImg = XCreateImage(awt_display, &buffer->maskPixmap, 8, ZPixmap, 0, (char *) buffer->alphaData, 32, 32, 8, 0);
++  buffer->aImgWidth = 32;
++  buffer->aImgHeight = 32;
+ 
+   return buffer;
+ }
+ 
+-static void allocTileBuffer(MaskBuffer* buf)
+-{
++static void allocTileBuffer(MaskBuffer* buf) {
+   buf->xTiles = ((buf->region.x2 - buf->region.x) / MASK_TILE_SIZE) + 1;
+   buf->yTiles = ((buf->region.y2 - buf->region.y) / MASK_TILE_SIZE) + 1;
+ 
+-  //If current tile-array is too small, allocate a larger one
++  /* If current tile-array is too small, allocate a larger one */
+   if(buf->tiles == NULL || buf->xTileCap < buf->xTiles || buf->yTileCap < buf->yTiles) {
+     buf->xTileCap = MAX((buf->xTiles * 2), buf->xTileCap);
+     buf->yTileCap = MAX((buf->yTiles * 2), buf->yTileCap);
+@@ -82,7 +83,7 @@
+     buf->tiles = calloc(buf->xTileCap * buf->yTileCap, sizeof(XrTile));
+   }
+ 
+-  //Init/Reset the tiles that will be used later
++  /* Init/Reset the tiles that will be used later */
+   int x,y;
+   for(y=0; y < buf->yTiles; y++) {
+     for(x=0; x < buf->xTiles; x++) {
+@@ -91,30 +92,22 @@
+  }
+ }
+ 
+-static void cleanMaskBuffer(MaskBuffer *buf)
+-{
+-  initRegion(&buf->region); //TODO: eigentlich nicht noetig
++static void cleanMaskBuffer(MaskBuffer *buf) {
++  initRegion(&buf->region);
+   buf->xTiles = 0;
+   buf->yTiles = 0;
+   clearXRList(&buf->rects);
+   clearXRList(&buf->lines);
+ }
+ 
+-static void getTileDirtyArea(MaskRegion *dirtyRectArea, MaskRegion *dirtyLineArea, MaskRegion *totalDirtyArea)
+-{
++static void getTileDirtyArea(MaskRegion *dirtyRectArea, MaskRegion *dirtyLineArea, MaskRegion *totalDirtyArea) {
+   totalDirtyArea->x = MIN(dirtyRectArea->x, dirtyLineArea->x);
+   totalDirtyArea->y = MIN(dirtyRectArea->y, dirtyLineArea->y);
+   totalDirtyArea->x2 = MAX(dirtyRectArea->x2, dirtyLineArea->x2);
+   totalDirtyArea->y2 = MAX(dirtyRectArea->y2, dirtyLineArea->y2);
+ }
+ 
+-/**
+-* Grows the dirty region of the tile.
+-* This allows to log which areas of the mask are used, and only do Composition
+-* with the parts that are really occupied.
+-*/
+-static void growDirtyRegion(MaskRegion *region, jint x, jint y, jint x2, jint y2)
+-{
++static void growDirtyRegion(MaskRegion *region, jint x, jint y, jint x2, jint y2) {
+   if(x < region->x){
+     region->x = x;
+   }
+@@ -129,8 +122,7 @@
+   }
+ }
+ 
+-static void growDirtyRegionTileLimit(MaskRegion *region, jint x, jint y, jint x2, jint y2)
+-{
++static void growDirtyRegionTileLimit(MaskRegion *region, jint x, jint y, jint x2, jint y2) {
+   if(x < region->x){
+     region->x = MAX(x, 0);
+   }
+@@ -149,8 +141,7 @@
+ * Limits the rect's coordinates to the mask coordinates.
+ * The result is used by growDirtyRegion.
+ */
+-static void limitRetcCoords(XRectangle *rect) 
+-{
++static void limitRetcCoords(XRectangle *rect)  {
+    if((rect->x + rect->width) > MASK_TILE_SIZE) {
+       rect->width = MASK_TILE_SIZE - rect->x;
+    }
+@@ -168,16 +159,14 @@
+   }
+ }
+ 
+-static void initRegion(MaskRegion *region)
+-{
+-  region->x = 99999;
++static void initRegion(MaskRegion *region) {
++  region->x = 99999; /*TODO: Integer max/min*/
+   region->y = 99999;
+   region->x2 = -99999;
+   region->y2 = -99999;
+ }
+ 
+-void addRect(MaskBuffer* buf, short x, short y, unsigned short w, unsigned short h)
+-{
++void addRect(MaskBuffer* buf, short x, short y, unsigned short w, unsigned short h) {
+   XRectangle *rect = (XRectangle*) getNewXR(&buf->rects, sizeof(XRectangle));
+   rect->x = x;
+   rect->y = y;
+@@ -187,51 +176,40 @@
+   growDirtyRegion(&buf->region, x, y, x+w, y+h);
+ }
+ 
+-void addLine(MaskBuffer* buf, int x1, int y1, int x2, int y2)
+-{
+-  /* EXA tries to accalerate lines which can be rendered with a single fillRect.
+-   * Unfourtunatly EXA is a bit dumb because our image is held in sysmem all the time anyway.
+-   * So although it would be pretty cheap in sysmem, it migrates the mask to vram just to do a single accalerated fillRect.
+-   * This should really be fixed in EXA, I hope I get it done sometimes.
+-   *
+-   * We seperate rect/line rendering to not cause exzessive migration, therefor we simple add that "line" to our rects.
+-   */
++void addLine(MaskBuffer* buf, int x1, int y1, int x2, int y2) {
++  /* EXA is not able to accalerate diagonal lines, 
++     we try to "guide" it a bit to avoid excessive migration
++     See project documentation for an detailed explanation */
+ 
+   int minX, minY, maxX, maxY;
+-  GET_DIRTY_LINE_REGION(x1, y1, x2, y2, minX, minY, maxX, maxY); 
++  GET_DIRTY_LINE_REGION(x1, y1, x2, y2, minX, minY, maxX, maxY);
+   int xDiff = maxX - minX;
+   int yDiff = maxY - minY;
+ 
+-   if(xDiff == 0 || yDiff == 0)
+-   {
++  if(xDiff == 0 || yDiff == 0) {
+      addRect(buf, minX, minY, maxX - minX + 1, maxY - minY + 1);
+-   }else
+-   if(xDiff == 1 && yDiff == 1)
+-   {
++  } else if(xDiff == 1 && yDiff == 1) {
+      addRect(buf, x1, y1, 1, 1);
+      addRect(buf, x2, y2, 1, 1);
+-   } else 
+-   {
++  } else {
+      XSegment *line = (XSegment*) getNewXR(&buf->lines, sizeof(XSegment));
+      line->x1 = x1;
+      line->y1 = y1;
+      line->x2 = x2;
+      line->y2 = y2;
+- 
++
+      growDirtyRegion(&buf->region, minX, minY, maxX + 1, maxY + 1);
+   }
+ }
+ 
+-static void initXrTile(XrTile *tile)
+-{
++static void initXrTile(XrTile *tile) {
+   initRegion(&tile->dirtyLineArea);
+   initRegion(&tile->dirtyRectArea);
+   clearXRList(&tile->rects);
+   clearXRList(&tile->lines);
+ }
+ 
+-static void storeLinesInTiles(MaskBuffer *buf)
+-{
++static void storeLinesInTiles(MaskBuffer *buf) {
+   int i,n,m;
+ 
+   for(i=0; i < buf->lines.used; i++) {
+@@ -242,8 +220,8 @@
+      line->x2 -= buf->region.x;
+      line->y2 -= buf->region.y;
+ 
+-    int minX, minY, maxX, maxY;
+-    GET_DIRTY_LINE_REGION(line->x1, line->y1, line->x2, line->y2, minX, minY, maxX, maxY);
++     int minX, minY, maxX, maxY;
++     GET_DIRTY_LINE_REGION(line->x1, line->y1, line->x2, line->y2, minX, minY, maxX, maxY);
+ 
+      int tileXStartIndex = minX / MASK_TILE_SIZE;
+      int tileYStartIndex = minY / MASK_TILE_SIZE;
+@@ -277,8 +255,7 @@
+   }
+ }
+ 
+-static void storeRectsInTiles(MaskBuffer *buf)
+-{
++static void storeRectsInTiles(MaskBuffer *buf) {
+   int i,n,m;
+ 
+   for(i=0; i < buf->rects.used; i++) {
+@@ -296,7 +273,7 @@
+         for(m=0; m < tileXLenght; m++) {
+           int tileIndex = (buf->xTileCap * (tileYStartIndex + n)) + tileXStartIndex + m;
+           assert(tileIndex >= 0 && tileIndex < (buf->xTileCap*buf->yTileCap));
+-          //printf("Index: %d - tileX:%d, tileY:%d, tilesx:%d, tilesy:%d, capx:%d capy:%d\n",tileIndex,  (m + tileXLenght), (n + tileYStartIndex), buf->xTiles, buf->yTiles, buf->xTileCap, buf->yTileCap);fflush(stdout);
++
+           XrTile *tile = &buf->tiles[tileIndex];
+           XRectangle *tileRect = (XRectangle*) getNewXR(&tile->rects, sizeof(XRectangle));
+ 
+@@ -315,8 +292,7 @@
+   }
+ }
+ 
+-static void translateRects(XrArrayList *rectList, int x, int y)
+-{
++static void translateRects(XrArrayList *rectList, int x, int y) {
+   int i;
+   for(i = 0; i < rectList->used; i++) {
+       XRectangle *rect = ((XRectangle *) rectList->elements) + i;
+@@ -325,20 +301,18 @@
+    }
+ }
+ 
+-void fillMask(MaskBuffer* buf, Picture dest)
+-{
+-  XRenderColor color_black={.red=0, .green=0, .blue=0, .alpha=0xffff};
++void fillMask(MaskBuffer* buf, Picture dest) {
+   int i, m, n;
+ 
+   jboolean maskRequired = (xrSrcData.src != xrSrcData.solid) || (xrSrcData.solidColor.alpha != 0xffff) || (xrSrcData.extraAlpha != 1.0f);
+-  /*Extra Alpha is already storen in solid-colo*/
+-  jdouble maskAlpha = (xrSrcData.src == xrSrcData.solid) ? 1.0f : xrSrcData.extraAlpha;
++  /*Extra Alpha is already stored in solid-color*/
++  jdouble maskAlpha = (xrSrcData.src != xrSrcData.texture) ? 1.0f : xrSrcData.extraAlpha;
+ 
+   unsigned short alphaValueFixed = XDoubleToUShort(maskAlpha);
+   XRenderColor maskColor;
+   maskColor.alpha = alphaValueFixed;
+ 
+-  /* If we don't have to use a mask and there are no lines, 
++  /* If we don't have to use a mask and there are no lines,
+    * we can draw the rects directly and omit tile partitioning */
+   if(maskRequired || buf->lines.used > 0) {
+   allocTileBuffer(buf);
+@@ -369,9 +343,10 @@
+           width = MIN(width, MASK_TILE_SIZE);
+           height = MIN(height, MASK_TILE_SIZE);
+ 
+-	  if(maskRequired || lineList->used  > 0) /*Again, only composite _current_tile_ if required, otherwise just fill rects*/
+-          {
++          /*Again, only composite the current tile if required, otherwise just fill rects*/
++	  if(maskRequired || lineList->used  > 0) {
+             Picture mask = None;
++
+             if(lineList->used != 0) {
+               XDrawSegments(awt_display, buf->lineMaskPixmap, buf->drawLineGC, (XSegment *) lineList->elements, lineList->used);
+               mask = buf->lineMaskPicture;
+@@ -386,16 +361,17 @@
+ 
+              XRComposite(mask, dest, x, y, tileDirtyArea.x, tileDirtyArea.y, x, y, width, height);
+ 
+-             /*Clear dirty rectangle of the rect-mask*/
++             /* Clear dirty rectangle of the rect-mask */
+              XRenderFillRectangle (awt_display, PictOpClear, buf->maskPicture, &color_black, tileDirtyArea.x, tileDirtyArea.y, width, height);
+ 
++             /* Clear diagonal lines with lines again,
++                to avoid the sysmem copy marked "dirty" causing migration for the next lines*/
+              if(lineList->used != 0) {
+                XDrawSegments(awt_display, buf->lineMaskPixmap, buf->clearLineGC, (XSegment *) lineList->elements, lineList->used);
+                clearXRList(lineList);
+ 	     }
+           }else
+-          if(rectList->used != 0)
+-          {
++          if(rectList->used != 0) {
+              translateRects(rectList, (tileStartX + buf->region.x), (tileStartY + buf->region.y));
+              XRenderFillRectangles (awt_display, xrSrcData.compRule, dest, &xrSrcData.solidColor, (XRectangle*) rectList->elements, rectList->used);
+              clearXRList(rectList);
+@@ -403,8 +379,7 @@
+         }
+       }
+      }
+- } else 
+- {
++  } else {
+    XRenderFillRectangles (awt_display, xrSrcData.compRule, dest, &xrSrcData.solidColor, (XRectangle*) buf->rects.elements, buf->rects.used);
+  }
+ 
+@@ -412,165 +387,3 @@
+ }
+ 
+ #endif
+-
+-
+-	   /*printf("Composition: x:%d y:%d width:%d height:%d, dx:%d, dy:%d\n", x, y, width, height, tileDirtyArea.x, tileDirtyArea.y);
+-           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, 0, 0, MASK_TILE_SIZE, 1);
+-           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, 0, MASK_TILE_SIZE-1, MASK_TILE_SIZE, 1);
+-           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, 0, 0, 1, MASK_TILE_SIZE);
+-           XRenderFillRectangle (awt_display, PictOpSrc, buf->maskPicture, &color_black, MASK_TILE_SIZE-1, 0, 1, MASK_TILE_SIZE);*/
+-
+-
+-
+-           /* if(xrSrcData.src == xrSrcData.gradient)
+-             { 
+-               XRenderComposite (awt_display, PictOpSrc, xrSrcData.gradient, None, buf->gradPict, x, y, 0, 0, 0, 0, width, height);
+-               XRenderComposite (awt_display, xrSrcData.compRule, buf->gradPict, mask, dest, 0, 0, tileDirtyArea.x, tileDirtyArea.y, x, y, width, height);
+-             }else 
+-             {
+-               XRenderComposite (awt_display, xrSrcData.compRule, xrSrcData.src, mask, dest, x, y, tileDirtyArea.x, tileDirtyArea.y, x, y, width, height);
+-             }*/
+-
+-/*
+-void addTrap(MaskBuffer* buf, XTrapezoid *xt)
+-{
+-  XTrapezoid *trap = (XTrapezoid*) getNewXR(&buf->traps, sizeof(XTrapezoid));
+-  memcpy(trap, xt, sizeof(XTrapezoid));
+-
+-  int leftMin = XFixedToDouble(MIN(trap->left.p1.x, trap->left.p2.x)) - 1;
+-  int rightMax = XFixedToDouble(MAX(trap->right.p2.x, trap->right.p1.x)) + 1;
+-  int top = XFixedToDouble(trap->top) - 1;
+-  int bottom = XFixedToDouble(trap->bottom) + 1;
+-
+-  growDirtyRegion(&buf->region, leftMin, top, rightMax, bottom);
+-}
+-*/
+-
+-/*void translateTrap(XTrapezoid *trap, int x, int y)
+-{
+-   XFixed xTrans = XDoubleToFixed(x);     
+-   XFixed yTrans = XDoubleToFixed(y);
+-
+-   trap->left.p1.x  += xTrans;
+-   trap->left.p2.x  += xTrans;
+-   trap->right.p1.x += xTrans;    
+-   trap->right.p2.x += xTrans;
+-   trap->left.p1.y  += yTrans;
+-   trap->left.p2.y  += yTrans;
+-   trap->right.p1.y += yTrans;
+-   trap->right.p2.y += yTrans;
+-   trap->top += yTrans;
+-   trap->bottom += yTrans;
+-}*/
+-
+-/*
+-void storeTrapsInTiles(MaskBuffer *buf)
+-{
+-  int i,n,m;
+-
+-  for(i=0; i < buf->traps.used; i++) {
+-     XTrapezoid *trap = ((XTrapezoid*) buf->traps.elements) + i;
+-     translateTrap(trap, -buf->region.x, -buf->region.y);
+-
+-     int leftMin = XFixedToDouble(MIN(trap->left.p1.x, trap->left.p2.x));
+-     int rightMax = XFixedToDouble(MAX(trap->right.p2.x, trap->right.p1.x));
+-     int top = XFixedToDouble(trap->top) - 1;
+-     int bottom = XFixedToDouble(trap->bottom) + 1;
+-
+-     int tileXStartIndex = leftMin / MASK_TILE_SIZE;
+-     int tileYStartIndex = top / MASK_TILE_SIZE;
+-     int tileXLenght = ((rightMax / MASK_TILE_SIZE) + 1) - tileXStartIndex;
+-     int tileYLenght = ((bottom / MASK_TILE_SIZE) + 1) - tileYStartIndex;
+-
+-      for(n=0; n < tileYLenght; n++) {
+-        for(m=0; m < tileXLenght; m++) {
+-          int tileIndex = (buf->xTileCap * (tileYStartIndex + n)) + tileXStartIndex + m;
+-          assert(tileIndex >= 0);
+-          XrTile *tile = &buf->tiles[tileIndex];
+-
+-          XTrapezoid *tileTrap = (XTrapezoid*) getNewXR(&tile->traps, sizeof(XTrapezoid));
+-          memcpy(tileTrap, trap, sizeof(XTrapezoid));
+-
+-          int tileStartPosX = (tileXStartIndex + m) * MASK_TILE_SIZE;
+-          int tileStartPosY = (tileYStartIndex + n) * MASK_TILE_SIZE;
+-          translateTrap(tileTrap, -tileStartPosX, -tileStartPosY);
+-
+-          leftMin = XFixedToDouble(MIN(tileTrap->left.p1.x, tileTrap->left.p2.x)) - 1;
+-          rightMax = XFixedToDouble(MAX(tileTrap->right.p2.x, tileTrap->right.p1.x)) + 1;
+-          top = XFixedToDouble(tileTrap->top) - 1;
+-          bottom = XFixedToDouble(tileTrap->bottom) + 1;
+-
+-         // limitRetcCoords(tileRect);
+-          //TODO: Better dirty array handling
+-          growDirtyRegionTileLimit(&tile->dirtyArea, leftMin, top, rightMax, bottom);
+-        }
+-      }
+-  }
+-}*/
+-
+-//   XrArrayList tileRectList;
+-//   initXRList(&tileRectList, sizeof(XRectangle), 64); //Todo memory leak!
+-// 
+-//   int i, tileStartX, tileStartY;
+-//   MaskRegion ditryRegion;
+-// 
+-//   for(tileStartX = buf->region.x; tileStartX <= buf->region.x2; tileStartX += MASK_TILE_SIZE) {
+-//    int tileEndX = tileStartX + MASK_TILE_SIZE;
+-// 
+-//     for(tileStartY = buf->region.y; tileStartY <= buf->region.y2; tileStartY += MASK_TILE_SIZE) {
+-//       int tileEndY = tileStartY + MASK_TILE_SIZE;
+-//       initRegion(&ditryRegion);
+-// 
+-//       for(i=0; i < buf->rects.used; i++) {
+-//         XRectangle *rect = ((XRectangle*) buf->rects.elements) + i;
+-// 
+-//         if((rect->x <= tileEndX) && ((rect->x + rect->width) > tileStartX) &&
+-//            (rect->y <= tileEndY) && ((rect->y + rect->height) > tileStartY)) {
+-// 	  XRectangle *ptr = (XRectangle *) getNewXR(&tileRectList);
+-//           ptr->x = rect->x - tileStartX; /*Translate coordinates relative to the mask-location*/
+-//           ptr->y = rect->y - tileStartY;
+-//           ptr->width = rect->width;
+-//           ptr->height = rect->height;
+-// 
+-//           limitRetcCoords(ptr);
+-//           growDirtyRegion(&ditryRegion, ptr->x, ptr->y, ptr->x + ptr->width, ptr->y + ptr->height);
+-//         }
+-//       }
+-// 
+-//         if(tileRectList.used > 0) { 
+-//            XRenderFillRectangles (display, PictOpSrc, mask, alphaColor, (XRectangle*) tileRectList.elements, tileRectList.used);
+-//            clearXRList(&tileRectList);
+-// 
+-//            int x = ditryRegion.x + tileStartX;
+-//            int y = ditryRegion.y + tileStartY;
+-//            int width = ditryRegion.x2 - ditryRegion.x;
+-//            int height = ditryRegion.y2 - ditryRegion.y;
+-// 
+-//            XRenderComposite (display, PictOpOver, src, mask, dest, x, y, ditryRegion.x, ditryRegion.y, x, y, width, height);
+-//            XRenderFillRectangle (display, PictOpClear, mask, alphaColor, ditryRegion.x, ditryRegion.y, width, height);
+-//         }
+-//     } 
+-//   }
+-
+-
+-/*
+-          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, MASK_TILE_SIZE, 1);
+-          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, MASK_TILE_SIZE-1, MASK_TILE_SIZE, 1);
+-          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, 1, MASK_TILE_SIZE);
+-          XRenderFillRectangle (display, PictOpSrc, mask, &color_black, MASK_TILE_SIZE-1, 0, 1, MASK_TILE_SIZE);
+-*/
+-
+-//         int z;
+-//         for(z=0; z < tileRectList.used; z++)
+-//  {
+-//      XRectangle *rect = ((XRectangle*) tileRectList.elements) + z;
+-//      printf("Rechteck %d - %d %d %d %d %d\n", z, rect->x, rect->y, rect->width, rect->height, tileRectList.used);
+-// }
+-
+-//printf("Composition rect: %d %d %d %d\n", x, y, ditryRegion.x2 - ditryRegion.x, ditryRegion.y2 - ditryRegion.y);fflush(stdout);
+-          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, MASK_TILE_SIZE, 1);
+-          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, MASK_TILE_SIZE-1, MASK_TILE_SIZE, 1);
+-          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, 0, 0, 1, MASK_TILE_SIZE);
+-          //XRenderFillRectangle (display, PictOpSrc, mask, &color_black, MASK_TILE_SIZE-1, 0, 1, MASK_TILE_SIZE);
+-
+-// printf("Rendering region: %d %d %d %d\n", buf->region.x, buf->region.y, buf->region.x2 - buf->region.x, buf->region.y2 - buf->region.y);fflush(stdout);
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/MaskBuffer.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	Fri Aug 01 22:43:51 2008 +0200
+@@ -1,3 +1,11 @@
++/* MaskBuffer buffers geometry (for now only lines and rects),
++ * renders those primitives into a mask in one go and composites
++ * using the mask as geometry-buffer.
++ * The advantage is that rendering rects can be done quite efficiently,
++ * but composition scanline-by-scanline is very slow.
++ * Please see the project-page for an in-depth explanation of MaskBuffer.
++ */
++
+ #ifndef MaskBuffer_h_Included
+ #define MaskBuffer_h_Included
+ 
+@@ -10,6 +18,8 @@
+ #include <X11/extensions/Xrender.h>
+ #include <assert.h>
+ 
++/* To not alloc/dealloc the mask pixmap tiling is used.
++   This specifies the size of the alpha-tile.        */
+ #define MASK_TILE_SIZE 256
+ 
+ typedef struct {
+@@ -19,6 +29,7 @@
+   jint y2;
+ }MaskRegion;
+ 
++/*Holds information which belongs to a single tile*/
+ typedef struct {
+   XrArrayList rects;
+   XrArrayList lines;
+@@ -27,6 +38,8 @@
+   MaskRegion dirtyLineArea;
+ } XrTile;
+ 
++/* The MaskBuffer data-structure itself is shared in the application
++   and contains pixmaps for gradient-caching and MaskFill/MaskBlit */
+ typedef struct {
+   Pixmap lineMaskPixmap;
+   Picture lineMaskPicture;
+@@ -35,6 +48,7 @@
+ 
+   Pixmap maskPixmap;
+   Picture maskPicture;
++  GC maskGC;
+   jfloat validatedGCAlpha;
+ 
+   XrArrayList rects;
+@@ -47,34 +61,59 @@
+   int yTileCap;
+   XrTile *tiles;
+ 
+-  Pixmap gradPixmap;
+-  Picture gradPict;
++  XImage *alphaImg;
++  unsigned char* alphaData;
++  jint aImgWidth;
++  jint aImgHeight;
+ }MaskBuffer;
+ 
++/* Initializes the MaskBuffer data structure*/
+ MaskBuffer* initMaskBuffer(Window window);
+ 
++/* Adds a rect which will be filled to the geometry-buffer*/ 
+ void addRect(MaskBuffer* buf, short x, short y, unsigned short w, unsigned short h);
+ 
++/* Adds a line to the geometry-buffer*/
+ void addLine(MaskBuffer* buf, int x1, int y1, int x2, int y2);
+ 
++/* Composites using the stored geometry as mask, using properties stored in SrcSurfaceData*/
+ void fillMask(MaskBuffer* buf, Picture dest);
+ 
++/* Builds a 2D array of tiles and adds the rects buffered by addRect,
++   to the tiles which are affacted. */
+ static void storeRectsInTiles(MaskBuffer *buf);
+ 
++/* Builds a 2D array of tiles and adds the lines stored by addLine 
++ * to the tiles which are affacted*/
++static void storeLinesInTiles(MaskBuffer *buf);
++
++/* Re-sets the MaskBuffer to an empty state */
+ static void cleanMaskBuffer(MaskBuffer *buf);
+ 
++/* Shrinks the rectangle's coordinates if in the middle of two tiles*/
+ static void limitRetcCoords(XRectangle *rect);
+ 
++/* Re-Sets the values of a MaskRegion */
+ static void initRegion(MaskRegion *region);
+ 
++/* If parameters are outside the bounds of the MaskRegion, the MaskRegion will be enlarged */
+ static void growDirtyRegion(MaskRegion *region, jint x, jint y, jint x2, jint y2);
+ 
++/* If parameters are outside the bounds of the MaskRegion, the MaskRegion will be enlarged, 
++   but is limited to the size of a single tile */
+ static void growDirtyRegionTileLimit(MaskRegion *region, jint x, jint y, jint x2, jint y2);
+ 
++/* Re-Sets a tile data-structure*/
+ static void initXrTile(XrTile *tile);
+ 
++/* Returns the total dirty size of both, the rect and the line tile combined */
+ static void getTileDirtyArea(MaskRegion *dirtyRectArea, MaskRegion *dirtyLineArea, MaskRegion *totalDirtyArea);
+ 
++/* Translates all rects in rectList by x/y */
+ static void translateRects(XrArrayList *rectList, int x, int y);
+ 
++/* Allocates and initializes the tile-datastructures nescessary
++   to hold the geometry stored in the MaskBuffer*/
++static void allocTileBuffer(MaskBuffer* buf);
++
+ #endif /* MaskBuffer_h_Included */
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/X11SurfaceData.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -97,7 +97,7 @@
+ 
+ #endif /* !HEADLESS */
+ 
+-jboolean XShared_initIDs(JNIEnv *env)
++jboolean XShared_initIDs(JNIEnv *env, jboolean allowShmPixmaps)
+ {
+ #ifndef HEADLESS
+    union {
+@@ -122,14 +122,19 @@
+         getenv("NO_J2D_MITSHM") == NULL) {
+         char * force;
+         TryInitMITShm(env, &useMitShmExt, &useMitShmPixmaps);
+-        useMitShmPixmaps = (useMitShmPixmaps == CAN_USE_MITSHM);
+-        force = getenv("J2D_PIXMAPS");
+-        if (force != NULL) {
+-            if (useMitShmPixmaps && (strcmp(force, "shared") == 0)) {
+-                forceSharedPixmaps = JNI_TRUE;
+-            } else if (strcmp(force, "server") == 0) {
+-                useMitShmPixmaps = JNI_FALSE;
+-            }
++
++        if(allowShmPixmaps) {
++          useMitShmPixmaps = (useMitShmPixmaps == CAN_USE_MITSHM);
++          force = getenv("J2D_PIXMAPS");
++          if (force != NULL) {
++              if (useMitShmPixmaps && (strcmp(force, "shared") == 0)) {
++                  forceSharedPixmaps = JNI_TRUE;
++              } else if (strcmp(force, "server") == 0) {
++                  useMitShmPixmaps = JNI_FALSE;
++              }
++          }
++        }else {
++          useMitShmPixmaps = JNI_FALSE;
+         }
+     }
+ 
+@@ -150,7 +155,7 @@
+                                            jclass XORComp, jboolean tryDGA)
+ {
+ #ifndef HEADLESS
+-  if(XShared_initIDs(env))
++  if(XShared_initIDs(env, JNI_TRUE))
+   {
+     void *lib = 0;
+ 
+@@ -189,7 +194,7 @@
+  * Signature: ()Z
+  */
+ JNIEXPORT jboolean JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_isDrawableValid(JNIEnv *env, jobject this)
++Java_sun_java2d_x11_XSurfaceData_isDrawableValid(JNIEnv *env, jobject this)
+ {
+     jboolean ret = JNI_FALSE;
+ 
+@@ -227,7 +232,7 @@
+  * Signature: (Ljava/lang/Object;I)V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_initOps(JNIEnv *env, jobject xsd,
++Java_sun_java2d_x11_XSurfaceData_initOps(JNIEnv *env, jobject xsd,
+                                            jobject peer,
+                                            jobject graphicsConfig, jint depth)
+ {
+@@ -311,7 +316,7 @@
+  * Signature: ()V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)
++Java_sun_java2d_x11_XSurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)
+ {
+ #ifndef HEADLESS
+     SurfaceDataOps *ops = SurfaceData_GetOps(env, xsd);
+@@ -395,7 +400,7 @@
+  * Signature: ()V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_setInvalid(JNIEnv *env, jobject xsd)
++Java_sun_java2d_x11_XSurfaceData_setInvalid(JNIEnv *env, jobject xsd)
+ {
+ #ifndef HEADLESS
+     X11SDOps *xsdo = (X11SDOps *) SurfaceData_GetOps(env, xsd);
+@@ -1584,7 +1589,7 @@
+  * Signature: (I)J
+  */
+ JNIEXPORT jlong JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_XCreateGC
++Java_sun_java2d_x11_XSurfaceData_XCreateGC
+     (JNIEnv *env, jclass xsd, jlong pXSData)
+ {
+     jlong ret;
+@@ -1614,7 +1619,7 @@
+  * Signature: (JIIIILsun/java2d/pipe/Region;)V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_XResetClip
++Java_sun_java2d_x11_XSurfaceData_XResetClip
+     (JNIEnv *env, jclass xsd, jlong xgc)
+ {
+ #ifndef HEADLESS
+@@ -1629,7 +1634,7 @@
+  * Signature: (JIIIILsun/java2d/pipe/Region;)V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_XSetClip
++Java_sun_java2d_x11_XSurfaceData_XSetClip
+     (JNIEnv *env, jclass xsd, jlong xgc,
+      jint x1, jint y1, jint x2, jint y2,
+      jobject complexclip)
+@@ -1704,7 +1709,7 @@
+  * Signature: (JZ)V
+  */
+ JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_XSetGraphicsExposures
++Java_sun_java2d_x11_XSurfaceData_XSetGraphicsExposures
+     (JNIEnv *env, jclass xsd, jlong xgc, jboolean needExposures)
+ {
+ #ifndef HEADLESS
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/X11SurfaceData.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.h	Fri Aug 01 22:43:51 2008 +0200
+@@ -166,17 +166,17 @@
+ /*Prototypes for shared functions used by XRSurfaceData*/
+ jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable);
+ 
+-jboolean XShared_initIDs(JNIEnv *env);
++jboolean XShared_initIDs(JNIEnv *env, jboolean allowShmPixmaps);
+ 
+-JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_initOps(JNIEnv *env, jobject xsd,
+-                                           jobject peer,
+-                                           jobject graphicsConfig, jint depth);
++// JNIEXPORT void JNICALL
++// Java_sun_java2d_x11_X11SurfaceData_initOps(JNIEnv *env, jobject xsd,
++//                                            jobject peer,
++//                                            jobject graphicsConfig, jint depth);
+ 
+-JNIEXPORT jlong JNICALL Java_sun_java2d_x11_X11SurfaceData_XCreateGC (JNIEnv *env, jclass xsd, jlong pXSData);
++// JNIEXPORT jlong JNICALL Java_sun_java2d_x11_X11SurfaceData_XCreateGC (JNIEnv *env, jclass xsd, jlong pXSData);
+ 
+ jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo);
++/*
++JNIEXPORT void JNICALL
++Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd);*/
+ 
+-JNIEXPORT void JNICALL
+-Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd);
+-
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRGlyphCache.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -35,6 +35,7 @@
+ 
+     return cache;
+ }
++
+ 
+ static jboolean cleanCache(XRGlyphCacheInfo *cache)
+ {
+@@ -158,7 +159,13 @@
+      
+ 
+      Glyph gid = (Glyph) cacheCell->glyphID;
+-     XGlyphInfo xginfo={.x=(jginfo->topLeftX*-1),.y=(jginfo->topLeftY*-1),.width=width,.height=height, .xOff = cacheCell->xOff,.yOff = cacheCell->yOff};
++     XGlyphInfo xginfo;
++     xginfo.x = (jginfo->topLeftX*-1);
++     xginfo.y = (jginfo->topLeftY*-1);
++     xginfo.width = width;
++     xginfo.height = height;
++     xginfo.xOff = cacheCell->xOff;
++     xginfo.yOff = cacheCell->yOff;
+ 
+      XRenderAddGlyphs(awt_display, cache->glyphSet, &gid, &xginfo, 1, glyphBuf, bufLen);
+      
+@@ -242,25 +249,23 @@
+    return JNI_TRUE;
+ }
+ 
+-#if 0
+-void dumpCache(XRGlyphCacheInfo *cache)
+-{
+-  int i;
+-  for(i=0; i < cache->cellCapacity; i++)
+-  {
+-    XRCacheCellInfo *cell = &cache->cells[i];
+-    if(cell->glyphID != 0)
+-    {
+-      printf("Cache-Position: %d enthaelt glyph: %d mit counter:%d\n", i, cell->glyphID, cell->timesRendered);
+-      fflush(stdout);
+-    }
+-  }
+-}
+-#endif
+-
+ #endif /*!Headless*/
+ 
+ 
++// Dev-only debug and trace function.
++// void dumpCache(XRGlyphCacheInfo *cache)
++// {
++//   int i;
++//   for(i=0; i < cache->cellCapacity; i++)
++//   {
++//     XRCacheCellInfo *cell = &cache->cells[i];
++//     if(cell->glyphID != 0)
++//     {
++//       printf("Cache-Position: %d enthaelt glyph: %d mit counter:%d\n", i, cell->glyphID, cell->timesRendered);
++//       fflush(stdout);
++//     }
++//   }
++// }
+ // 	  int line_, pix_;
+ // 	  for(line_ = 0; line_ < jginfo->height; line_++)
+ // 	  {
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRGlyphCache.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	Fri Aug 01 22:43:51 2008 +0200
+@@ -11,6 +11,7 @@
+ typedef struct _XRGlyphCacheInfo XRGlyphCacheInfo;
+ typedef struct _XRCacheCellInfo XRCacheCellInfo;
+ 
++/* Cell-Cache structure*/
+ struct _XRGlyphCacheInfo {
+     XRCacheCellInfo *cells;
+     jint searchPosition;
+@@ -20,6 +21,10 @@
+     GlyphSet glyphSet;
+ };
+ 
++/* CacheCellInfo structure, 
++*  holds a cached GlyphInfo and
++*  other per-glpyh information.
++*/
+ struct _XRCacheCellInfo {
+     XRGlyphCacheInfo *cacheInfo;
+     GlyphInfo *glyphInfo;
+@@ -33,9 +38,17 @@
+ };
+ 
+ #ifndef HEADLESS
++/*Initialized the GlyphCache structure*/
+ XRGlyphCacheInfo* XRGlyphCache_Init(XRenderPictFormat* glyphSetPictFormat);
++
++/*Add a list of GlyphInfo's to the cache, returns false of not succeeded.*/
+ jboolean XRGlyphCache_CacheGlyphs(XRGlyphCacheInfo *cache, jlong *glyphPtrs, jint glyphCount, jint *ids);
+-void dumpCache(XRGlyphCacheInfo *cache);
++
++/* Frees entries which have not been used a lot, and enlarges cache if nescessary */
++static jboolean cleanCache(XRGlyphCacheInfo *cache);
++
++/* Adds a single glyph to the cache and uploads it to the X-Server*/
++static jboolean uploadGlyph(XRGlyphCacheInfo *cache, GlyphInfo *jginfo, XRCacheCellInfo *cacheCell);
+ #endif
+ 
+ #endif /* XRGlyphCache_h_Included */
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -59,84 +59,69 @@
+         return;
+     }
+ 
+-#ifdef MITSHM
+-    if (srcXsdo->isPixmap) {
+-        X11SD_UnPuntPixmap(srcXsdo);
+-    }
+-#endif /* MITSHM */
++    XRenderComposite (awt_display, xrSrcData.compRule, srcXsdo->xrPic, xrSrcData.alphaMask, dstXsdo->xrPic, srcx, srcy, 0, 0, dstx, dsty, width, height); 
+ 
+-/*   printf("src: %d, dst: %d", srcXsdo->xrData.xrPic, dstXsdo->xrData.xrPic);
+-   fflush(stdout);*/
+-
+-/*XTransform xf = {{{XDoubleToFixed (0.5), 0, 0 },
+-{0, XDoubleToFixed (0.5), 0 },
+-{XDoubleToFixed (0), XDoubleToFixed (0), XDoubleToFixed (1.0)}}};
+-
+-XRenderSetPictureTransform(awt_display, dstXsdo->xrData.xrPic, &xf);
+-XRenderSetPictureFilter(awt_display, dstXsdo->xrData.xrPic, "good", NULL, 0);*/
+-
+-   XRenderComposite (awt_display, xrSrcData.compRule, srcXsdo->xrPic, xrSrcData.alphaMask, dstXsdo->xrPic, srcx, srcy, 0, 0, dstx, dsty, width, height); 
+-
+-#ifdef MITSHM
+-    if (srcXsdo->shmPMData.usingShmPixmap) {
+-        srcXsdo->shmPMData.xRequestSent = JNI_TRUE;
+-    }
+-#endif /* MITSHM */
+     X11SD_DirectRenderNotify(env, dstXsdo);
+ #endif /* !HEADLESS */
+ }
+ 
++
+ #ifndef HEADLESS
+-static Picture prepareMaskPM(JNIEnv *env, X11SDOps *alphaXsdo, jbyteArray maskArray, jint maskoff, jint maskscan, jint w, jint h)
++static Picture prepareMaskPM(JNIEnv *env, jbyteArray maskArray, jint maskoff, jint maskscan, jint w, jint h)
+ {
+     int line, pix;
+     unsigned char *mask;
+-    SurfaceDataOps *alphaOps = &alphaXsdo->sdOps;
+ 
+-    jboolean useEA = (xrSrcData.src != xrSrcData.solid && xrSrcData.extraAlpha != 1.0f);
++    jboolean useEA = (xrSrcData.src == xrSrcData.texture && xrSrcData.extraAlpha != 1.0f);
+ 
+-    if (maskArray != NULL) {
+-    		SurfaceDataRasInfo alphaInfo;
+-    		alphaInfo.bounds.x1 = 0;
+-    		alphaInfo.bounds.y1 = 0;
+-    		alphaInfo.bounds.x2 = w;
+-    		alphaInfo.bounds.y2 = h;
++    if(maskArray != NULL) {
+ 
+-		if (alphaOps->Lock(env, alphaOps, &alphaInfo, SD_LOCK_WRITE) != SD_SUCCESS) {
+-			SurfaceData_InvokeUnlock(env, alphaOps, &alphaInfo);
+-			return None;
+-		}
+-                mask = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, maskArray, NULL);
++         mask = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, maskArray, NULL);
+ 
+-		alphaOps->GetRasInfo(env, alphaOps, &alphaInfo);
++         /* Tries to optimize Mask-Upload:  
++          * 1. If existing XImage and supplied buffer match, only adjust the data pointer
++          * 2. If existing XImage is large enough to hold the data put does not match in scan,
++          *    the data is copied in way to fit the XImage.
++          * 3. If data is larger than the existing XImage a new temporary XImage is allocated
++          * The default XImage is optimized for the AA tiles, which are currently 32x32.
++          */
++          XImage *defaultImg = maskBuffer->alphaImg;
++          XImage *img = maskBuffer->alphaImg;
++          jboolean imageFits = defaultImg->width >= w && defaultImg->height >= h;
+ 
+-              if(useEA && (w > MASK_TILE_SIZE || h > MASK_TILE_SIZE))
+-              {
+-		for(line=0; line < h; line++) {
+-		  for(pix=0; pix < w; pix++) {
+-  		     ((unsigned char*)alphaInfo.rasBase)[line*alphaInfo.scanStride + pix] = (unsigned char) (mask[maskscan*line + pix + maskoff] * xrSrcData.extraAlpha);  
+-		  }
+-		}
+-             }else
+-             {
+-		for(line=0; line < h; line++) {
+-		  for(pix=0; pix < w; pix++) {
+-  		     ((unsigned char*)alphaInfo.rasBase)[line*alphaInfo.scanStride + pix] = (unsigned char) (mask[maskscan*line + pix + maskoff]);  
+-		  }
+-		}
+-             }
++          if(imageFits && maskoff == defaultImg->xoffset && maskscan == defaultImg->bytes_per_line) {
++                defaultImg->data = mask;
++          }else {
++            if(imageFits) {
++               defaultImg->data = maskBuffer->alphaData;
+ 
+-                SurfaceData_InvokeRelease(env, alphaOps, &alphaInfo);
+-                SurfaceData_InvokeUnlock(env, alphaOps, &alphaInfo);
+-                (*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT);
++               for(line=0; line < h; line++) {
++                   for(pix=0; pix < w; pix++) {
++                       img->data[line*img->bytes_per_line + pix] = (unsigned char) (mask[maskscan*line + pix + maskoff]);  
++                   }
++               }
+ 
+-	if(useEA) {
+-                XRenderComposite (awt_display, PictOpOver, alphaXsdo->xrPic, xrSrcData.alphaMask, maskBuffer->maskPicture, 0, 0, 0, 0, 0, 0, w, h); 
+-                return maskBuffer->maskPicture;
+-          }else
+-          {
+-             return alphaXsdo->xrPic;
++            }else { 
++               /*TODO: handle case where XImage is larger than pixmap*/
++               img = XCreateImage(awt_display, &maskBuffer->maskPixmap, 8, ZPixmap, maskoff, mask, maskscan, h, 8, 0);
++            }
+           }
++
++          XPutImage(awt_display, maskBuffer->maskPixmap, maskBuffer->maskGC, img, 0, 0, 0, 0, w, h);
++          (*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT);
++
++	  if(img != defaultImg) {
++             img->data = NULL;
++             XDestroyImage(img);
++          }
++
++        /* XRender does not expose multitexturing, therefor we have to Composite with the alphaMask to get EA in*/
++	if(useEA)  {
++                XRenderComposite (awt_display, PictOpSrc, maskBuffer->maskPicture, xrSrcData.alphaMask, maskBuffer->lineMaskPicture, 0, 0, 0, 0, 0, 0, w, h); 
++                return maskBuffer->lineMaskPicture;
++	}else {
++           return maskBuffer->maskPicture;
++        }
+     }else
+     {
+       if(useEA) {
+@@ -147,12 +132,11 @@
+     return None;
+ }
+ 
+-static void cleanMask(Picture mask, int w, int h)
+-{
+-  if(mask == maskBuffer->maskPicture)
+-  {
+-     XRenderColor color_black={.red=0, .green=0, .blue=0, .alpha=0xffff};
+-     XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->maskPicture, &color_black, 0, 0, w, h);
++/* Clean up the area of the masks which have been used as target-pixmap for mask-upload */
++static void cleanMask(Picture mask, int w, int h) {
++  XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->maskPicture, &color_black, 0, 0, w, h);
++  if(mask == maskBuffer->lineMaskPicture) {
++     XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->lineMaskPicture, &color_black, 0, 0, w, h);
+   }
+ }
+ #endif
+@@ -160,7 +144,7 @@
+ JNIEXPORT void JNICALL
+ Java_sun_java2d_xr_XRMaskFill_maskFill
+      (JNIEnv *env, jobject joSelf, 
+-      jlong dstData, jlong alphaData,
++      jlong dstData,
+       jint x, jint y, jint w, jint h,
+       jint maskoff, jint maskscan, 
+       jint masklen, jbyteArray maskArray)
+@@ -169,17 +153,14 @@
+     J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_maskFill");
+ 
+     Picture maskPic;
+-    X11SDOps *dstXsdo, *alphaXsdo;
++    X11SDOps *dstXsdo;
+     dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
+-    alphaXsdo = (X11SDOps *)jlong_to_ptr(alphaData);
+-    if (dstXsdo == NULL || alphaXsdo == NULL) {
++    if (dstXsdo == NULL) {
+         return;
+     }
+ 
+-    maskPic = prepareMaskPM(env, alphaXsdo, maskArray, maskoff, maskscan, w, h);
+-
++    maskPic = prepareMaskPM(env, maskArray, maskoff, maskscan, w, h);
+     XRComposite(maskPic, dstXsdo->xrPic, x, y, 0, 0, x, y, w, h);
+-
+     cleanMask(maskPic, w, h);
+ 
+     X11SD_DirectRenderNotify(env, dstXsdo);
+@@ -190,7 +171,7 @@
+ JNIEXPORT void JNICALL
+ Java_sun_java2d_xr_XRMaskBlit_maskBlit
+      (JNIEnv *env, jobject joSelf, 
+-      jlong srcData, jlong dstData, jlong alphaData,
++      jlong srcData, jlong dstData,
+       jint srcx, jint srcy,
+       jint dstx, jint dsty, jint w, jint h,
+       jint maskoff, jint maskscan, 
+@@ -200,15 +181,14 @@
+     J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_maskBlit");
+ 
+     Picture maskPic;
+-    X11SDOps *srcXsdo, *dstXsdo, *alphaXsdo;
++    X11SDOps *srcXsdo, *dstXsdo;
+     srcXsdo = (X11SDOps *)jlong_to_ptr(srcData);
+     dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
+-    alphaXsdo = (X11SDOps *)jlong_to_ptr(alphaData);
+-    if (srcXsdo == NULL || dstXsdo == NULL || alphaXsdo == NULL) {
++    if (srcXsdo == NULL || dstXsdo == NULL) {
+         return;
+     }
+ 
+-    maskPic = prepareMaskPM(env, alphaXsdo, maskArray, maskoff, maskscan, w, h);
++    maskPic = prepareMaskPM(env, maskArray, maskoff, maskscan, w, h);
+     XRenderComposite (awt_display, xrSrcData.compRule, srcXsdo->xrPic, maskPic, dstXsdo->xrPic, srcx, srcy, 0, 0, dstx, dsty, w, h); 
+     cleanMask(maskPic, w, h);
+ 
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRRenderer.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRRenderer.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -49,6 +49,7 @@
+ #define CLAMP_TO_USHORT(x)  (((x) > 65535) ? 65535 : ((x) < 0) ? 0 : (x))
+ 
+ 
++/* Adds a PolyLine consisting of multiple points to the MaskBuffer */
+ JNIEXPORT void JNICALL XRDrawLines(Picture dst, XPoint * points, int npoints)
+ {
+ #ifndef HEADLESS
+@@ -216,6 +217,7 @@
+ #endif /* !HEADLESS */
+ }
+ 
++
+ JNIEXPORT void JNICALL Java_sun_java2d_xr_XRRenderer_XRFillRect
+     (JNIEnv *env, jobject xr,
+      jlong pXSData,
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRSurfaceData.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -6,6 +6,7 @@
+ #ifndef HEADLESS
+ SrcSurfaceData xrSrcData;
+ MaskBuffer *maskBuffer;
++XRenderColor color_black;
+ #endif /* !HEADLESS */
+ 
+ #define BUILD_TRANSFORM_MATRIX(TRANSFORM, M00, M01, M02, M10, M11, M12)                        \
+@@ -20,65 +21,6 @@
+       TRANSFORM.matrix[2][1] = 0;                                                              \
+       TRANSFORM.matrix[2][2] = 1<<16;                                                          \
+     }
+-
+-
+-JNIEXPORT void JNICALL
+-Java_sun_java2d_xr_XRSurfaceData_initOps(JNIEnv *env, jobject xsd,
+-                                           jobject peer,
+-                                           jobject graphicsConfig, jint depth)
+-{
+-   J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initOps");
+-
+-   Java_sun_java2d_x11_X11SurfaceData_initOps(env, xsd, peer, graphicsConfig, depth);
+-}
+-
+-JNIEXPORT jlong JNICALL Java_sun_java2d_xr_XRSurfaceData_XCreateGC (JNIEnv *env, jclass xsd, jlong pXSData)
+-{
+-   J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XCreateGC");
+-
+-   return Java_sun_java2d_x11_X11SurfaceData_XCreateGC (env, xsd, pXSData);
+-}
+-
+-JNIEXPORT void JNICALL
+-Java_sun_java2d_xr_XRSurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)
+-{
+-  J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_flushNativeSurface");
+-
+-  Java_sun_java2d_x11_X11SurfaceData_flushNativeSurface(env, xsd);
+-}
+-
+-
+-JNIEXPORT void JNICALL
+-Java_sun_java2d_xr_XRSurfaceData_setInvalid(JNIEnv *env, jobject xsd)
+-{
+-#ifndef HEADLESS
+-    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_setInvalid");
+-    X11SDOps *xsdo = (X11SDOps *) SurfaceData_GetOps(env, xsd);
+-
+-    if (xsdo != NULL) {
+-        xsdo->invalid = JNI_TRUE;
+-    }
+-#endif /* !HEADLESS */
+-}
+-
+-JNIEXPORT jboolean JNICALL
+-Java_sun_java2d_xr_XRSurfaceData_XRIsDrawableValid(JNIEnv *env, jobject this)
+-{
+-    jboolean ret = JNI_FALSE;
+-
+-#ifndef HEADLESS
+-    J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_XRIsDrawableValid");
+-    X11SDOps *xsdo = X11SurfaceData_GetOps(env, this);
+-
+-    if (xsdo->drawable != 0 || X11SD_InitWindow(env, xsdo) == SD_SUCCESS) {
+-        ret = JNI_TRUE;
+-    }
+-
+-#endif /* !HEADLESS */
+-
+-    return ret;
+-}
+-
+ 
+ JNIEXPORT void JNICALL
+    Java_sun_java2d_xr_XRSurfaceData_XRInitXRender(JNIEnv *env, jobject xsd, jlong pXSData, jint pictFormat)
+@@ -99,25 +41,37 @@
+     xsdo->xrPic = XRenderCreatePicture(awt_display, xsdo->drawable, fmt, CPRepeat, &pict_attr);
+   }
+ 
+-  if(maskBuffer == NULL) 
+-  {
++  /*TODO: Improper place to initialize that stuff here - however we need a drawable in order to create the pixmaps*/
++  if(maskBuffer == NULL) {
+     maskBuffer = initMaskBuffer(xsdo->drawable);
++    initXRSrcData(xsdo->drawable);
++  }
++#endif /* !HEADLESS */
++}
+ 
++static void initXRSrcData(Drawable *drawable) {
++#ifndef HEADLESS
+     XRenderPictureAttributes pict_attr;
+     pict_attr.repeat = 1;
+ 
+     /*Init solid color pen*/
+-    XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, PictStandardARGB32);
+-    Pixmap solidPixmap = XCreatePixmap(awt_display, xsdo->drawable, 1, 1, 32);
+-    xrSrcData.solid = XRenderCreatePicture(awt_display, solidPixmap, fmt, CPRepeat, &pict_attr);
++    XRenderPictFormat *fmt32 = XRenderFindStandardFormat(awt_display, PictStandardARGB32);
++    Pixmap solidPixmap = XCreatePixmap(awt_display, drawable, 1, 1, 32);
++    xrSrcData.solid = XRenderCreatePicture(awt_display, solidPixmap, fmt32, CPRepeat, &pict_attr);
+ 
+     /*Init extra-alpha mask*/
+-    fmt = XRenderFindStandardFormat(awt_display, PictStandardA8);
+-    Pixmap alphaPixmap = XCreatePixmap(awt_display, xsdo->drawable, 1, 1, 8);
+-    xrSrcData.alphaMaskPict = XRenderCreatePicture(awt_display, alphaPixmap, fmt, CPRepeat, &pict_attr);
+-  }
++    XRenderPictFormat *fmt8 = XRenderFindStandardFormat(awt_display, PictStandardA8);
++    Pixmap alphaPixmap = XCreatePixmap(awt_display, drawable, 1, 1, 8);
++    xrSrcData.alphaMaskPict = XRenderCreatePicture(awt_display, alphaPixmap, fmt8, CPRepeat, &pict_attr);
++
++    /*Init gradient cache*/
++    if(xrSrcData.gradCacheEnabled) {
++      xrSrcData.gradPixmap = XCreatePixmap(awt_display, drawable, MASK_TILE_SIZE, MASK_TILE_SIZE, 32);
++      xrSrcData.gradPict = XRenderCreatePicture(awt_display, xrSrcData.gradPixmap, fmt32, 0, &pict_attr);
++    }
+ #endif /* !HEADLESS */
+ }
++
+ 
+ JNIEXPORT void JNICALL
+ Java_sun_java2d_xr_XRSurfaceData_initIDs(JNIEnv *env, jclass xsd, jboolean gradCacheEnabled)
+@@ -133,18 +87,15 @@
+   xrSrcData.alphaMaskPict = None;
+   xrSrcData.compRule = PictOpOver;
+   xrSrcData.extraAlpha = 1.0f;
+-  xrSrcData.compRequired = JNI_FALSE;
+-
+-  xrSrcData.alphaColor.alpha = 0xffff;
+-  xrSrcData.alphaColor.red = 0xffff;
+-  xrSrcData.alphaColor.green = 0xffff;
+-  xrSrcData.alphaColor.blue = 0xffff;
+-
+   xrSrcData.gradCacheEnabled = gradCacheEnabled;
+-
+   maskBuffer = NULL;
+ 
+-  XShared_initIDs(env);
++  color_black.red=0;
++  color_black.green=0;
++  color_black.blue=0;
++  color_black.alpha=0xffff;
++
++  XShared_initIDs(env, JNI_FALSE);
+ #endif /* !HEADLESS */
+ }
+ 
+@@ -157,10 +108,10 @@
+ 
+   if(xrSrcData.src == xrSrcData.gradient && xrSrcData.gradCacheEnabled)
+   {
+-    XRenderComposite(awt_display, PictOpSrc, xrSrcData.gradient, None, maskBuffer->gradPict, srcX, srcY, 0, 0, 0, 0, width, height);
++    XRenderComposite(awt_display, PictOpSrc, xrSrcData.gradient, None, xrSrcData.gradPict, srcX, srcY, 0, 0, 0, 0, width, height);
+     cachedX = 0;
+     cachedY = 0; 
+-    cachedSrc = maskBuffer->gradPict;
++    cachedSrc = xrSrcData.gradPict;
+   }
+ 
+    XRenderComposite (awt_display, xrSrcData.compRule, cachedSrc, mask, dest, cachedX, cachedY, maskX, maskY, dstX, dstY, width, height);
+@@ -246,20 +197,24 @@
+    }
+ 
+     XLinearGradient grad;
+-    XRenderColor colors[numStops];
+-    XFixed stops[numStops];
+-
+     grad.p1.x = x1;
+     grad.p1.y = y1;
+     grad.p2.x = x2;
+     grad.p2.y = y2;
+ 
++    /*TODO optimized & malloc check*/
++    XRenderColor *colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor));
++    XFixed *stops =  (XFixed *) malloc(numStops * sizeof(XFixed));
++
+     for(i=0; i < numStops; i++) {
+       stops[i] = XDoubleToFixed(fractions[i]);
+-      decodeRenderColorPre(pixels[i], &colors[i]);
++      decodeRenderColorPre(pixels[i], colors + i);
+     }
+ 
+-    xrSrcData.gradient = XRenderCreateLinearGradient(awt_display, &grad, &stops[0], &colors[0], numStops);
++    xrSrcData.gradient = XRenderCreateLinearGradient(awt_display, &grad, stops, colors, numStops);
++    free(colors);
++    free(stops);
++
+     xrSrcData.src = xrSrcData.gradient;
+ 
+     XTransform tr;
+@@ -299,9 +254,6 @@
+    }
+ 
+     XRadialGradient grad;
+-    XRenderColor colors[numStops];
+-    XFixed stops[numStops];
+-
+     grad.inner.x = 0;
+     grad.inner.y = 0;
+     grad.inner.radius = innerRadius;
+@@ -309,12 +261,19 @@
+     grad.outer.y = 0;
+     grad.outer.radius = outerRadius;
+ 
++    /*TODO optimized & malloc check*/
++    XRenderColor *colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor));
++    XFixed *stops = (XFixed *) malloc(numStops * sizeof(XFixed));
++
+     for(i=0; i < numStops; i++) {
+       stops[i] = XDoubleToFixed(fractions[i]);
+-      decodeRenderColorPre(pixels[i], &colors[i]);
++      decodeRenderColorPre(pixels[i], colors + i);
+     }
+ 
+-    xrSrcData.gradient = XRenderCreateRadialGradient(awt_display, &grad, &stops[0], &colors[0], numStops);
++    xrSrcData.gradient = XRenderCreateRadialGradient(awt_display, &grad, stops, colors, numStops);
++    free(colors);
++    free(stops);
++
+     xrSrcData.src = xrSrcData.gradient;
+ 
+     XTransform tr;
+@@ -362,11 +321,12 @@
+ 
+   if(eAlpha != 1.0f) {
+     unsigned short alphaValue = XDoubleToUShort(eAlpha);
+-    xrSrcData.alphaColor.alpha = alphaValue;
+-    xrSrcData.alphaColor.red = alphaValue;
+-    xrSrcData.alphaColor.green = alphaValue;
+-    xrSrcData.alphaColor.blue = alphaValue;
+-    XRenderFillRectangle (awt_display, PictOpSrc, xrSrcData.alphaMaskPict, &xrSrcData.alphaColor, 0, 0, 1, 1);
++    XRenderColor alphaColor;
++    alphaColor.alpha = alphaValue;
++    alphaColor.red = alphaValue;
++    alphaColor.green = alphaValue;
++    alphaColor.blue = alphaValue;
++    XRenderFillRectangle (awt_display, PictOpSrc, xrSrcData.alphaMaskPict, &alphaColor, 0, 0, 1, 1);
+     xrSrcData.alphaMask = xrSrcData.alphaMaskPict;
+   }else {
+     xrSrcData.alphaMask = None;
+@@ -430,7 +390,6 @@
+ }
+ 
+ 
+-	//private static native void XRSetTransform(long xsdo, double m00, double m01, double m02, double m10, double m11, double m12);
+ JNIEXPORT void JNICALL
+ Java_sun_java2d_xr_XRSurfaceData_XRSetTransformNative
+     (JNIEnv *env, jclass xsd, jlong pXSData, jint m00, jint m01, jint m02, jint m10, jint m11, jint m12)
+@@ -498,10 +457,16 @@
+ static void decodeRenderColor(jint pixel, XRenderColor *color)
+ { 
+    /*Extract color values from pixel, premultiply values. TODO: shouldn't this be done at the Java-level?*/
+-    XFixed alpha = (((pixel & 0xFF000000) >> 16) + 255); /*REMIND: We rely on optimizations that this is 0xffff for opaque colors*/
++    XFixed alpha = (((pixel & 0xFF000000) >> 16) + 255);
+     XFixed red =   (((pixel & 0x00FF0000) >> 8)  + 255);
+     XFixed green = (((pixel & 0x0000FF00) >> 0)  + 255);
+     XFixed blue =  (((pixel & 0x000000FF) << 8)  + 255);
++
++    /* Optimizations are based on the fact that alpha is 0xffff,
++     * but XRender maybe also optimizes if alpha==0, so we correct here in that case */
++    if(alpha == 255) {
++      alpha = 0;
++    }
+ 
+     XDouble alphaMult = XFixedToDouble(alpha);
+     color->alpha = alpha;
+@@ -516,4 +481,8 @@
+     color->red =   (((pixel & 0x00FF0000) >> 8)  + 255);
+     color->green = (((pixel & 0x0000FF00) >> 0)  + 255);
+     color->blue =  (((pixel & 0x000000FF) << 8)  + 255);
++
++    if(color->alpha == 255) {
++      color->alpha = 0;
++    }
+ }
+\ No newline at end of file
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRSurfaceData.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Fri Aug 01 22:43:51 2008 +0200
+@@ -3,11 +3,9 @@
+ 
+ #define XDoubleToUShort(f)    ((unsigned short) ((f) * 65535))
+ 
++/* Holds source-parameters*/
+ typedef struct {
+-  Picture src;
+-  jboolean compRequired;
+-  XRenderColor alphaColor;
+-
++  Picture src;            /* Currently used source*/
+   Picture solid;
+   XRenderColor solidColor;
+   Picture texture;
+@@ -15,19 +13,28 @@
+ 
+   jint compRule;
+   jfloat extraAlpha;
+-  Picture alphaMask; //Only !None when eA turned on
++  Picture alphaMaskPict;  /*Reference to the 1x1 alpha Mask*/
++  Picture alphaMask;      /*Alpha-Mask which should be used for composition, either alphaMaskPict or None*/ 
+ 
+-  Picture alphaMaskPict;
+   jboolean gradCacheEnabled;
++  Pixmap gradPixmap;
++  Picture gradPict;
+ } SrcSurfaceData;
+ 
+ extern SrcSurfaceData xrSrcData;
+ extern MaskBuffer *maskBuffer;
++extern XRenderColor color_black;
+ 
++/* Composite using gradient-caching if enabled */ 
+ void XRComposite(Picture mask, Picture dest, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, unsigned int width, unsigned int height);
+ 
++/* Initializes the global source structure*/
++static void initXRSrcData();
++
++/*Decodes non-premultiplied pixel, multiplies it and stores the result in color*/
+ static void decodeRenderColor(jint pixel, XRenderColor *color);
+ 
++/*Decodes a pixel and stores the result in color*/
+ static void decodeRenderColorPre(jint pixel, XRenderColor *color);
+ 
+ #endif //XRSurfaceData_h_Included
+diff -r 6d294fa2bd42 -r 4b11af86e814 src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c	Sat Jul 26 00:13:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRTextRenderer_md.c	Fri Aug 01 22:43:51 2008 +0200
+@@ -44,7 +44,6 @@
+ #define TEXT_BM_WIDTH   1024
+ #define TEXT_BM_HEIGHT  32
+ 
+-
+ #define FLOOR_ASSIGN(l, r)\
+  if ((r)<0) (l) = ((int)floor(r)); else (l) = ((int)(r))
+ 
+@@ -84,8 +83,19 @@
+   }
+ 
+    int eltCnt = -1;
+-   jint ids[numGlyphs]; 
+-   XGlyphElt32 elts[numGlyphs];
++   jint *ids; 
++   XGlyphElt32 *elts;
++
++   /*for less then 128 glyphs we allocate temorary mem on stack*/
++   jint idArray[128];
++   XGlyphElt32 eltArray[128];
++   if(numGlyphs <= 128) {
++     ids = &idArray[0];
++     elts = &eltArray[0];
++   }else {
++     ids = (jint *) malloc(numGlyphs * sizeof(jint));
++     elts = (XGlyphElt32 *) malloc(numGlyphs * sizeof(XGlyphElt32));
++   }
+ 
+    float advX = xOrigin; //xOrigin;/*Contains all advance-corrections summed up*/
+    float advY = yOrigin; //yOrigin; 
+@@ -100,7 +110,7 @@
+   }
+ 
+    XRGlyphCacheInfo *glyphCache = (grayscale == JNI_TRUE) ?  grayCache : lcdCache;
+-   jboolean cacheResult = XRGlyphCache_CacheGlyphs(glyphCache, images, numGlyphs, &ids[0]);
++   jboolean cacheResult = XRGlyphCache_CacheGlyphs(glyphCache, images, numGlyphs, ids);
+    if(cacheResult == JNI_FALSE){
+       J2dTraceLn(J2D_TRACE_INFO, "XRTextRenderer_md: Glyph caching failed");
+       return;
+@@ -116,7 +126,6 @@
+ 	 *  If it does not match the positioning information stored on the server, create a new ELT.
+ 	 *  advX/Y and posX/Y contain all advance-corrections summed up, so that we don't forget rounding errors happend in the past.
+          *  The actual advance is computed from the difference to the last integer-correction-position.
+-         *  TODO: Spaeter mit cache vergleichen, statt einfach mit X-Werten
+ 	 */
+ 	int posX = 0, posY = 0;
+ 	if(usePositions || (jginfo->advanceX != ((float)cellInfo->xOff) || jginfo->advanceY != ((float)cellInfo->yOff)) || eltCnt == -1) 
+@@ -165,7 +174,12 @@
+    }
+ 
+   /*TODO: Also integrate into MaskBuffer??*/
+-  XRenderCompositeText32(awt_display, PictOpOver, xrSrcData.src, xsdo->xrPic, None, 0, 0, 0, 0, &elts[0], eltCnt+1);
++  XRenderCompositeText32(awt_display, PictOpOver, xrSrcData.src, xsdo->xrPic, None, 0, 0, 0, 0, elts, eltCnt+1);
++
++  if(numGlyphs > 128) {
++    free(ids);
++    free(elts);
++  }
+ #endif
+ }
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-003.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,78 @@
+# HG changeset patch
+# User ceisserer
+# Date 1217704459 -7200
+# Node ID f757686901c7e70f76bfa4860ea2e0c16d7e7252
+# Parent  4b11af86e814b7d62e9e1e19788d527987bb209c
+Summary: Added some missing mappings which caused failures in non-fastdebug mode
+
+diff -r 4b11af86e814 -r f757686901c7 make/sun/awt/mapfile-mawt-vers
+--- openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Fri Aug 01 22:43:51 2008 +0200
++++ openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Sat Aug 02 21:14:19 2008 +0200
+@@ -417,6 +417,36 @@
+                 Java_sun_java2d_x11_X11SurfaceData_XSetForeground;
+                 Java_sun_java2d_x11_X11SurfaceData_XSetGraphicsExposures;
+ 
++
++		Java_sun_java2d_xr_XRSurfaceData_flushNativeSurface;
++		Java_sun_java2d_xr_XRSurfaceData_XRIsDrawableValid;
++		Java_sun_java2d_xr_XRSurfaceData_setInvalid;
++		Java_sun_java2d_xr_XRSurfaceData_XRInitXRender;
++		Java_sun_java2d_xr_XRSurfaceData_initOps;
++		Java_sun_java2d_xr_XRSurfaceData_XRSetForeground;
++		Java_sun_java2d_xr_XRSurfaceData_XRSetComposite;
++		Java_sun_java2d_xr_XRSurfaceData_initIDs;
++		Java_sun_java2d_xr_XRSurfaceData_XRInitSurface;
++		Java_sun_java2d_xr_XRSurfaceData_XRResetClip;
++		Java_sun_java2d_xr_XRSurfaceData_XRSetClip;
++		Java_sun_java2d_xr_XRSurfaceData_XRSetTransformNative;
++		Java_sun_java2d_xr_XRSurfaceData_XRSetFilter;
++		Java_sun_java2d_xr_XRSurfaceData_XRSetTexturePaint;
++		Java_sun_java2d_xr_XRSurfaceData_XRSetGradientPaint;
++		Java_sun_java2d_xr_XRSurfaceData_XRSetLinearGradientPaint;
++		Java_sun_java2d_xr_XRSurfaceData_XRSetRadialGradientPaint;
++		Java_sun_java2d_xr_XRSurfaceData_XRResetPaint;
++		Java_sun_java2d_xr_XRSurfaceData_XRSetRepeat;
++		Java_sun_java2d_xr_XRPMBlitLoops_nativeRenderBlit;
++		Java_sun_java2d_xr_XRRenderer_XRFillRect;
++		Java_sun_java2d_xr_XRRenderer_XRFillSpans;
++		Java_sun_java2d_xr_XRRenderer_XRDoPath;
++		Java_sun_java2d_xr_XRRenderer_XRDrawLine;
++        	Java_sun_java2d_xr_XRRenderer_devCopyArea;
++		Java_sun_java2d_xr_XRMaskFill_maskFill;
++		Java_sun_java2d_xr_XRMaskBlit_maskBlit;
++		XRT_DrawGlyphList;
++
+                 Java_sun_java2d_opengl_OGLMaskFill_maskFill;
+                 Java_sun_java2d_opengl_OGLRenderer_drawPoly;
+                 Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer;
+diff -r 4b11af86e814 -r f757686901c7 make/sun/headless/mapfile-vers
+--- openjdk/jdk/make/sun/headless/mapfile-vers	Fri Aug 01 22:43:51 2008 +0200
++++ openjdk/jdk/make/sun/headless/mapfile-vers	Sat Aug 02 21:14:19 2008 +0200
+@@ -57,6 +57,8 @@
+                 Java_sun_java2d_x11_X11SurfaceData_XSetXorMode;
+                 Java_sun_java2d_x11_X11SurfaceData_XSetForeground;
+ 
++		XRT_DrawGlyphList;
++
+ 		X11SurfaceData_GetOps;
+ 		Java_java_awt_Font_initIDs;
+                 Java_sun_font_FontManager_getFontConfig;
+diff -r 4b11af86e814 -r f757686901c7 make/sun/xawt/mapfile-vers
+--- openjdk/jdk/make/sun/xawt/mapfile-vers	Fri Aug 01 22:43:51 2008 +0200
++++ openjdk/jdk/make/sun/xawt/mapfile-vers	Sat Aug 02 21:14:19 2008 +0200
+@@ -356,6 +356,7 @@
+         Java_sun_java2d_xr_XRSurfaceData_XRSetComposite;
+         Java_sun_java2d_xr_XRSurfaceData_initIDs;
+         Java_sun_java2d_xr_XRSurfaceData_XRInitSurface;
++	Java_sun_java2d_xr_XRSurfaceData_XRSetClip;
+ 	Java_sun_java2d_xr_XRSurfaceData_XRResetClip;
+ 	Java_sun_java2d_xr_XRSurfaceData_XRSetTransformNative;
+         Java_sun_java2d_xr_XRSurfaceData_XRSetFilter;
+@@ -370,6 +371,7 @@
+ 	Java_sun_java2d_xr_XRRenderer_XRFillSpans;
+         Java_sun_java2d_xr_XRRenderer_XRDoPath;
+ 	Java_sun_java2d_xr_XRRenderer_XRDrawLine;
++        Java_sun_java2d_xr_XRRenderer_devCopyArea;
+         Java_sun_java2d_xr_XRMaskFill_maskFill;
+ 	Java_sun_java2d_xr_XRMaskBlit_maskBlit;
+ 	XRT_DrawGlyphList;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-004.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,86 @@
+# HG changeset patch
+# User ceisserer
+# Date 1217866603 -7200
+# Node ID cf291c1144545d190c719d31a709cf32968ade59
+# Parent  f757686901c7e70f76bfa4860ea2e0c16d7e7252
+Summary: Added some comments
+
+diff -r f757686901c7 -r cf291c114454 make/sun/awt/mapfile-mawt-vers
+--- openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Sat Aug 02 21:14:19 2008 +0200
++++ openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Mon Aug 04 18:16:43 2008 +0200
+@@ -445,7 +445,6 @@
+         	Java_sun_java2d_xr_XRRenderer_devCopyArea;
+ 		Java_sun_java2d_xr_XRMaskFill_maskFill;
+ 		Java_sun_java2d_xr_XRMaskBlit_maskBlit;
+-		XRT_DrawGlyphList;
+ 
+                 Java_sun_java2d_opengl_OGLMaskFill_maskFill;
+                 Java_sun_java2d_opengl_OGLRenderer_drawPoly;
+@@ -541,6 +540,7 @@
+                 AWTCharAscent;
+                 AWTCharDescent;
+                 AWTDrawGlyphList;
++		XRT_DrawGlyphList;
+ 
+ 	local:
+ 		*;
+diff -r f757686901c7 -r cf291c114454 make/sun/awt/mapfile-vers-linux
+--- openjdk/jdk/make/sun/awt/mapfile-vers-linux	Sat Aug 02 21:14:19 2008 +0200
++++ openjdk/jdk/make/sun/awt/mapfile-vers-linux	Mon Aug 04 18:16:43 2008 +0200
+@@ -568,6 +568,7 @@
+                 AWTCharAscent;
+                 AWTCharDescent;
+                 AWTDrawGlyphList;
++		XRT_DrawGlyphList;
+ 
+ 	local:
+ 		*;
+diff -r f757686901c7 -r cf291c114454 make/sun/headless/mapfile-vers
+--- openjdk/jdk/make/sun/headless/mapfile-vers	Sat Aug 02 21:14:19 2008 +0200
++++ openjdk/jdk/make/sun/headless/mapfile-vers	Mon Aug 04 18:16:43 2008 +0200
+@@ -57,8 +57,6 @@
+                 Java_sun_java2d_x11_X11SurfaceData_XSetXorMode;
+                 Java_sun_java2d_x11_X11SurfaceData_XSetForeground;
+ 
+-		XRT_DrawGlyphList;
+-
+ 		X11SurfaceData_GetOps;
+ 		Java_java_awt_Font_initIDs;
+                 Java_sun_font_FontManager_getFontConfig;
+@@ -100,6 +98,7 @@
+                 AWTCharAscent;
+                 AWTCharDescent;
+                 AWTDrawGlyphList;
++		XRT_DrawGlyphList;
+ 
+ 
+ 	local:
+diff -r f757686901c7 -r cf291c114454 src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Sat Aug 02 21:14:19 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Mon Aug 04 18:16:43 2008 +0200
+@@ -67,6 +67,9 @@
+ 
+ 
+ #ifndef HEADLESS
++/**
++ * Prepares a mask-picture according to the mask and the properties currently set, which is used for composition later.
++ */
+ static Picture prepareMaskPM(JNIEnv *env, jbyteArray maskArray, jint maskoff, jint maskscan, jint w, jint h)
+ {
+     int line, pix;
+@@ -107,6 +110,7 @@
+             }
+           }
+ 
++          /*Upload Image to X-Server*/
+           XPutImage(awt_display, maskBuffer->maskPixmap, maskBuffer->maskGC, img, 0, 0, 0, 0, w, h);
+           (*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT);
+ 
+@@ -124,6 +128,7 @@
+         }
+     }else
+     {
++      /*If we haven't got a mask (full coverage), we have to return the EA mask, if EA is used*/
+       if(useEA) {
+         return xrSrcData.alphaMask;
+       }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-005.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,18 @@
+# HG changeset patch
+# User ceisserer
+# Date 1217885774 -7200
+# Node ID 8463c586ceaf12e5bc9d49e916a300c5b2a3ef81
+# Parent  cf291c1144545d190c719d31a709cf32968ade59
+Summary: Fixed Solaris build error
+
+diff -r cf291c114454 -r 8463c586ceaf make/sun/awt/FILES_c_unix.gmk
+--- openjdk/jdk/make/sun/awt/FILES_c_unix.gmk	Mon Aug 04 18:16:43 2008 +0200
++++ openjdk/jdk/make/sun/awt/FILES_c_unix.gmk	Mon Aug 04 23:36:14 2008 +0200
+@@ -212,6 +212,7 @@
+ 	X11SurfaceData.c \
+ 	X11FontScaler_md.c \
+ 	X11TextRenderer_md.c \
++        XRTextRenderer_md.c \
+         OGLBlitLoops.c \
+         OGLBufImgOps.c \
+         OGLContext.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-006.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,295 @@
+# HG changeset patch
+# User ceisserer
+# Date 1217901941 -7200
+# Node ID 2e58d73ce3ffd0301067d097ba443910c387c8d5
+# Parent  8463c586ceaf12e5bc9d49e916a300c5b2a3ef81
+Summary: Added copyright / gpl2 header
+
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/classes/sun/java2d/xr/XRDrawImage.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
+ package sun.java2d.xr;
+ 
+ import java.awt.*;
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/classes/sun/java2d/xr/XRMaskBlit.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskBlit.java	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
+ package sun.java2d.xr;
+ 
+ import static sun.java2d.loops.CompositeType.SrcNoEa;
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/classes/sun/java2d/xr/XRMaskFill.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
+ package sun.java2d.xr;
+ 
+ import static sun.java2d.loops.CompositeType.SrcNoEa;
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/classes/sun/java2d/xr/XRRenderer.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
+ package sun.java2d.xr;
+ 
+ import java.awt.*;
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/classes/sun/java2d/xr/XRUtils.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
+ package sun.java2d.xr;
+ 
+ import static java.awt.AlphaComposite.*;
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/native/sun/java2d/x11/XRGlyphCache.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.c	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
+ #include <malloc.h>
+ #include "jni.h"
+ #include "XRGlyphCache.h"
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/native/sun/java2d/x11/XRGlyphCache.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRGlyphCache.h	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
+ #ifndef XRGlyphCache_h_Included
+ #define XRGlyphCache_h_Included
+ 
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/native/sun/java2d/x11/XRSurfaceData.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
+ #include "GraphicsPrimitiveMgr.h"
+ #include "Region.h"
+ #include "Trace.h"
+diff -r 8463c586ceaf -r 2e58d73ce3ff src/solaris/native/sun/java2d/x11/XRSurfaceData.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Mon Aug 04 23:36:14 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Tue Aug 05 04:05:41 2008 +0200
+@@ -1,3 +1,28 @@
++/*
++ * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.  Sun designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Sun in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
++ * CA 95054 USA or visit www.sun.com if you need additional information or
++ * have any questions.
++ */
++
+ #ifndef XRSurfaceData_h_Included
+ #define XRSurfaceData_h_Included
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-007.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,1143 @@
+# HG changeset patch
+# User ceisserer
+# Date 1224775518 -7200
+# Node ID d6ab5f9f96efa37a823e071a27e3555557930203
+# Parent  2e58d73ce3ffd0301067d097ba443910c387c8d5
+TransformedBlit rewrite
+
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/classes/sun/java2d/xr/XRDrawImage.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRDrawImage.java	Thu Oct 23 17:25:18 2008 +0200
+@@ -42,13 +42,10 @@
+ 	SurfaceData srcData = dstData.getSourceSurfaceData(img,
+ 		SunGraphics2D.TRANSFORM_GENERIC, sg.imageComp, bgColor);
+ 
+-	if (srcData != null && !isBgOperation(srcData, bgColor)
++	if (srcData != null && !isBgOperation(srcData, bgColor) // TODO: Don't bail out on bg-blits
+ 		&& srcData instanceof XRSurfaceData) {
+ 	    SurfaceType srcType = srcData.getSurfaceType();
+ 	    SurfaceType dstType = dstData.getSurfaceType();
+-
+-	    ((XRSurfaceData) srcData).setPreferredInterpolation(XRUtils
+-		    .ATransOpToXRQuality(interpType));
+ 
+ 	    TransformBlit blit = TransformBlit.getFromCache(srcType,
+ 		    sg.imageComp, dstType);
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Thu Oct 23 17:25:18 2008 +0200
+@@ -42,35 +42,25 @@
+     public static void register() {
+ 	GraphicsPrimitive[] primitives = {
+ 
+-		new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),
+-		new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11),
+-		new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11),
+-		new X11PMBlit(XRSurfaceData.IntArgbX11,
+-			XRSurfaceData.IntArgbX11),
++	new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11), new X11PMBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11),
++		new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11), new X11PMBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
+ 
+-		new X11PMScaledBlit(XRSurfaceData.IntRgbX11,
+-			XRSurfaceData.IntRgbX11),
+-		new X11PMScaledBlit(XRSurfaceData.IntRgbX11,
+-			XRSurfaceData.IntArgbX11),
+-		new X11PMScaledBlit(XRSurfaceData.IntArgbX11,
+-			XRSurfaceData.IntRgbX11),
+-		new X11PMScaledBlit(XRSurfaceData.IntArgbX11,
+-			XRSurfaceData.IntArgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11),
++		new X11PMScaledBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11),
+ 
+-		new X11PMTransformedBlit(XRSurfaceData.IntRgbX11,
+-			XRSurfaceData.IntRgbX11),
+-		new X11PMTransformedBlit(XRSurfaceData.IntRgbX11,
+-			XRSurfaceData.IntArgbX11),
+-		new X11PMTransformedBlit(XRSurfaceData.IntArgbX11,
+-			XRSurfaceData.IntRgbX11),
+-		new X11PMTransformedBlit(XRSurfaceData.IntArgbX11,
+-			XRSurfaceData.IntArgbX11),
+-	};
++		new X11PMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntRgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntRgbX11, XRSurfaceData.IntArgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntRgbX11),
++		new X11PMTransformedBlit(XRSurfaceData.IntArgbX11, XRSurfaceData.IntArgbX11), };
+ 	GraphicsPrimitiveMgr.register(primitives);
+     }
+ 
+-    public static native void nativeRenderBlit(long srcData, long dstData,
+-	    int sx, int sy, int dx, int dy, int w, int h);
++    public static native void nativeRenderBlit(long srcData, long dstData, int sx, int sy, int dx, int dy, int w, int h);
++
++    public static native void nativeTransformedRenderBlit(long srcData, long dstData, int sx, int sy, int dx, int dy, int w, int h, int m00, int m01,
++	    int m02, int m10, int m11, int m12, int maskWidth, int maskHeight, int lastMaskWidth, int lastMaskHeight);
+ }
+ 
+ class X11PMBlit extends Blit {
+@@ -78,8 +68,7 @@
+ 	super(srcType, CompositeType.AnyAlpha, dstType);
+     }
+ 
+-    public void Blit(SurfaceData src, SurfaceData dst, Composite comp,
+-	    Region clip, int sx, int sy, int dx, int dy, int w, int h) {
++    public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) {
+ 	try {
+ 	    SunToolkit.awtLock();
+ 
+@@ -89,8 +78,7 @@
+ 
+ 	    x11sdSrc.validateAsSource(null, XRUtils.RepeatNone, XRUtils.FAST);
+ 
+-	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst
+-		    .getNativeOps(), sx, sy, dx, dy, w, h);
++	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), sx, sy, dx, dy, w, h);
+ 	} finally {
+ 	    SunToolkit.awtUnlock();
+ 	}
+@@ -101,10 +89,9 @@
+     public X11PMScaledBlit(SurfaceType srcType, SurfaceType dstType) {
+ 	super(srcType, CompositeType.AnyAlpha, dstType);
+     }
+-
+-    public void Scale(SurfaceData src, SurfaceData dst, Composite comp,
+-	    Region clip, int sx1, int sy1, int sx2, int sy2, double dx1,
+-	    double dy1, double dx2, double dy2) {
++    
++    public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1,
++	    double dx2, double dy2) {
+ 	try {
+ 	    SunToolkit.awtLock();
+ 
+@@ -120,14 +107,13 @@
+ 	    sy1 *= yScale;
+ 	    sy2 *= yScale;
+ 
+-	    AffineTransform xForm = AffineTransform.getScaleInstance(
+-		    1 / xScale, 1 / yScale);
++	    AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale);
+ 
+ 	    x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST);
+ 
+-	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst
+-		    .getNativeOps(), (int) sx1, (int) sy1, (int) dx1,
+-		    (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));
++	    /*TODO: This breaks non-integer scaled images*/
++	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1),
++		    (int) (dy2 - dy1));
+ 
+ 	} finally {
+ 	    SunToolkit.awtUnlock();
+@@ -145,59 +131,90 @@
+ 	super(srcType, CompositeType.AnyAlpha, dstType);
+     }
+ 
+-    public void Transform(SurfaceData src, SurfaceData dst, Composite comp,
+-	    Region clip, AffineTransform xform, int hint, int srcx, int srcy,
++    static int lastMaskWidth = 0, lastMaskHeight = 0;
++
++    /**
++     * Possible optimizations: 
++     * - Nearest interpolation -> ExtraAlpha mit 1x1 maske durchführen
++     * - Mehere Maskengroessen anlegen, und skalieren
++     * - Ueberpruefen ob aktueller Maskeninhalt mit skalierung passen wuerde, bzw. nur so viel aendern bis passt (wenn bereich < maske)
++     * - Aendering entweder mit 2 filLRects, oder nur 1 fillrect je nach groesse
++     */
++    
++    public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy,
+ 	    int dstx, int dsty, int width, int height) {
+ 	try {
+ 	    SunToolkit.awtLock();
++
++	    int xrInterpolationType = XRUtils.ATransOpToXRQuality(hint);
+ 
+ 	    XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+ 	    x11sdDst.validate(clip, comp, null, null, null, 0);
+ 	    XRSurfaceData x11sdSrc = (XRSurfaceData) src;
+ 
+-	    boolean needClip = (xform.getScaleX() != 0.0f)
+-		    || (xform.getShearY() != 0.0f);
++	    Rectangle2D.Float rect = new Rectangle2D.Float(dstx, dsty, width, height);
++	    Shape shp = xform.createTransformedShape(rect);
++	    Rectangle bounds = shp.getBounds();
++
++	    AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y));
++	    trx.concatenate(xform);
++	    AffineTransform maskTX = (AffineTransform) trx.clone();
++
++	    trx.translate(-srcx, -srcy);
++
+ 	    try {
+-		/* Calculate area which will be covered by the transform-blit */
+-		Rectangle2D.Float rect = new Rectangle2D.Float(dstx, dsty,
+-			width, height);
+-		Shape shp = xform.createTransformedShape(rect);
+-		Rectangle bounds = shp.getBounds();
++		trx.invert();
++	    } catch (NoninvertibleTransformException ex) {
++		trx.setToIdentity();
++		System.err.println("Reseted to identity!");
++	    }
+ 
+-		AffineTransform sourceTrans = (AffineTransform) xform.clone();
+-		sourceTrans.translate(-srcx, -srcy);
++	    boolean omitMask = isMaskOmittable(trx, comp, xrInterpolationType);
+ 
+-		try
+-		{
+-		     sourceTrans.invert();
+-		}catch(NoninvertibleTransformException ex)
+-		{
+-		    sourceTrans.setToIdentity();
++	    if (!omitMask) {
++		int maskWidth = Math.max(width / 8, 1);
++		int maskHeight = Math.max(height / 8, 1);
++		maskTX.scale(((double) width) / maskWidth, ((double) height) / maskHeight);
++
++		try {
++		    maskTX.invert();
++		} catch (NoninvertibleTransformException ex) {
++		    maskTX.setToIdentity();
++		    System.err.println("Reseted to identity!");
+ 		}
+ 
+-		x11sdSrc.validateAsSource(sourceTrans, XRUtils.RepeatNone);
++		x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, xrInterpolationType);
+ 
+-		if (needClip) {
+-		    x11sdDst.setShapeClip(shp);
+-		}
++		XRPMBlitLoops.nativeTransformedRenderBlit(src.getNativeOps(), dst.getNativeOps(), 0, 0, bounds.x, bounds.y, bounds.width,
++			bounds.height, XRUtils.XDoubleToFixed(maskTX.getScaleX()), XRUtils.XDoubleToFixed(maskTX.getShearX()), XRUtils
++				.XDoubleToFixed(maskTX.getTranslateX()), XRUtils.XDoubleToFixed(maskTX.getShearY()), XRUtils.XDoubleToFixed(maskTX
++				.getScaleY()), XRUtils.XDoubleToFixed(maskTX.getTranslateY()), maskWidth, maskHeight, lastMaskWidth, lastMaskHeight);
+ 
+-		XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst
+-			.getNativeOps(), 0, 0, 0, 0, bounds.x + bounds.width,
+-			bounds.y + bounds.height);// bounds.x, bounds.y,
+-						    // bounds.width,
+-						    // bounds.height);//(int)
+-						    // (maxX - minX), (int)
+-						    // (maxY - minY));
++		lastMaskWidth = maskWidth;
++		lastMaskHeight = maskHeight;
++	    } else {
++		int repeat = xrInterpolationType <= XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
++		x11sdSrc.validateAsSource(trx, repeat, xrInterpolationType);
++		XRPMBlitLoops.nativeTransformedRenderBlit(src.getNativeOps(), dst.getNativeOps(), 0, 0, bounds.x, bounds.y, bounds.width,
++			bounds.height, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0);
++	    }
+ 
+-		if (needClip) {
+-		    x11sdDst.resetShapeClip();
+-		}
+-
+-	    } catch (Exception ex) {
+-		ex.printStackTrace();
+-	    }
+ 	} finally {
+ 	    SunToolkit.awtUnlock();
+ 	}
+     }
++
++    protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int interpolation) {
++	return (interpolation <= XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /*
++												     * If
++												     * translate
++												     * is
++												     * integer only
++												     */
++		&& trx.getTranslateY() == (int) trx.getTranslateY() && (trx.getShearX() == 0 && trx.getShearY() == 0 // Only
++															// "90°"
++															// rotation
++		|| trx.getShearX() == -trx.getShearY())) && ((AlphaComposite) comp).getAlpha() == 1.0f; // No
++													// ExtraAlpha!=1
++    }
+ }
+\ No newline at end of file
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/classes/sun/java2d/xr/XRSurfaceData.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Thu Oct 23 17:25:18 2008 +0200
+@@ -50,8 +50,7 @@
+ 
+     private static native void initIDs(boolean gradCache);
+ 
+-    protected native void XRInitSurface(int depth, int width, int height,
+-	    long drawable, int pictFormat);
++    protected native void XRInitSurface(int depth, int width, int height, long drawable, int pictFormat);
+ 
+     native void XRInitXRender(long xsdo, int pictForm);
+ 
+@@ -110,12 +109,13 @@
+ 	TextPipe textpipe;
+ 	boolean validated = false;
+ 
+-	/* The textpipe for now can't handle TexturePaint when extra-alpha is specified nore XOR mode*/
++	/*
++	 * The textpipe for now can't handle TexturePaint when extra-alpha is
++	 * specified nore XOR mode
++	 */
+ 	if (sg2d.compositeState < SunGraphics2D.COMP_XOR
+-		&& (sg2d.paintState < SunGraphics2D.PAINT_TEXTURE
+-		|| sg2d.composite == null
+-		|| !(sg2d.composite instanceof AlphaComposite)
+-		|| ((AlphaComposite) sg2d.composite).getAlpha() == 1.0f)) {
++		&& (sg2d.paintState < SunGraphics2D.PAINT_TEXTURE || sg2d.composite == null || !(sg2d.composite instanceof AlphaComposite) || ((AlphaComposite) sg2d.composite)
++			.getAlpha() == 1.0f)) {
+ 	    textpipe = xrtextpipe;
+ 	} else {
+ 	    super.validatePipe(sg2d);
+@@ -167,8 +167,8 @@
+     }
+ 
+     /**
+-     * Returns an accalerated MaskFill object if the current paint
+-     *  is supported by the pipeline.
++     * Returns an accalerated MaskFill object if the current paint is supported
++     * by the pipeline.
+      */
+     protected MaskFill getMaskFill(SunGraphics2D sg2d) {
+ 	if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR && !isPaintValid(sg2d)) {
+@@ -178,8 +178,7 @@
+     }
+ 
+     public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
+-	if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR
+-		&& sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
++	if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) {
+ 	    return solidloops;
+ 	}
+ 
+@@ -199,28 +198,24 @@
+     }
+ 
+     /**
+-     * Method for instantiating a Pixmap SurfaceData (offscreen).
+-     * If the surface is opaque a 24-bit/RGB surface is chosen, 
+-     * otherwise a 32-bit ARGB surface.
++     * Method for instantiating a Pixmap SurfaceData (offscreen). If the surface
++     * is opaque a 24-bit/RGB surface is chosen, otherwise a 32-bit ARGB
++     * surface.
+      */
+-    public static XRPixmapSurfaceData createData(XRGraphicsConfig gc,
+-	    int width, int height, ColorModel cm, Image image, long drawable,
++    public static XRPixmapSurfaceData createData(XRGraphicsConfig gc, int width, int height, ColorModel cm, Image image, long drawable,
+ 	    int transparency) {
+ 	int depth = transparency > Transparency.OPAQUE ? 32 : 24;
+ 	if (depth == 24) {
+ 	    cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00, 0x000000FF);
+ 	} else {
+-	    cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00,
+-		    0x000000FF, 0xFF000000);
++	    cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+ 	}
+ 
+-	return new XRPixmapSurfaceData(gc, width, height, image,
+-		getSurfaceType(gc, transparency), cm, drawable, transparency,
+-		XRUtils.getPictureFormatForTransparency(transparency), depth);
++	return new XRPixmapSurfaceData(gc, width, height, image, getSurfaceType(gc, transparency), cm, drawable, transparency, XRUtils
++		.getPictureFormatForTransparency(transparency), depth);
+     }
+ 
+-    protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc,
+-	    SurfaceType sType, ColorModel cm, int depth, int transparency) {
++    protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, SurfaceType sType, ColorModel cm, int depth, int transparency) {
+ 	super(sType, cm);
+ 	this.peer = peer;
+ 	this.graphicsConfig = gc;
+@@ -233,6 +228,7 @@
+ 
+     /**
+      * Inits the XRender-data-structures which belong to the XRSurfaceData.
++     * 
+      * @param pictureFormat
+      */
+     public void initXRender(int pictureFormat) {
+@@ -248,8 +244,7 @@
+ 	if (peer != null) {
+ 	    return (XRGraphicsConfig) peer.getGraphicsConfiguration();
+ 	} else {
+-	    GraphicsEnvironment env = GraphicsEnvironment
+-		    .getLocalGraphicsEnvironment();
++	    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ 	    GraphicsDevice gd = env.getDefaultScreenDevice();
+ 	    return (XRGraphicsConfig) gd.getDefaultConfiguration();
+ 	}
+@@ -269,16 +264,14 @@
+     public abstract boolean canSourceSendExposures(int x, int y, int w, int h);
+ 
+     /**
+-     * CopyArea is implemented using the "old" X11 GC, 
+-     * therefor clip and needExposures have to be validated against that GC.
+-     * Pictures and GCs don't share state.
++     * CopyArea is implemented using the "old" X11 GC, therefor clip and
++     * needExposures have to be validated against that GC. Pictures and GCs
++     * don't share state.
+      */
+     public void validateCopyAreaGC(Region gcClip, boolean needExposures) {
+ 	if (validatedGCClip != gcClip) {
+ 	    if (gcClip != null) {
+-		XSetClip(xgc, gcClip.getLoX(), gcClip.getLoY(),
+-			gcClip.getHiX(), gcClip.getHiY(), 
+-			gcClip.isRectangular() ? null : gcClip);
++		XSetClip(xgc, gcClip.getLoX(), gcClip.getLoY(), gcClip.getHiX(), gcClip.getHiY(), gcClip.isRectangular() ? null : gcClip);
+ 	    } else {
+ 		XResetClip(xgc);
+ 	    }
+@@ -291,8 +284,7 @@
+ 	}
+     }
+ 
+-    public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
+-	    int dx, int dy) {
++    public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) {
+ 	if (xrpipe == null) {
+ 	    if (!isXRDrawableValid()) {
+ 		return true;
+@@ -301,16 +293,14 @@
+ 	}
+ 	CompositeType comptype = sg2d.imageComp;
+ 	if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE
+-		&& (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa
+-			.equals(comptype))) {
++		&& (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa.equals(comptype))) {
+ 	    x += sg2d.transX;
+ 	    y += sg2d.transY;
+ 	    try {
+ 		SunToolkit.awtLock();
+ 		boolean needExposures = canSourceSendExposures(x, y, w, h);
+ 		validateCopyAreaGC(sg2d.getCompClip(), needExposures);
+-		xrpipe.devCopyArea(getNativeOps(), xgc, x, y, x + dx, y + dy,
+-			w, h);
++		xrpipe.devCopyArea(getNativeOps(), xgc, x, y, x + dx, y + dy, w, h);
+ 	    } finally {
+ 		SunToolkit.awtUnlock();
+ 	    }
+@@ -320,11 +310,10 @@
+     }
+ 
+     /**
+-     * Returns the XRender SurfaceType which is able to fullfill the
+-     * specified transparency requirement.
++     * Returns the XRender SurfaceType which is able to fullfill the specified
++     * transparency requirement.
+      */
+-    public static SurfaceType getSurfaceType(XRGraphicsConfig gc,
+-	    int transparency) {
++    public static SurfaceType getSurfaceType(XRGraphicsConfig gc, int transparency) {
+ 	SurfaceType sType = null;
+ 
+ 	switch (transparency) {
+@@ -355,45 +344,35 @@
+ 
+     private static native void XRSetComposite(int compRule, float eAlpha);
+ 
+-    private static native void XRSetClip(long xsdo, int lox, int loy, int hix,
+-	    int hiy, Region complexclip);
++    private static native void XRSetClip(long xsdo, int lox, int loy, int hix, int hiy, Region complexclip);
+ 
+     private static native void XRResetClip(long xsdo);
+ 
+-    private static native void XRSetTransformNative(long xsdo, int m00,
+-	    int m01, int m02, int m10, int m11, int m12);
++    private static native void XRSetTransformNative(long xsdo, int m00, int m01, int m02, int m10, int m11, int m12);
+ 
+     private static native void XRSetTexturePaint(long xsdo);
+ 
+     private static native void XRResetPaint();
+ 
+     private static native void XRSetRepeat(long xsdo, int repeat);
+-    
++
+     private static native void XRSetFilter(long xsdo, int value);
+-    
+-    private static native void XRSetLinearGradientPaint(float[] fractions,
+-	    int[] pixels, int x1, int y1, int x2, int y2, int numStops,
+-	    int cycleMethod, boolean useMask, boolean linear, int m00, int m01,
+-	    int m02, int m10, int m11, int m12);
+-    
+-    private native static void XRSetRadialGradientPaint(float[] fractions,
+-	    int[] pixels, int fx, int numStops, int cycleMethod,
+-	    boolean useMask, boolean linear, int innerRadius, int outerRadius,
+-	    int m00, int m01, int m02, int m10, int m11, int m12);
++
++    private static native void XRSetLinearGradientPaint(float[] fractions, int[] pixels, int x1, int y1, int x2, int y2, int numStops,
++	    int cycleMethod, boolean useMask, boolean linear, int m00, int m01, int m02, int m10, int m11, int m12);
++
++    private native static void XRSetRadialGradientPaint(float[] fractions, int[] pixels, int fx, int numStops, int cycleMethod, boolean useMask,
++	    boolean linear, int innerRadius, int outerRadius, int m00, int m01, int m02, int m10, int m11, int m12);
+ 
+     private void XRSetTransform(AffineTransform transform) {
+ 	double[] transformData = new double[6];
+ 	transform.getMatrix(transformData);
+ 
+-	XRSetTransformNative(getNativeOps(), XDoubleToFixed(transformData[0]),
+-		XDoubleToFixed(transformData[2]),
+-		XDoubleToFixed(transformData[4]),
+-		XDoubleToFixed(transformData[1]),
+-		XDoubleToFixed(transformData[3]),
+-		XDoubleToFixed(transformData[5]));
++	XRSetTransformNative(getNativeOps(), XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]),
++		XDoubleToFixed(transformData[1]), XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
+     }
+ 
+-    private long xgc; //GC is still used for copyArea
++    private long xgc; // GC is still used for copyArea
+ 
+     public static int validatedPixel = -1;
+     public static int validatedPaintState = -1;
+@@ -410,35 +389,37 @@
+     private AffineTransform validatedSourceTransform = new AffineTransform();
+     private int validatedRepeat = XRUtils.RepeatNone;
+     private int validatedInterpolation = -1;
+-    /*Used if API does not allow to pass interpolation value at the level needed*/
++    /*
++     * Used if API does not allow to pass interpolation value at the level
++     * needed
++     */
+     private int preferredInterpolation = -1;
+ 
+     public void setPreferredInterpolation(int interpolation) {
+ 	this.preferredInterpolation = interpolation;
+     }
+-    
+-    
++
+     /*
+-     * For now those shape-clips are used for transformed images,
+-     * because transformed image for now would invalidate a much larger area that they are intended to do.
+-     * However as soon as the transformed-mask approach I am working on turns out
+-     * to work well, those will be dropped.
++     * For now those shape-clips are used for transformed images, because
++     * transformed image for now would invalidate a much larger area that they
++     * are intended to do. However as soon as the transformed-mask approach I am
++     * working on turns out to work well, those will be dropped.
+      */
+     public void setShapeClip(Shape shape) {
+ 	Region shapeClip = Region.getInstance(validatedClip, shape, null);
+-	XRSetClip(getNativeOps(), shapeClip.getLoX(), shapeClip.getLoY(),
+-		shapeClip.getHiX(), shapeClip.getHiY(), shapeClip
+-			.isRectangular() ? null : shapeClip);
++	XRSetClip(getNativeOps(), shapeClip.getLoX(), shapeClip.getLoY(), shapeClip.getHiX(), shapeClip.getHiY(), shapeClip.isRectangular() ? null
++		: shapeClip);
+     }
+ 
+     public void resetShapeClip() {
+-	XRSetClip(getNativeOps(), validatedClip.getLoX(), validatedClip
+-		.getLoY(), validatedClip.getHiX(), validatedClip.getHiY(),
+-		validatedClip.isRectangular() ? null : validatedClip);
++	XRSetClip(getNativeOps(), validatedClip.getLoX(), validatedClip.getLoY(), validatedClip.getHiX(), validatedClip.getHiY(), validatedClip
++		.isRectangular() ? null : validatedClip);
+     }
+ 
+     /**
+-     * Validate the source with the preferred interpolation set sometimes earlier.
++     * Validate the source with the preferred interpolation set sometimes
++     * earlier.
++     * 
+      * @param sxForm
+      * @param repeat
+      */
+@@ -447,35 +428,40 @@
+     }
+ 
+     /**
+-     * Validates an XRSurfaceData when used as source.
+-     * Note that the clip is applied when used as source as well as destination.
++     * Validates an XRSurfaceData when used as source. Note that the clip is
++     * applied when used as source as well as destination.
+      */
+     void validateAsSource(AffineTransform sxForm, int repeat, int interpolation) {
++	// System.out.println("Source:
++	// "+getBounds().width+"/"+getBounds().height);
++
+ 	if (validatedClip != null) {
+ 	    validatedClip = null;
+ 	    XRResetClip(getNativeOps());
++	    // System.out.println("Clip ge-reseted");
+ 	}
+ 
+ 	if (validatedRepeat != repeat) {
+ 	    validatedRepeat = repeat;
+ 	    XRSetRepeat(getNativeOps(), repeat);
++	    // System.out.println("Repeat ge-reseted");
+ 	}
+ 
+ 	if (sxForm == null) {
+ 	    if (transformInUse) {
+ 		validatedSourceTransform.setToIdentity();
++		// System.out.println("Transform ge-reseted");
+ 		XRSetTransform(validatedSourceTransform);
+ 		transformInUse = false;
+ 	    }
+ 	} else {
+-	    if (!transformInUse
+-		 || (transformInUse && !sxForm.equals(validatedSourceTransform))) {
+-		
+-		validatedSourceTransform.setTransform(sxForm.getScaleX(),
+-			sxForm.getShearY(), sxForm.getShearX(), sxForm
+-				.getScaleY(), sxForm.getTranslateX(), sxForm
+-				.getTranslateY());
+-		
++	    if (!transformInUse || (transformInUse && !sxForm.equals(validatedSourceTransform))) {
++
++		// System.out.println("Setze transform: "+sxForm);
++
++		validatedSourceTransform.setTransform(sxForm.getScaleX(), sxForm.getShearY(), sxForm.getShearX(), sxForm.getScaleY(), sxForm
++			.getTranslateX(), sxForm.getTranslateY());
++
+ 		XRSetTransform(validatedSourceTransform);
+ 		transformInUse = true;
+ 	    }
+@@ -488,8 +474,9 @@
+     }
+ 
+     /**
+-     * Utility method for setting the Composite,
+-     * passing down the arguments to the native method.
++     * Utility method for setting the Composite, passing down the arguments to
++     * the native method.
++     * 
+      * @param comp
+      */
+     private void setComposite(Composite comp) {
+@@ -497,12 +484,9 @@
+ 	    AlphaComposite aComp = (AlphaComposite) comp;
+ 	    validatedExtraAlpha = aComp.getAlpha();
+ 
+-	    XRSetComposite(XRUtils.j2dAlphaCompToXR(aComp.getRule()),
+-		    validatedExtraAlpha);
++	    XRSetComposite(XRUtils.j2dAlphaCompToXR(aComp.getRule()), validatedExtraAlpha);
+ 	} else {
+-	    throw new InternalError(
+-		    "Composite accaleration not implemented for: "
+-			    + comp.getClass().getName());
++	    throw new InternalError("Composite accaleration not implemented for: " + comp.getClass().getName());
+ 	}
+     }
+ 
+@@ -537,10 +521,10 @@
+ 
+ 	return ((a << 24) | (r << 16) | (g << 8) | (b));
+     }
+-    
++
+     /**
+-     * The currently only known paint XRender can't support are
+-     * radial gradients where focus and center paint differ.
++     * The currently only known paint XRender can't support are radial gradients
++     * where focus and center paint differ.
+      */
+     public static boolean isPaintValid(SunGraphics2D sg2d) {
+ 	if (sg2d.paintState == SunGraphics2D.PAINT_RAD_GRADIENT) {
+@@ -551,14 +535,11 @@
+     }
+ 
+     /**
+-     * Sets a 2-stop gradient.
+-     * Utility method generating the by the native method expected
+-     * parameters and calling it.
++     * Sets a 2-stop gradient. Utility method generating the by the native
++     * method expected parameters and calling it.
+      */
+-    private void setGradientPaint(SunGraphics2D sg2d, GradientPaint paint,
+-	    boolean useMask) {
+-	int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(),
+-		paint.getColor2() }, false);
++    private void setGradientPaint(SunGraphics2D sg2d, GradientPaint paint, boolean useMask) {
++	int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(), paint.getColor2() }, false);
+ 
+ 	float fractions[] = new float[2];
+ 	fractions[0] = 0;
+@@ -577,27 +558,19 @@
+ 	double[] transformData = new double[6];
+ 	at.getMatrix(transformData);
+ 
+-	int repeat = paint.isCyclic() ? XRUtils.RepeatReflect
+-		: XRUtils.RepeatPad;
++	int repeat = paint.isCyclic() ? XRUtils.RepeatReflect : XRUtils.RepeatPad;
+ 
+-	XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()),
+-		XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()),
+-		XDoubleToFixed(pt2.getY()), 2, repeat, useMask, false,
+-		XDoubleToFixed(transformData[0]),
+-		XDoubleToFixed(transformData[2]),
+-		XDoubleToFixed(transformData[4]),
+-		XDoubleToFixed(transformData[1]),
+-		XDoubleToFixed(transformData[3]),
++	XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()), XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()),
++		XDoubleToFixed(pt2.getY()), 2, repeat, useMask, false, XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]),
++		XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]), XDoubleToFixed(transformData[3]),
+ 		XDoubleToFixed(transformData[5]));
+     }
+-    
++
+     /**
+-     * Sets a n-stop linear gradient.
+-     * Utility method generating the by the native method expected
+-     * parameters and calling it.
++     * Sets a n-stop linear gradient. Utility method generating the by the
++     * native method expected parameters and calling it.
+      */
+-    public void setLinearGradientPaint(SunGraphics2D sg2d,
+-	    LinearGradientPaint paint, boolean useMask) {
++    public void setLinearGradientPaint(SunGraphics2D sg2d, LinearGradientPaint paint, boolean useMask) {
+ 	boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
+ 	Color[] colors = paint.getColors();
+ 	int numStops = colors.length;
+@@ -607,8 +580,7 @@
+ 	AffineTransform at = paint.getTransform();
+ 	at.preConcatenate(sg2d.transform);
+ 
+-	int cycleMethod = XRUtils.getRepeatForCycleMethod(paint
+-		.getCycleMethod());
++	int cycleMethod = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
+ 	float[] fractions = paint.getFractions();
+ 	int[] pixels = convertToIntArgbPixels(colors, linear);
+ 
+@@ -621,32 +593,24 @@
+ 	double[] transformData = new double[6];
+ 	at.getMatrix(transformData);
+ 
+-	XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()),
+-		XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()),
+-		XDoubleToFixed(pt2.getY()), numStops, cycleMethod, useMask,
+-		linear, XDoubleToFixed(transformData[0]),
+-		XDoubleToFixed(transformData[2]),
+-		XDoubleToFixed(transformData[4]),
+-		XDoubleToFixed(transformData[1]),
+-		XDoubleToFixed(transformData[3]),
+-		XDoubleToFixed(transformData[5]));
++	XRSetLinearGradientPaint(fractions, pixels, XDoubleToFixed(pt1.getX()), XDoubleToFixed(pt1.getY()), XDoubleToFixed(pt2.getX()),
++		XDoubleToFixed(pt2.getY()), numStops, cycleMethod, useMask, linear, XDoubleToFixed(transformData[0]),
++		XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]), XDoubleToFixed(transformData[1]),
++		XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
+     }
+ 
+     /**
+-     * Sets a Radial Gradient where focus and center point match.
+-     * Utility method generating the by the native method expected
+-     * parameters and calling it.
++     * Sets a Radial Gradient where focus and center point match. Utility method
++     * generating the by the native method expected parameters and calling it.
+      */
+-    public void setRadialGradientPaint(SunGraphics2D sg2d,
+-	    RadialGradientPaint paint) {
++    public void setRadialGradientPaint(SunGraphics2D sg2d, RadialGradientPaint paint) {
+ 	boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB);
+ 	Color[] colors = paint.getColors();
+ 	int numStops = colors.length;
+ 	Point2D center = paint.getCenterPoint();
+ 	Point2D focus = paint.getFocusPoint();
+ 
+-	int cycleMethod = XRUtils.getRepeatForCycleMethod(paint
+-		.getCycleMethod());
++	int cycleMethod = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod());
+ 	float[] fractions = paint.getFractions();
+ 	int[] pixels = convertToIntArgbPixels(colors, linear);
+ 	float radius = paint.getRadius();
+@@ -683,28 +647,19 @@
+ 	double[] transformData = new double[6];
+ 	at.getMatrix(transformData);
+ 
+-	XRSetRadialGradientPaint(fractions, pixels, XDoubleToFixed(fx),
+-		numStops, cycleMethod, false, linear, XDoubleToFixed(0),
+-		XDoubleToFixed(radius), XDoubleToFixed(transformData[0]),
+-		XDoubleToFixed(transformData[2]),
+-		XDoubleToFixed(transformData[4]),
+-		XDoubleToFixed(transformData[1]),
+-		XDoubleToFixed(transformData[3]),
+-		XDoubleToFixed(transformData[5]));
++	XRSetRadialGradientPaint(fractions, pixels, XDoubleToFixed(fx), numStops, cycleMethod, false, linear, XDoubleToFixed(0),
++		XDoubleToFixed(radius), XDoubleToFixed(transformData[0]), XDoubleToFixed(transformData[2]), XDoubleToFixed(transformData[4]),
++		XDoubleToFixed(transformData[1]), XDoubleToFixed(transformData[3]), XDoubleToFixed(transformData[5]));
+     }
+ 
+-    private TexturePaint setTexturePaint(SunGraphics2D sg2d,
+-	    TexturePaint paint, boolean useMask) {
++    private TexturePaint setTexturePaint(SunGraphics2D sg2d, TexturePaint paint, boolean useMask) {
+ 	BufferedImage bi = paint.getImage();
+ 	SurfaceData dstData = sg2d.surfaceData;
+-	SurfaceData srcData = dstData.getSourceSurfaceData(bi,
+-		SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
++	SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
+ 
+ 	// REMIND: this hack tries to ensure that we have a cached texture
+ 	if (!(srcData instanceof XRSurfaceData)) {
+-	    srcData = dstData.getSourceSurfaceData(paint.getImage(),
+-		    SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver,
+-		    null);
++	    srcData = dstData.getSourceSurfaceData(paint.getImage(), SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null);
+ 	    if (!(srcData instanceof XRSurfaceData)) {
+ 		return null;
+ 	    }
+@@ -715,17 +670,15 @@
+ 	AffineTransform at = (AffineTransform) sg2d.transform.clone();
+ 	Rectangle2D anchor = paint.getAnchorRect();
+ 	at.translate(anchor.getX(), anchor.getY());
+-	at.scale(anchor.getWidth() / ((double) bi.getWidth()), 
+-		anchor.getHeight() / ((double) bi.getHeight()));
+-	
++	at.scale(anchor.getWidth() / ((double) bi.getWidth()), anchor.getHeight() / ((double) bi.getHeight()));
++
+ 	try {
+ 	    at.invert();
+ 	} catch (NoninvertibleTransformException ex) {
+ 	    at.setToIdentity(); /* TODO: Right thing to do in this case? */
+ 	}
+ 
+-	x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, 
+-		XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
++	x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
+ 
+ 	XRSetTexturePaint(srcData.getNativeOps());
+ 
+@@ -733,8 +686,9 @@
+     }
+ 
+     /**
+-     * Sets the paint as source.
+-     * Checks the type of paint and calls the appropriate set*Paint method.
++     * Sets the paint as source. Checks the type of paint and calls the
++     * appropriate set*Paint method.
++     * 
+      * @param sg2d
+      * @param paint
+      */
+@@ -750,8 +704,7 @@
+ 		    break;
+ 
+ 		case SunGraphics2D.PAINT_LIN_GRADIENT:
+-		    setLinearGradientPaint(sg2d, (LinearGradientPaint) paint,
+-			    false);
++		    setLinearGradientPaint(sg2d, (LinearGradientPaint) paint, false);
+ 		    validatedPaint = paint;
+ 		    break;
+ 
+@@ -761,8 +714,7 @@
+ 		    break;
+ 
+ 		case SunGraphics2D.PAINT_TEXTURE:
+-		    validatedPaint = setTexturePaint(sg2d,
+-			    (TexturePaint) paint, false);
++		    validatedPaint = setTexturePaint(sg2d, (TexturePaint) paint, false);
+ 		    break;
+ 
+ 		default:
+@@ -773,12 +725,10 @@
+     }
+ 
+     /**
+-     * Validates the Surface when used as destination, 
+-     * takes care that the native surface has the same state as expected, 
+-     * changing it it not.
++     * Validates the Surface when used as destination, takes care that the
++     * native surface has the same state as expected, changing it it not.
+      */
+-    public void validate(Region clip, Composite comp, AffineTransform xform,
+-	    Paint paint, SunGraphics2D sg2d, int flags) {
++    public void validate(Region clip, Composite comp, AffineTransform xform, Paint paint, SunGraphics2D sg2d, int flags) {
+ 	boolean updateClip = (clip != validatedClip);
+ 	boolean updatePaint = (paint != validatedPaint) || paint == null;
+ 
+@@ -789,8 +739,7 @@
+ 	// validate clip
+ 	if (updateClip) {
+ 	    if (clip != null) {
+-		XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip
+-			.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
++		XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
+ 	    } else {
+ 		XRResetClip(getNativeOps());
+ 	    }
+@@ -830,7 +779,10 @@
+ 	}
+     }
+ 
+-    public void makePipes() { /*TODO: Why was this synchronized, but access not?*/
++    public void makePipes() { /*
++				 * TODO: Why was this synchronized, but access
++				 * not?
++				 */
+ 	if (xrpipe == null) {
+ 	    try {
+ 		SunToolkit.awtLock();
+@@ -847,14 +799,11 @@
+     }
+ 
+     public static class XRWindowSurfaceData extends XRSurfaceData {
+-	public XRWindowSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc,
+-		SurfaceType sType) {
+-	    super(peer, gc, sType, peer.getColorModel(), peer.getColorModel()
+-		    .getPixelSize(), Transparency.OPAQUE);
++	public XRWindowSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, SurfaceType sType) {
++	    super(peer, gc, sType, peer.getColorModel(), peer.getColorModel().getPixelSize(), Transparency.OPAQUE);
+ 
+ 	    if (isXRDrawableValid()) {
+-		initXRender(XRUtils
+-			.getPictureFormatForTransparency(Transparency.OPAQUE));
++		initXRender(XRUtils.getPictureFormatForTransparency(Transparency.OPAQUE));
+ 		makePipes();
+ 	    }
+ 	}
+@@ -888,8 +837,7 @@
+ 	int height;
+ 	int transparency;
+ 
+-	public XRPixmapSurfaceData(XRGraphicsConfig gc, int width, int height,
+-		Image image, SurfaceType sType, ColorModel cm, long drawable,
++	public XRPixmapSurfaceData(XRGraphicsConfig gc, int width, int height, Image image, SurfaceType sType, ColorModel cm, long drawable,
+ 		int transparency, int pictFormat, int depth) {
+ 	    super(null, gc, sType, cm, depth, transparency);
+ 	    this.width = width;
+@@ -900,8 +848,7 @@
+ 	    makePipes();
+ 	}
+ 
+-	public void initSurface(int depth, int width, int height,
+-		long drawable, int pictFormat) {
++	public void initSurface(int depth, int width, int height, long drawable, int pictFormat) {
+ 	    try {
+ 		SunToolkit.awtLock();
+ 		XRInitSurface(depth, width, height, drawable, pictFormat);
+@@ -936,10 +883,11 @@
+ 	public void flush() {
+ 	    /*
+ 	     * We need to invalidate the surface before disposing the native
+-	     * Drawable and Picture. This way if an application tries to render to an
+-	     * already flushed XRSurfaceData, we will notice in the validate()
+-	     * method above that it has been invalidated, and we will avoid
+-	     * using those native resources that have already been disposed.
++	     * Drawable and Picture. This way if an application tries to render
++	     * to an already flushed XRSurfaceData, we will notice in the
++	     * validate() method above that it has been invalidated, and we will
++	     * avoid using those native resources that have already been
++	     * disposed.
+ 	     */
+ 	    invalidate();
+ 	    flushNativeSurface();
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/native/sun/java2d/x11/MaskBuffer.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Thu Oct 23 17:25:18 2008 +0200
+@@ -44,13 +44,36 @@
+ 
+   buffer->maskPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 8);
+   buffer->lineMaskPixmap = XCreatePixmap(awt_display, window, MASK_TILE_SIZE, MASK_TILE_SIZE, 8);
+- 
++
+   XRenderPictureAttributes pict_attr;
+   buffer->maskPicture = XRenderCreatePicture(awt_display, buffer->maskPixmap, fmt, 0, &pict_attr);
+   buffer->lineMaskPicture = XRenderCreatePicture(awt_display, buffer->lineMaskPixmap, fmt, 0, &pict_attr);
+ 
+   XRenderFillRectangle (awt_display, PictOpClear, buffer->maskPicture, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
+   XRenderFillRectangle (awt_display, PictOpClear, buffer->lineMaskPicture, &color_black, 0, 0, MASK_TILE_SIZE, MASK_TILE_SIZE);
++
++/*
++  //1x1 image mask pixmap
++  Pixmap m1p =  XCreatePixmap(awt_display, window, 1, 1, 8);
++  buffer->img1Mask = XRenderCreatePicture(awt_display, m1p, fmt, 0, &pict_attr);
++  XRenderFillRectangle (awt_display, PictOpSrc, buffer->img1Mask, &color_black, 0, 0, 1, 1);
++
++  //8x8 image mask pixmap
++  Pixmap m8p =  XCreatePixmap(awt_display, window, 8, 8, 8);
++  buffer->img8Mask = XRenderCreatePicture(awt_display, m8p, fmt, 0, &pict_attr);
++  XRenderFillRectangle (awt_display, PictOpSrc, buffer->img8Mask, &color_black, 0, 0, 8, 8);
++
++  //64x64 image mask pixmap
++  Pixmap m64p =  XCreatePixmap(awt_display, window, 64, 64, 8);
++  buffer->img64Mask = XRenderCreatePicture(awt_display, m64p, fmt, 0, &pict_attr);
++  XRenderFillRectangle (awt_display, PictOpSrc, buffer->img64Mask, &color_black, 0, 0, 64, 64);
++*/
++
++  Pixmap mp =  XCreatePixmap(awt_display, window, 64, 64, 8);
++  buffer->maxMask = XRenderCreatePicture(awt_display, mp, fmt, 0, &pict_attr);
++  XRenderFillRectangle (awt_display, PictOpClear, buffer->maxMask, &color_black, 0, 0, 64, 64);
++  buffer->maxWidth = 64;
++  buffer->maxHeight = 64;
+ 
+   buffer->validatedGCAlpha = 1.0f;
+   XGCValues values;
+@@ -347,12 +370,12 @@
+ 	  if(maskRequired || lineList->used  > 0) {
+             Picture mask = None;
+ 
+-            if(lineList->used != 0) {
++            if(lineList->used > 0) {
+               XDrawSegments(awt_display, buf->lineMaskPixmap, buf->drawLineGC, (XSegment *) lineList->elements, lineList->used);
+               mask = buf->lineMaskPicture;
+             }
+ 
+-            if(rectList->used != 0) {
++            if(rectList->used > 0) {
+                XRenderComposite (awt_display, PictOpSrc, buf->lineMaskPicture, None, buf->maskPicture, tile->dirtyLineArea.x, tile->dirtyLineArea.y, 0, 0, tile->dirtyLineArea.x, tile->dirtyLineArea.y, (tile->dirtyLineArea.x2 - tile->dirtyLineArea.x), (tile->dirtyLineArea.y2 - tile->dirtyLineArea.y)); 
+                XRenderFillRectangles (awt_display, PictOpSrc, buf->maskPicture, &maskColor, (XRectangle*) rectList->elements, rectList->used);
+                mask = buf->maskPicture;
+@@ -371,7 +394,7 @@
+                clearXRList(lineList);
+ 	     }
+           }else
+-          if(rectList->used != 0) {
++          if(rectList->used > 0) {
+              translateRects(rectList, (tileStartX + buf->region.x), (tileStartY + buf->region.y));
+              XRenderFillRectangles (awt_display, xrSrcData.compRule, dest, &xrSrcData.solidColor, (XRectangle*) rectList->elements, rectList->used);
+              clearXRList(rectList);
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/native/sun/java2d/x11/MaskBuffer.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.h	Thu Oct 23 17:25:18 2008 +0200
+@@ -50,6 +50,13 @@
+   Picture maskPicture;
+   GC maskGC;
+   jfloat validatedGCAlpha;
++
++  /*Picture img1Mask;
++  Picture img8Mask;
++  Picture img64Mask;*/
++  Picture maxMask;
++  jint maxWidth;
++  jint maxHeight;
+ 
+   XrArrayList rects;
+   XrArrayList lines;
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRPMBlitLoops.c	Thu Oct 23 17:25:18 2008 +0200
+@@ -65,6 +65,92 @@
+ #endif /* !HEADLESS */
+ }
+ 
++
++JNIEXPORT void JNICALL
++Java_sun_java2d_xr_XRPMBlitLoops_nativeTransformedRenderBlit
++    (JNIEnv *env, jclass xsd,
++     jlong srcData, jlong dstData,
++     jint srcx, jint srcy,
++     jint dstx, jint dsty,
++     jint width, jint height,
++     jint m00, jint m01, jint m02, jint m10, jint m11, jint m12, jint maskWidth, jint maskHeight, jint lastWidth, jint lastHeight)
++{
++#ifndef HEADLESS
++    J2dTraceLn(J2D_TRACE_INFO, "in XRPBMBlitLoops_nativeTranformedRenderBlit");
++
++    X11SDOps *srcXsdo, *dstXsdo;
++    SurfaceDataBounds span, srcBounds;
++
++    if (width <= 0 || height <= 0) {
++        return;
++    }
++
++    srcXsdo = (X11SDOps *)jlong_to_ptr(srcData);
++    if (srcXsdo == NULL) {
++        return;
++    }
++    dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
++    if (dstXsdo == NULL) {
++        return;
++    }
++
++
++    Picture mask = None;
++    if(maskWidth > -1)
++    {
++      XRenderColor maskColor;
++      maskColor.alpha = XDoubleToUShort(xrSrcData.extraAlpha);
++
++    /*Picture mask;
++    switch(maskSize)
++    {
++      case 1: 
++        mask = maskBuffer->img1Mask;
++        break;
++
++      case 8:
++        mask = maskBuffer->img8Mask;
++        break;
++
++      case 64:
++        mask = maskBuffer->img64Mask;
++        break;
++    }*/
++
++   if(maskBuffer->maxWidth < maskWidth || maskBuffer->maxHeight < maskHeight) {
++     XRenderPictFormat *fmt = XRenderFindStandardFormat(awt_display, PictStandardA8);
++     XRenderPictureAttributes pict_attr;
++     Pixmap mp =  XCreatePixmap(awt_display, RootWindow(awt_display, dstXsdo->configData->awt_visInfo.screen), maskWidth, maskHeight, 8);
++
++     //TODO: Alte maske free'n
++     maskBuffer->maxMask = XRenderCreatePicture(awt_display, mp, fmt, 0, &pict_attr);
++     XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->maxMask, &maskColor, 0, 0, maskWidth, maskHeight);
++     maskBuffer->maxWidth = maskWidth;
++     maskBuffer->maxHeight = maskHeight;
++
++  //   printf("Reinitialized it!\n"); fflush(stdout);
++   }else
++   {
++    XRenderFillRectangle (awt_display, PictOpClear, maskBuffer->maxMask, &maskColor, 0, 0, lastWidth, lastHeight);
++   }
++
++    //printf("Blit: %d, %d, %d, %d\n", maskWidth, maskHeight, lastWidth, lastHeight); fflush(stdout);
++
++    XRenderFillRectangle (awt_display, PictOpSrc, maskBuffer->maxMask, &maskColor, 0, 0, maskWidth, maskHeight);
++    
++    XTransform tr;
++    BUILD_TRANSFORM_MATRIX(tr, m00, m01, m02, m10, m11, m12);
++    XRenderSetPictureTransform (awt_display, maskBuffer->maxMask, &tr);
++
++    mask = maskBuffer->maxMask;
++}
++
++    XRenderComposite (awt_display, xrSrcData.compRule, srcXsdo->xrPic, mask, dstXsdo->xrPic, srcx, srcy, 0, 0, dstx, dsty, width, height); 
++    
++
++    X11SD_DirectRenderNotify(env, dstXsdo);
++#endif /* !HEADLESS */
++}
+ 
+ #ifndef HEADLESS
+ /**
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/native/sun/java2d/x11/XRSurfaceData.c
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c	Thu Oct 23 17:25:18 2008 +0200
+@@ -33,19 +33,6 @@
+ MaskBuffer *maskBuffer;
+ XRenderColor color_black;
+ #endif /* !HEADLESS */
+-
+-#define BUILD_TRANSFORM_MATRIX(TRANSFORM, M00, M01, M02, M10, M11, M12)                        \
+-    {                                                                                          \
+-      TRANSFORM.matrix[0][0] = M00;                                                            \
+-      TRANSFORM.matrix[0][1] = M01;                                                            \
+-      TRANSFORM.matrix[0][2] = M02;                                                            \
+-      TRANSFORM.matrix[1][0] = M10;                                                            \
+-      TRANSFORM.matrix[1][1] = M11;                                                            \
+-      TRANSFORM.matrix[1][2] = M12;                                                            \
+-      TRANSFORM.matrix[2][0] = 0;                                                              \
+-      TRANSFORM.matrix[2][1] = 0;                                                              \
+-      TRANSFORM.matrix[2][2] = 1<<16;                                                          \
+-    }
+ 
+ JNIEXPORT void JNICALL
+    Java_sun_java2d_xr_XRSurfaceData_XRInitXRender(JNIEnv *env, jobject xsd, jlong pXSData, jint pictFormat)
+diff -r 2e58d73ce3ff -r d6ab5f9f96ef src/solaris/native/sun/java2d/x11/XRSurfaceData.h
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Tue Aug 05 04:05:41 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.h	Thu Oct 23 17:25:18 2008 +0200
+@@ -27,6 +27,19 @@
+ #define XRSurfaceData_h_Included
+ 
+ #define XDoubleToUShort(f)    ((unsigned short) ((f) * 65535))
++
++#define BUILD_TRANSFORM_MATRIX(TRANSFORM, M00, M01, M02, M10, M11, M12)                        \
++    {                                                                                          \
++      TRANSFORM.matrix[0][0] = M00;                                                            \
++      TRANSFORM.matrix[0][1] = M01;                                                            \
++      TRANSFORM.matrix[0][2] = M02;                                                            \
++      TRANSFORM.matrix[1][0] = M10;                                                            \
++      TRANSFORM.matrix[1][1] = M11;                                                            \
++      TRANSFORM.matrix[1][2] = M12;                                                            \
++      TRANSFORM.matrix[2][0] = 0;                                                              \
++      TRANSFORM.matrix[2][1] = 0;                                                              \
++      TRANSFORM.matrix[2][2] = 1<<16;                                                          \
++    }
+ 
+ /* Holds source-parameters*/
+ typedef struct {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-008.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,131 @@
+# HG changeset patch
+# User ceisserer
+# Date 1224781905 -7200
+# Node ID 0ae86de6889ebd18b1a8f0232c50ce2c3049bc40
+# Parent  d6ab5f9f96efa37a823e071a27e3555557930203
+Updated Symbol-Mapping files
+
+diff -r d6ab5f9f96ef -r 0ae86de6889e make/sun/awt/mapfile-mawt-vers
+--- openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Thu Oct 23 17:25:18 2008 +0200
++++ openjdk/jdk/make/sun/awt/mapfile-mawt-vers	Thu Oct 23 19:11:45 2008 +0200
+@@ -438,6 +438,7 @@
+ 		Java_sun_java2d_xr_XRSurfaceData_XRResetPaint;
+ 		Java_sun_java2d_xr_XRSurfaceData_XRSetRepeat;
+ 		Java_sun_java2d_xr_XRPMBlitLoops_nativeRenderBlit;
++                Java_sun_java2d_xr_XRPMBlitLoops_nativeTransformedRenderBlit;
+ 		Java_sun_java2d_xr_XRRenderer_XRFillRect;
+ 		Java_sun_java2d_xr_XRRenderer_XRFillSpans;
+ 		Java_sun_java2d_xr_XRRenderer_XRDoPath;
+diff -r d6ab5f9f96ef -r 0ae86de6889e make/sun/xawt/mapfile-vers
+--- openjdk/jdk/make/sun/xawt/mapfile-vers	Thu Oct 23 17:25:18 2008 +0200
++++ openjdk/jdk/make/sun/xawt/mapfile-vers	Thu Oct 23 19:11:45 2008 +0200
+@@ -367,6 +367,7 @@
+         Java_sun_java2d_xr_XRSurfaceData_XRResetPaint;
+         Java_sun_java2d_xr_XRSurfaceData_XRSetRepeat;
+ 	Java_sun_java2d_xr_XRPMBlitLoops_nativeRenderBlit;
++        Java_sun_java2d_xr_XRPMBlitLoops_nativeTransformedRenderBlit;
+ 	Java_sun_java2d_xr_XRRenderer_XRFillRect;
+ 	Java_sun_java2d_xr_XRRenderer_XRFillSpans;
+         Java_sun_java2d_xr_XRRenderer_XRDoPath;
+diff -r d6ab5f9f96ef -r 0ae86de6889e src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Thu Oct 23 17:25:18 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Thu Oct 23 19:11:45 2008 +0200
+@@ -31,6 +31,7 @@
+ import sun.java2d.SurfaceData;
+ import java.awt.*;
+ import java.awt.geom.*;
++import java.awt.image.*;
+ 
+ /**
+  * XRPMBlitLoops
+@@ -38,7 +39,7 @@
+  * This class accelerates Blits between two surfaces of types *PM.s
+  */
+ public class XRPMBlitLoops {
+-
++    
+     public static void register() {
+ 	GraphicsPrimitive[] primitives = {
+ 
+@@ -90,15 +91,32 @@
+ 	super(srcType, CompositeType.AnyAlpha, dstType);
+     }
+     
++    /*
++     * TODO:  This breaks scales with non-integer coordinates!
++     */
+     public void Scale(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx1, int sy1, int sx2, int sy2, double dx1, double dy1,
+ 	    double dx2, double dy2) {
+ 	try {
+ 	    SunToolkit.awtLock();
+-
++	    
++//	    int width = sx2-sx1;
++//	    int height = sy2-sy1;
++//	    double xScale = (dx2 - dx1) / width;
++//	    double yScale = (dy2 - dy1) / height;
++//	    AffineTransform scaleTransform = AffineTransform.getTranslateInstance(sx1, sy1);
++//	    scaleTransform.scale(xScale, yScale);
++//	   // scaleTransform.translate(sx1, sy1);
++//	    
++//	    /*
++//             *    static void IsoBlit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, 
++//             *    int srcx, int srcy, int dstx, int dsty, int width, int height)
++//	     */
++//	    XRPMBlitLoops.IsoBlit(src, dst, comp, clip, scaleTransform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 0, 0, (int)(dx1/xScale), (int)(dy1/yScale), width, height);
++////
+ 	    XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+ 	    x11sdDst.validate(clip, comp, null, null, null, 0);
+ 	    XRSurfaceData x11sdSrc = (XRSurfaceData) src;
+-
++	    
+ 	    double xScale = (dx2 - dx1) / (sx2 - sx1);
+ 	    double yScale = (dy2 - dy1) / (sy2 - sy1);
+ 
+@@ -110,8 +128,7 @@
+ 	    AffineTransform xForm = AffineTransform.getScaleInstance(1 / xScale, 1 / yScale);
+ 
+ 	    x11sdSrc.validateAsSource(xForm, XRUtils.RepeatNone, XRUtils.FAST);
+-
+-	    /*TODO: This breaks non-integer scaled images*/
++	    
+ 	    XRPMBlitLoops.nativeRenderBlit(src.getNativeOps(), dst.getNativeOps(), (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1),
+ 		    (int) (dy2 - dy1));
+ 
+@@ -127,11 +144,12 @@
+  * @author Clemens Eisserer
+  */
+ class X11PMTransformedBlit extends TransformBlit {
++    
++    static int lastMaskWidth = 0, lastMaskHeight = 0;
++    
+     public X11PMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
+ 	super(srcType, CompositeType.AnyAlpha, dstType);
+     }
+-
+-    static int lastMaskWidth = 0, lastMaskHeight = 0;
+ 
+     /**
+      * Possible optimizations: 
+@@ -145,7 +163,6 @@
+ 	    int dstx, int dsty, int width, int height) {
+ 	try {
+ 	    SunToolkit.awtLock();
+-
+ 	    int xrInterpolationType = XRUtils.ATransOpToXRQuality(hint);
+ 
+ 	    XRSurfaceData x11sdDst = (XRSurfaceData) dst;
+@@ -198,12 +215,11 @@
+ 		XRPMBlitLoops.nativeTransformedRenderBlit(src.getNativeOps(), dst.getNativeOps(), 0, 0, bounds.x, bounds.y, bounds.width,
+ 			bounds.height, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0);
+ 	    }
+-
+ 	} finally {
+ 	    SunToolkit.awtUnlock();
+ 	}
+     }
+-
++    
+     protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int interpolation) {
+ 	return (interpolation <= XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /*
+ 												     * If
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/icedtea-xrender-009.patch	Tue Dec 02 13:58:24 2008 +0000
@@ -0,0 +1,170 @@
+
+# HG changeset patch
+# User ceisserer
+# Date 1228079698 -3600
+# Node ID c72b1c0435c0b262a78dea6ee7109634a82eb574
+# Parent 0ae86de6889ebd18b1a8f0232c50ce2c3049bc40
+- Improved performance of non-solid operations
+- Improved performance of GPUs not supporting A8+A8 composition, but are capable of XCopyArea'ing with A8->A8 with their 2D engines (i830, GF6/7)
+- X11/XR pipeline initialization in X11GraphicsDevice was mixed up
+
+--- openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Thu Oct 23 19:11:45 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/awt/X11GraphicsDevice.java	Sun Nov 30 22:14:58 2008 +0100
+@@ -151,7 +151,7 @@ public class X11GraphicsDevice
+             }
+ 
+             boolean glxSupported = X11GraphicsEnvironment.isGLXAvailable();
+-            boolean xrender = X11GraphicsEnvironment.isXRenderAvailable();
++            boolean xrenderSupported = X11GraphicsEnvironment.isXRenderAvailable();
+             
+             boolean dbeSupported = isDBESupported();
+             if (dbeSupported && doubleBufferVisuals == null) {
+@@ -169,7 +169,7 @@ public class X11GraphicsDevice
+                         (dbeSupported &&
+                          doubleBufferVisuals.contains(Integer.valueOf(visNum)));
+                     
+-                    if(!xrender)
++                    if(xrenderSupported)
+                     {
+                         ret[i] = XRGraphicsConfig.getConfig(this, visNum, depth,
+                                 getConfigColormap(i, screen),
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Thu Oct 23 19:11:45 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRMaskFill.java	Sun Nov 30 22:14:58 2008 +0100
+@@ -104,6 +104,7 @@ public class XRMaskFill extends MaskFill
+ 
+ 	    maskFill(sData.getNativeOps(), x, y, w, h, maskoff, maskscan,
+ 		    mask != null ? mask.length : 0, mask);
++	
+ 	} finally {
+ 	    SunToolkit.awtUnlock();
+ 	}
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Thu Oct 23 19:11:45 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java	Sun Nov 30 22:14:58 2008 +0100
+@@ -211,6 +211,7 @@ class X11PMTransformedBlit extends Trans
+ 		lastMaskHeight = maskHeight;
+ 	    } else {
+ 		int repeat = xrInterpolationType <= XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
++		
+ 		x11sdSrc.validateAsSource(trx, repeat, xrInterpolationType);
+ 		XRPMBlitLoops.nativeTransformedRenderBlit(src.getNativeOps(), dst.getNativeOps(), 0, 0, bounds.x, bounds.y, bounds.width,
+ 			bounds.height, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0);
+--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Thu Oct 23 19:11:45 2008 +0200
++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java	Sun Nov 30 22:14:58 2008 +0100
+@@ -399,23 +399,6 @@ public abstract class XRSurfaceData exte
+ 	this.preferredInterpolation = interpolation;
+     }
+ 
+-    /*
+-     * For now those shape-clips are used for transformed images, because
+-     * transformed image for now would invalidate a much larger area that they
+-     * are intended to do. However as soon as the transformed-mask approach I am
+-     * working on turns out to work well, those will be dropped.
+-     */
+-    public void setShapeClip(Shape shape) {
+-	Region shapeClip = Region.getInstance(validatedClip, shape, null);
+-	XRSetClip(getNativeOps(), shapeClip.getLoX(), shapeClip.getLoY(), shapeClip.getHiX(), shapeClip.getHiY(), shapeClip.isRectangular() ? null
+-		: shapeClip);
+-    }
+-
+-    public void resetShapeClip() {
+-	XRSetClip(getNativeOps(), validatedClip.getLoX(), validatedClip.getLoY(), validatedClip.getHiX(), validatedClip.getHiY(), validatedClip
+-		.isRectangular() ? null : validatedClip);
+-    }
+-
+     /**
+      * Validate the source with the preferred interpolation set sometimes
+      * earlier.
+@@ -432,32 +415,25 @@ public abstract class XRSurfaceData exte
+      * applied when used as source as well as destination.
+      */
+     void validateAsSource(AffineTransform sxForm, int repeat, int interpolation) {
+-	// System.out.println("Source:
+-	// "+getBounds().width+"/"+getBounds().height);
+ 
+ 	if (validatedClip != null) {
+ 	    validatedClip = null;
+ 	    XRResetClip(getNativeOps());
+-	    // System.out.println("Clip ge-reseted");
+ 	}
+ 
+ 	if (validatedRepeat != repeat) {
+ 	    validatedRepeat = repeat;
+ 	    XRSetRepeat(getNativeOps(), repeat);
+-	    // System.out.println("Repeat ge-reseted");
+ 	}
+ 
+ 	if (sxForm == null) {
+ 	    if (transformInUse) {
+ 		validatedSourceTransform.setToIdentity();
+-		// System.out.println("Transform ge-reseted");
+ 		XRSetTransform(validatedSourceTransform);
+ 		transformInUse = false;
+ 	    }
+ 	} else {
+ 	    if (!transformInUse || (transformInUse && !sxForm.equals(validatedSourceTransform))) {
+-
+-		// System.out.println("Setze transform: "+sxForm);
+ 
+ 		validatedSourceTransform.setTransform(sxForm.getScaleX(), sxForm.getShearY(), sxForm.getShearX(), sxForm.getScaleY(), sxForm
+ 			.getTranslateX(), sxForm.getTranslateY());
+@@ -677,7 +653,7 @@ public abstract class XRSurfaceData exte
+ 	} catch (NoninvertibleTransformException ex) {
+ 	    at.setToIdentity(); /* TODO: Right thing to do in this case? */
+ 	}
+-
++	
+ 	x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType));
+ 
+ 	XRSetTexturePaint(srcData.getNativeOps());
+@@ -739,6 +715,8 @@ public abstract class XRSurfaceData exte
+ 	// validate clip
+ 	if (updateClip) {
+ 	    if (clip != null) {
++		//    System.out.println("Set paint clip: "+getBounds().width+":"+getBounds().height);
++		//    Thread.dumpStack();
+ 		XRSetClip(getNativeOps(), clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY(), clip.isRectangular() ? null : clip);
+ 	    } else {
+ 		XRResetClip(getNativeOps());
+--- openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Thu Oct 23 19:11:45 2008 +0200
++++ openjdk/jdk/src/solaris/native/sun/java2d/x11/MaskBuffer.c	Sun Nov 30 22:14:58 2008 +0100
+@@ -77,12 +77,14 @@ MaskBuffer* initMaskBuffer(Window window
+ 
+   buffer->validatedGCAlpha = 1.0f;
+   XGCValues values;
++  values.graphics_exposures = 0;
++
+   values.foreground = 255;
+-  buffer->drawLineGC = XCreateGC(awt_display, buffer->lineMaskPixmap, GCForeground, &values);
++  buffer->drawLineGC = XCreateGC(awt_display, buffer->lineMaskPixmap, GCForeground | GCGraphicsExposures, &values);
+   /*Invisible GC for readback assistance*/
+   values.foreground = 0;
+-  buffer->clearLineGC = XCreateGC(awt_display, buffer->lineMaskPixmap, GCForeground, &values);
+-  buffer->maskGC = XCreateGC(awt_display, buffer->maskPixmap, 0, &values);
++  buffer->clearLineGC = XCreateGC(awt_display, buffer->lineMaskPixmap, GCForeground | GCGraphicsExposures, &values);
++  buffer->maskGC = XCreateGC(awt_display, buffer->maskPixmap, GCGraphicsExposures, &values);
+  
+   buffer->alphaData = malloc(32*32);
+   buffer->alphaImg = XCreateImage(awt_display, &buffer->maskPixmap, 8, ZPixmap, 0, (char *) buffer->alphaData, 32, 32, 8, 0);
+@@ -376,7 +378,11 @@ void fillMask(MaskBuffer* buf, Picture d
+             }
+ 
+             if(rectList->used > 0) {
+-               XRenderComposite (awt_display, PictOpSrc, buf->lineMaskPicture, None, buf->maskPicture, tile->dirtyLineArea.x, tile->dirtyLineArea.y, 0, 0, tile->dirtyLineArea.x, tile->dirtyLineArea.y, (tile->dirtyLineArea.x2 - tile->dirtyLineArea.x), (tile->dirtyLineArea.y2 - tile->dirtyLineArea.y)); 
++               if(lineList->used > 0) {
++                 XCopyArea(awt_display, buf->lineMaskPixmap, buf->maskPixmap, buf->maskGC, tile->dirtyLineArea.x, tile->dirtyLineArea.y, (tile->dirtyLineArea.x2 - tile->dirtyLineArea.x), (tile->dirtyLineArea.y2 - tile->dirtyLineArea.y), tile->dirtyLineArea.x, tile->dirtyLineArea.y);
++                 //XRenderComposite (awt_display, PictOpSrc, buf->lineMaskPicture, None, buf->maskPicture, tile->dirtyLineArea.x, tile->dirtyLineArea.y, 0, 0, tile->dirtyLineArea.x, tile->dirtyLineArea.y, (tile->dirtyLineArea.x2 - tile->dirtyLineArea.x), (tile->dirtyLineArea.y2 - tile->dirtyLineArea.y)); 
++               }
++
+                XRenderFillRectangles (awt_display, PictOpSrc, buf->maskPicture, &maskColor, (XRectangle*) rectList->elements, rectList->used);
+                mask = buf->maskPicture;
+                clearXRList(rectList);
+@@ -389,7 +395,7 @@ void fillMask(MaskBuffer* buf, Picture d
+ 
+              /* Clear diagonal lines with lines again,
+                 to avoid the sysmem copy marked "dirty" causing migration for the next lines*/
+-             if(lineList->used != 0) {
++             if(lineList->used > 0) {
+                XDrawSegments(awt_display, buf->lineMaskPixmap, buf->clearLineGC, (XSegment *) lineList->elements, lineList->used);
+                clearXRList(lineList);
+ 	     }
+
--- a/plugin/icedtea/netscape/javascript/JSObject.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/plugin/icedtea/netscape/javascript/JSObject.java	Tue Dec 02 13:58:24 2008 +0000
@@ -86,8 +86,7 @@
  */
 public final class JSObject {
     /* the internal object data */
-    private int                               internal;
-    private long                              long_internal;
+    private long                              internal;
 
     /**
      * initialize
@@ -111,7 +110,7 @@
 
     public JSObject(long jsobj_addr) {
         PluginDebug.debug ("JSObject long CONSTRUCTOR");
-        long_internal = jsobj_addr;
+        internal = jsobj_addr;
     }
 
     /**
@@ -231,7 +230,7 @@
     {
         PluginDebug.debug("JSObject.getWindow");
         // FIXME: handle long case as well.
-        int internal = 0;
+        long internal = 0;
         internal = ((PluginAppletViewer)
                     applet.getAppletContext()).getWindow();
         PluginDebug.debug ("GOT IT: " + internal);
--- a/plugin/icedtea/sun/applet/GetWindowPluginCallRequest.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/plugin/icedtea/sun/applet/GetWindowPluginCallRequest.java	Tue Dec 02 13:58:24 2008 +0000
@@ -44,7 +44,7 @@
 
 public class GetWindowPluginCallRequest extends PluginCallRequest {
     // FIXME: look into int vs long JavaScript internal values.
-    int internal;
+    long internal;
 
     public GetWindowPluginCallRequest(String message, String returnString) {
         super(message, returnString);
@@ -55,7 +55,7 @@
         String[] args = message.split(" ");
         // FIXME: add thread ID to messages to support multiple
         // threads using the netscape.javascript package.
-        internal = Integer.parseInt(args[1]);
+        internal = Long.parseLong(args[1]);
         setDone(true);
     }
     
@@ -69,7 +69,7 @@
     	return message.contains("JavaScriptGetWindow");
     }
 
-    public Integer getObject() {
+    public Long getObject() {
     	return this.internal;
     }
 }
--- a/plugin/icedtea/sun/applet/PluginAppletSecurityContext.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/plugin/icedtea/sun/applet/PluginAppletSecurityContext.java	Tue Dec 02 13:58:24 2008 +0000
@@ -996,7 +996,7 @@
 
 		String classSrc = this.classLoaders.get(target.getClassLoader());
 
-		PluginDebug.debug("jsSrc=" + jsSrc + " classSrc=" + classSrc);
+		PluginDebug.debug("target = " + target + " jsSrc=" + jsSrc + " classSrc=" + classSrc);
 		
 		// if src is not a file and class loader does not map to the same base, UniversalBrowserRead (BrowserReadPermission) must be set
 		if (jsSrc != "file://" && !classSrc.equals(jsSrc)) {
--- a/plugin/icedtea/sun/applet/PluginAppletViewer.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/plugin/icedtea/sun/applet/PluginAppletViewer.java	Tue Dec 02 13:58:24 2008 +0000
@@ -63,6 +63,7 @@
 import javax.swing.SwingUtilities;
 
 import net.sourceforge.jnlp.NetxPanel;
+import net.sourceforge.jnlp.runtime.JNLPClassLoader;
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
 import sun.awt.X11.XEmbeddedFrame;
@@ -103,7 +104,7 @@
       * Some constants...
       */
      private static String defaultSaveFile = "Applet.ser";
- 
+     
      /**
       * The panel in which the applet is being displayed.
       */
@@ -168,7 +169,7 @@
         	 proposedHeightFactor = (Integer) atts.get("heightPercentage")/100.0;
          }
          
-         if (((String) atts.get("width")).endsWith("%")) {
+         if (atts.get("widthPercentage") != null) {
         	 proposedWidthFactor = (Integer) atts.get("widthPercentage")/100.0;
          }
  
@@ -177,6 +178,7 @@
             	 	try {
             	 		panel = new NetxPanel(doc, atts, true);
             	 		AppletViewerPanel.debug("Using NetX panel");
+            	 		PluginDebug.debug(atts.toString());
             	 	} catch (Exception ex) {
             	 		AppletViewerPanel.debug("Unable to start NetX applet - defaulting to Sun applet", ex);
             	 		panel = new AppletViewerPanel(doc, atts);
@@ -291,7 +293,7 @@
 
     if (atts.get("codebase") != null) {
     	try {
-    		URL appletSrcURL = new URL((String) atts.get("codebase"));
+    		URL appletSrcURL = new URL(codeBase + (String) atts.get("codebase"));
     		codeBase = appletSrcURL.getProtocol() + "://" + appletSrcURL.getHost();
     	} catch (MalformedURLException mfue) {
     		// do nothing
@@ -587,7 +589,7 @@
  	return getCachedImage(url);
      }
  
-     static Image getCachedImage(URL url) {
+     private Image getCachedImage(URL url) {
  	// System.getSecurityManager().checkConnection(url.getHost(), url.getPort());
  	return (Image)getCachedImageRef(url).get();
      }
@@ -595,15 +597,43 @@
      /**
       * Get an image ref.
       */
-     static Ref getCachedImageRef(URL url) {
- 	synchronized (imageRefs) {
- 	    AppletImageRef ref = (AppletImageRef)imageRefs.get(url);
- 	    if (ref == null) {
- 		ref = new AppletImageRef(url);
- 		imageRefs.put(url, ref);
- 	    }
- 	    return ref;
- 	}
+     private synchronized Ref getCachedImageRef(URL url) {
+         PluginDebug.debug("getCachedImageRef() searching for " + url);
+         
+         try {
+
+             String originalURL = url.toString();
+             String codeBase = panel.getCodeBase().toString();
+
+             if (originalURL.startsWith(codeBase)) {
+
+                 PluginDebug.debug("getCachedImageRef() got URL = " + url);
+                 PluginDebug.debug("getCachedImageRef() plugin codebase = " + codeBase);
+
+                 // try to fetch it locally
+                 if (panel instanceof NetxPanel) {
+                     URL localURL = null;
+                     localURL = ((NetxPanel) panel).getAppletClassLoader().getResource(originalURL.substring(codeBase.length()));
+
+                     url = localURL != null ? localURL : url;
+                 }
+             }
+
+             PluginDebug.debug("getCachedImageRef() getting img from URL = " + url);
+
+             synchronized (imageRefs) {
+                 AppletImageRef ref = (AppletImageRef)imageRefs.get(url);
+                 if (ref == null) {
+                     ref = new AppletImageRef(url);
+                     imageRefs.put(url, ref);
+                 }
+                 return ref;
+             }
+         } catch (Exception e) {
+             System.err.println("Error occurred wgen trying to fetch image:");
+             e.printStackTrace();
+             return null;
+         }
      }
  
      /**
@@ -703,7 +733,7 @@
  	}
      }
  
-     public int getWindow() {
+     public long getWindow() {
     	 PluginDebug.debug ("STARTING getWindow");
     	 PluginCallRequest request = requestFactory.getPluginCallRequest("window",
     			 							"instance " + identifier + " " + "GetWindow", 
@@ -716,7 +746,7 @@
     		 PluginDebug.debug ("wait request 1");
     		 synchronized(request) {
     			 PluginDebug.debug ("wait request 2");
-    			 while ((Integer) request.getObject() == 0)
+    			 while ((Long) request.getObject() == 0)
     				 request.wait();
     			 PluginDebug.debug ("wait request 3");
     		 }
@@ -726,11 +756,11 @@
     	 }
 
     	 PluginDebug.debug ("STARTING getWindow DONE");
-    	 return (Integer) request.getObject();
+    	 return (Long) request.getObject();
      }
  
      // FIXME: make private, access via reflection.
-     public static Object getMember(int internal, String name)
+     public static Object getMember(long internal, String name)
      {
     	 AppletSecurityContextManager.getSecurityContext(0).store(name);
          int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name);
@@ -757,7 +787,7 @@
          return request.getObject();
      }
  
-     public static void setMember(int internal, String name, Object value) {
+     public static void setMember(long internal, String name, Object value) {
     	 AppletSecurityContextManager.getSecurityContext(0).store(name);
          int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name);
          AppletSecurityContextManager.getSecurityContext(0).store(value);
@@ -786,7 +816,7 @@
      }
  
      // FIXME: handle long index as well.
-     public static void setSlot(int internal, int index, Object value) {
+     public static void setSlot(long internal, int index, Object value) {
     	 AppletSecurityContextManager.getSecurityContext(0).store(value);
          int valueID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value);
  
@@ -811,7 +841,7 @@
          PluginDebug.debug (" setSlot DONE");
      }
  
-     public static Object getSlot(int internal, int index)
+     public static Object getSlot(long internal, int index)
      {
          // Prefix with dummy instance for convenience.
          PluginCallRequest request = requestFactory.getPluginCallRequest("member", 
@@ -835,7 +865,7 @@
          return request.getObject();
      }
  
-     public static Object eval(int internal, String s)
+     public static Object eval(long internal, String s)
      {
     	 AppletSecurityContextManager.getSecurityContext(0).store(s);
          int stringID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(s);
@@ -862,7 +892,7 @@
          return request.getObject();
      }
  
-     public static void removeMember (int internal, String name) {
+     public static void removeMember (long internal, String name) {
     	 AppletSecurityContextManager.getSecurityContext(0).store(name);
          int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name);
  
@@ -887,7 +917,7 @@
          PluginDebug.debug (" RemoveMember DONE");
      }
  
-     public static Object call(int internal, String name, Object args[])
+     public static Object call(long internal, String name, Object args[])
      {
          // FIXME: when is this removed from the object store?
          // FIXME: reference should return the ID.
@@ -919,7 +949,7 @@
          return request.getObject();
      }
  
-     public static void JavaScriptFinalize(int internal)
+     public static void JavaScriptFinalize(long internal)
      {
          // Prefix with dummy instance for convenience.
          PluginCallRequest request = requestFactory.getPluginCallRequest("void",
@@ -942,7 +972,7 @@
          PluginDebug.debug (" finalize DONE");
      }
  
-     public static String javascriptToString(int internal)
+     public static String javascriptToString(long internal)
      {
          // Prefix with dummy instance for convenience.
          PluginCallRequest request = requestFactory.getPluginCallRequest("member",
@@ -1221,6 +1251,16 @@
       */
      public static String scanIdentifier(Reader in) throws IOException {
  	StringBuffer buf = new StringBuffer();
+ 	
+ 	if (c == '!') {
+        // Technically, we should be scanning for '!--' but we are reading 
+        // from a stream, and there is no way to peek ahead. That said, 
+        // a ! at this point can only mean comment here afaik, so we 
+        // should be okay
+        skipComment(in);
+        return "";
+    }
+ 	
  	while (true) {
  	    if (((c >= 'a') && (c <= 'z')) ||
  		((c >= 'A') && (c <= 'Z')) ||
@@ -1232,6 +1272,41 @@
  	    }
  	}
      }
+
+     public static void skipComment(Reader in) throws IOException {
+         StringBuffer buf = new StringBuffer();
+         boolean commentHeaderPassed = false;
+         c = in.read();
+         buf.append((char)c);
+
+         while (true) {
+             if (c == '-' && (c = in.read()) == '-') {
+                 buf.append((char)c);
+                 if (commentHeaderPassed) {
+                     // -- encountered ... is > next?
+                     if ((c = in.read()) == '>') {
+                         buf.append((char)c);
+
+                         PluginDebug.debug("Comment skipped: " + buf.toString());
+
+                         // comment skipped.
+                         return;
+                     }
+                 } else {
+                     // first -- is part of <!-- ... , just mark that we have passed it
+                     commentHeaderPassed = true;
+                 }
+
+             } else if (commentHeaderPassed == false) {
+                 buf.append((char)c);
+                 PluginDebug.debug("Warning: Attempted to skip comment, but this tag does not appear to be a comment: " + buf.toString());
+                 return;
+             }
+
+             c = in.read();
+             buf.append((char)c);
+         }
+     }
  
      /**
       * Scan tag
@@ -1266,11 +1341,21 @@
  		val = buf.toString();
  	    }
 
+        att = att.replace("&gt;", ">");
+        att = att.replace("&lt;", "<");
+        att = att.replace("&amp;", "&");
+        att = att.replace("&#10;", "\n");
+        att = att.replace("&#13;", "\r");
+ 	    
         val = val.replace("&gt;", ">");
         val = val.replace("&lt;", "<");
         val = val.replace("&amp;", "&");
- 	    PluginDebug.debug("PUT " + att + " = '" + val + "'");
- 	    atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val);
+        val = val.replace("&#10;", "\n");
+        val = val.replace("&#13;", "\r");
+
+        PluginDebug.debug("PUT " + att + " = '" + val + "'");
+        atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val);
+
              while (true) {
                  if ((c == '>') || (c < 0) ||
                      ((c >= 'a') && (c <= 'z')) ||
@@ -1283,6 +1368,20 @@
  	}
  	return atts;
      }
+     
+     // private static final == inline
+     private static final boolean isInt(Object o) {
+         boolean isInt = false;
+
+         try {
+             Integer.parseInt((String) o);
+             isInt = true;
+         } catch (Exception e) {
+             // don't care
+         }
+
+         return isInt;
+     }
  
      /* values used for placement of AppletViewer's frames */
      private static int x = 0;
@@ -1426,12 +1525,19 @@
     						 if (val == null) {
     							 statusMsgStream.println(requiresNameWarning);
     						 } else if (atts != null) {
-    							 // to prevent headaches, c++ side encodes &, < and >
-    							 // decode them back
+    							 att = att.replace("&gt;", ">");
+    							 att = att.replace("&lt;", "<");
+    							 att = att.replace("&amp;", "&");
+    							 att = att.replace("&#10;", "\n");
+    							 att = att.replace("&#13;", "\r");
+
     							 val = val.replace("&gt;", ">");
     							 val = val.replace("&lt;", "<");
     							 val = val.replace("&amp;", "&");
-    							 atts.put(att.toLowerCase(), val);
+    							 val = val.replace("&#10;", "\n");
+    							 val = val.replace("&#13;", "\r");
+    							 PluginDebug.debug("PUT " + att + " = " + val);
+   							     atts.put(att.toLowerCase(), val);
     						 } else {
     							 statusMsgStream.println(paramOutsideWarning);
     						 }
@@ -1453,21 +1559,21 @@
     						 atts = null;
     					 }
 
-    					 if (atts.get("width") == null) {
-    						 atts.put("width", "100");
+    					 if (atts.get("width") == null || !isInt(atts.get("width"))) {
+    						 atts.put("width", "1000");
     						 atts.put("widthPercentage", 100);
     					 } else if (((String) atts.get("width")).endsWith("%")) {
     						 String w = (String) atts.get("width");
-    						 atts.put("width", "100");
+    						 atts.put("width", "1000");
     						 atts.put("widthPercentage", Integer.parseInt((w.substring(0,  w.length() -1))));
     					  }
 
-    					 if (atts.get("height") == null) {
-    						 atts.put("height", "100");
+    					 if (atts.get("height") == null || !isInt(atts.get("height"))) {
+    						 atts.put("height", "1000");
     						 atts.put("heightPercentage", 100);
     					 } else if (((String) atts.get("height")).endsWith("%")) {
     						 String h = (String) atts.get("height");
-    						 atts.put("height", "100");
+    						 atts.put("height", "1000");
     						 atts.put("heightPercentage", Integer.parseInt(h.substring(0,  h.length() -1)));
     					 }
     				 }
@@ -1482,6 +1588,28 @@
     						 atts.put("code", ((String) atts.get("classid")).substring(5));
     					 }
 
+                         // java_* aliases override older names:
+                         // http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/using_tags.html#in-ie
+                         if (atts.get("java_code") != null) {
+                             atts.put("code", ((String) atts.get("java_code")));
+                         }
+
+                         if (atts.get("java_codebase") != null) {
+                             atts.put("codebase", ((String) atts.get("java_codebase")));
+                         }
+
+                         if (atts.get("java_archive") != null) {
+                             atts.put("archive", ((String) atts.get("java_archive")));
+                         }
+
+                         if (atts.get("java_object") != null) {
+                             atts.put("object", ((String) atts.get("java_object")));
+                         }
+
+                         if (atts.get("java_type") != null) {
+                             atts.put("type", ((String) atts.get("java_type")));
+                         }
+
     					 // The <OBJECT> attribute codebase isn't what
     					 // we want when not dealing with jars. If its 
     					 // defined, remove it in that case.
@@ -1489,21 +1617,21 @@
     						 atts.remove("codebase");
     					 }
 
-    					 if (atts.get("width") == null) {
-    						 atts.put("width", "100");
+    					 if (atts.get("width") == null || !isInt(atts.get("width"))) {
+    						 atts.put("width", "1000");
     						 atts.put("widthPercentage", 100);
     					 } else if (((String) atts.get("width")).endsWith("%")) {
     						 String w = (String) atts.get("width");
-    						 atts.put("width", "100");
+    						 atts.put("width", "1000");
     						 atts.put("widthPercentage", Integer.parseInt(w.substring(0,  w.length() -1)));
     					 }
 
-    					 if (atts.get("height") == null) {
-    						 atts.put("height", "100");
+    					 if (atts.get("height") == null || !isInt(atts.get("height"))) {
+    						 atts.put("height", "1000");
     						 atts.put("heightPercentage", 100);
     					 } else if (((String) atts.get("height")).endsWith("%")) {
     						 String h = (String) atts.get("height");
-    						 atts.put("height", "100");
+    						 atts.put("height", "1000");
     						 atts.put("heightPercentage", Integer.parseInt(h.substring(0,  h.length() -1)));
     					 }
     				 }
@@ -1517,14 +1645,36 @@
     						 //skip "java:"
     						 atts.put("code", ((String) atts.get("classid")).substring(5));
     					 }
+    					 
+    					 // java_* aliases override older names:
+    					 // http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/using_tags.html#in-nav
+    					 if (atts.get("java_code") != null) {
+    					     atts.put("code", ((String) atts.get("java_code")));
+    					 }
+    					 
+                         if (atts.get("java_codebase") != null) {
+                             atts.put("codebase", ((String) atts.get("java_codebase")));
+                         }
+                         
+                         if (atts.get("java_archive") != null) {
+                             atts.put("archive", ((String) atts.get("java_archive")));
+                         }
+                         
+                         if (atts.get("java_object") != null) {
+                             atts.put("object", ((String) atts.get("java_object")));
+                         }
+    					 
+                         if (atts.get("java_type") != null) {
+                             atts.put("type", ((String) atts.get("java_type")));
+                         }
 
     					 if (atts.get("code") == null && atts.get("object") == null) {
     						 statusMsgStream.println(embedRequiresCodeWarning);
     						 atts = null;
     					 }
     					 
-    					 if (atts.get("width") == null) {
-    						 atts.put("width", "100");
+    					 if (atts.get("width") == null || !isInt(atts.get("width"))) {
+    						 atts.put("width", "1000");
     						 atts.put("widthPercentage", 100);
     					 } else if (((String) atts.get("width")).endsWith("%")) {
     						 String w = (String) atts.get("width");
@@ -1532,8 +1682,8 @@
     						 atts.put("widthPercentage", Integer.parseInt(w.substring(0,  w.length() -1)));
     					 }
 
-    					 if (atts.get("height") == null) {
-    						 atts.put("height", "100");
+    					 if (atts.get("height") == null || !isInt(atts.get("height"))) {
+    						 atts.put("height", "1000");
     						 atts.put("heightPercentage", 100);
     					 } else if (((String) atts.get("height")).endsWith("%")) {
     						 String h = (String) atts.get("height");
@@ -1554,17 +1704,17 @@
     						 atts2.remove("src");
     						 atts2.put("codebase", nm);
     					 }
-    					 if (atts2.get("width") == null) {
-    						 atts2.put("width", "100");
+    					 if (atts2.get("width") == null || !isInt(atts2.get("width"))) {
+    						 atts2.put("width", "1000");
     						 atts2.put("widthPercentage", 100);
     					 } else if (((String) atts.get("width")).endsWith("%")) {
     						 String w = (String) atts.get("width");
     						 atts2.put("width", "100");
     						 atts2.put("widthPercentage", Integer.parseInt(w.substring(0,  w.length() -1)));
     					 }
-    					 
-    					 if (atts2.get("height") == null) {
-    						 atts2.put("height", "100");
+
+    					 if (atts2.get("height") == null || !isInt(atts2.get("height"))) {
+    						 atts2.put("height", "1000");
     						 atts2.put("heightPercentage", 100);
     					 } else if (((String) atts.get("height")).endsWith("%")) {
     						 String h = (String) atts.get("height");
--- a/plugin/icedtea/sun/applet/PluginMessageHandlerWorker.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/plugin/icedtea/sun/applet/PluginMessageHandlerWorker.java	Tue Dec 02 13:58:24 2008 +0000
@@ -24,6 +24,8 @@
 
 			if (message != null) {
 				
+			    PluginDebug.debug("Consumer thread " + id + " consuming " + message);
+			    
 				// ideally, whoever returns things object should mark it 
 				// busy first, but just in case..
 				busy();
@@ -39,21 +41,24 @@
 				}
 
 				this.message = null;
+				
+				PluginDebug.debug("Consumption completed by consumer thread " + id);
+
+	            // mark ourselves free again
+				free();
+				
 			} else {
 				
 				// Sleep when there is nothing to do
-				try {
-					Thread.sleep(Integer.MAX_VALUE);
-					PluginDebug.debug("Consumer thread " + id + " sleeping...");
-				} catch (InterruptedException ie) {
-					PluginDebug.debug("Consumer thread " + id + " woken...");
-					// nothing.. someone woke us up, see if there 
-					// is work to do
-				}
+			    try {
+			        Thread.sleep(Integer.MAX_VALUE);
+			        PluginDebug.debug("Consumer thread " + id + " sleeping...");
+			    } catch (InterruptedException ie) {
+			        PluginDebug.debug("Consumer thread " + id + " woken...");
+			        // nothing.. someone woke us up, see if there 
+			        // is work to do
+			    }
 			}
-			
-			// mark ourselves free again
-			free();
 		}
 	}
 	
--- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp	Fri Nov 21 10:29:58 2008 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp	Tue Dec 02 13:58:24 2008 +0000
@@ -1814,6 +1814,8 @@
     in_ByteSize(instanceKlass::vtable_length_offset() * HeapWordSize),
     SharkType::jint_type(),
     "vtable_length");
+  vtable_length =
+    builder()->CreateIntCast(vtable_length, SharkType::intptr_type(), false);
 
   bool needs_aligning = HeapWordsPerLong > 1;
   const char *itable_start_name = "itable_start";
@@ -1821,7 +1823,7 @@
     vtable_start,
     builder()->CreateShl(
       vtable_length,
-      LLVMValue::jint_constant(exact_log2(vtableEntry::size() * wordSize))),
+      LLVMValue::intptr_constant(exact_log2(vtableEntry::size() * wordSize))),
     needs_aligning ? "" : itable_start_name);
   if (needs_aligning)
     itable_start = builder()->CreateAlign(
@@ -1878,6 +1880,8 @@
     in_ByteSize(itableOffsetEntry::offset_offset_in_bytes()),
     SharkType::jint_type(),
     "offset");
+  offset =
+    builder()->CreateIntCast(offset, SharkType::intptr_type(), false);
 
   Value *index = builder()->CreateValueOfStructEntry(
     cache, ConstantPoolCacheEntry::f2_offset(),
@@ -1894,7 +1898,7 @@
             offset),
           builder()->CreateShl(
             index,
-            LLVMValue::jint_constant(
+            LLVMValue::intptr_constant(
               exact_log2(itableMethodEntry::size() * wordSize)))),
         LLVMValue::intptr_constant(
           itableMethodEntry::method_offset_in_bytes())),
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Fri Nov 21 10:29:58 2008 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Tue Dec 02 13:58:24 2008 +0000
@@ -29,7 +29,7 @@
 using namespace llvm;
 
 SharkBuilder::SharkBuilder()
-  : IRBuilder(),
+  : IRBuilder<>(),
       _module("shark"),
       _module_provider(module()),
       _execution_engine(ExecutionEngine::create(&_module_provider))
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Fri Nov 21 10:29:58 2008 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Tue Dec 02 13:58:24 2008 +0000
@@ -23,7 +23,7 @@
  *
  */
 
-class SharkBuilder : public llvm::IRBuilder {
+class SharkBuilder : public llvm::IRBuilder<> {
  public:
   SharkBuilder();
 
@@ -81,13 +81,13 @@
                                   llvm::Value*      index,
                                   const char*       name = "")
   {
-    llvm::Value* offset = index;
+    llvm::Value* offset = CreateIntCast(index, SharkType::intptr_type(), false);
     if (element_bytes != 1)
       offset = CreateShl(
         offset,
-        LLVMValue::jint_constant(exact_log2(element_bytes)));
+        LLVMValue::intptr_constant(exact_log2(element_bytes)));
     offset = CreateAdd(
-      LLVMValue::jint_constant(in_bytes(base_offset)), offset);
+      LLVMValue::intptr_constant(in_bytes(base_offset)), offset);
 
     return CreateIntToPtr(
       CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset),
--- a/ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp	Fri Nov 21 10:29:58 2008 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp	Tue Dec 02 13:58:24 2008 +0000
@@ -82,6 +82,12 @@
 
 Value *SharkConstantPool::cache_entry_at(int which)
 {
+  // Takes a constant pool cache index in byte-swapped byte order
+  // (which comes from the bytecodes after rewriting).  This is a
+  // bizarre hack but it's the same as
+  // constantPoolOopDesc::field_or_method_at().
+  which = Bytes::swap_u2(which);
+
   Value *entry = builder()->CreateIntToPtr(
     builder()->CreateAdd(
       builder()->CreatePtrToInt(
@@ -109,7 +115,7 @@
       builder()->CreateValueOfStructEntry(
         entry, ConstantPoolCacheEntry::indices_offset(),
         SharkType::intptr_type()),
-      LLVMValue::jint_constant(shift)),
+      LLVMValue::intptr_constant(shift)),
     LLVMValue::intptr_constant(0xff));
 
   BasicBlock *orig_block = builder()->GetInsertBlock();
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp	Fri Nov 21 10:29:58 2008 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp	Tue Dec 02 13:58:24 2008 +0000
@@ -182,7 +182,7 @@
   Value *fp = CreateLoadZeroFramePointer();
   Value *sp = builder()->CreateAdd(
     fp,
-    LLVMValue::jint_constant((1 + locals_to_pop) * wordSize));
+    LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize));
 
   CreateStoreZeroStackPointer(sp);
   CreateStoreZeroFramePointer(
--- a/ports/hotspot/src/share/vm/shark/sharkValue.hpp	Fri Nov 21 10:29:58 2008 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkValue.hpp	Tue Dec 02 13:58:24 2008 +0000
@@ -246,7 +246,7 @@
   {
     ShouldNotCallThis();
   }
-  virtual llvm::Value* intptr_value(llvm::IRBuilder* builder) const
+  virtual llvm::Value* intptr_value(llvm::IRBuilder<>* builder) const
   {
     ShouldNotCallThis();
   }
@@ -370,7 +370,7 @@
   {
     return llvm_value();
   }
-  llvm::Value* intptr_value(llvm::IRBuilder* builder) const
+  llvm::Value* intptr_value(llvm::IRBuilder<>* builder) const
   {
     assert(is_jobject(), "should be");
     return builder->CreatePtrToInt(llvm_value(), SharkType::intptr_type());
--- a/test/jtreg/com/sun/javatest/regtest/Main.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/test/jtreg/com/sun/javatest/regtest/Main.java	Tue Dec 02 13:58:24 2008 +0000
@@ -29,6 +29,7 @@
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.FileWriter;
@@ -52,6 +53,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.TreeMap;
 
 import com.sun.javatest.CompositeFilter;
@@ -1354,6 +1356,10 @@
             if (ignoreKind != null)
                 rp.setIgnoreKind(ignoreKind);
 
+            sameJVMSafeDirs = getSameJVMSafeDirs(ts);
+            if (sameJVMSafeDirs != null)
+                rp.setSameJVMSafeDirs(sameJVMSafeDirs);
+
             return rp;
         } catch (TestSuite.Fault f) {
             f.printStackTrace();
@@ -1374,6 +1380,35 @@
         }
     }
 
+    // Returns directory (prefix) for tests that are same jvm safe
+    // read from amejvmsafe property in TEST.ROOT file. Returning null
+    // means all tests are considered same jvm safe. null is returned
+    // when there is no samejvmsafe property, or there was a problem
+    // reading it, and when anything else than the test root was given
+    // as test file argument. Meaning that this only returns something
+    // non-null if anything was actually specified as same jvm safe and
+    // the whole test suite is being tested.
+    private List<String> getSameJVMSafeDirs(File testRoot) {
+	// Only use the same jvm safe dirs when running from the root.
+	if (testFileArgs.size() != 1
+	    || !canon(testFileArgs.iterator().next()).equals(canon(testRoot)))
+	    return null;
+
+	try {
+	    File file = new File(testRoot, "TEST.ROOT");
+            if (file.exists()) {
+		Properties testRootProps = new Properties();
+		testRootProps.load(new FileInputStream(file));
+		String safedirs = testRootProps.getProperty("samejvmsafe");
+		if ((safedirs != null) && (safedirs.trim().length() > 0))
+		    return Arrays.asList(StringArray.splitWS(safedirs));
+	    }
+	} catch (IOException ioe) {
+	    // Bah, then just assume everything is safe.
+	}
+	return null;
+    }
+
     private String getRelativePath(File base, File f) {
         StringBuilder sb = new StringBuilder();
         for ( ; f != null; f = f.getParentFile()) {
@@ -1762,6 +1797,7 @@
     // these args are jtreg extras
     private File baseDirArg;
     private boolean sameJVMFlag;
+    private List<String> sameJVMSafeDirs;
     private JDK jdk;
     private boolean guiFlag;
     private boolean reportOnlyFlag;
--- a/test/jtreg/com/sun/javatest/regtest/RegressionParameters.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/test/jtreg/com/sun/javatest/regtest/RegressionParameters.java	Tue Dec 02 13:58:24 2008 +0000
@@ -139,6 +139,7 @@
     private static final String TEST_JAVA_OPTIONS = ".testJavaOpts";
     private static final String IGNORE = ".ignore";
     private static final String RETAIN_ARGS = ".retain";
+    private static final String SAME_JVM_SAFE_DIRS = ".samejvmsafedirs";
     
     @Override
     public void load(Map data, boolean checkChecksum) throws Interview.Fault {
@@ -182,6 +183,10 @@
         v = (String) data.get(prefix + RETAIN_ARGS);
         if (v != null)
             setRetainArgs(Arrays.asList(StringArray.splitSeparator("\n", v)));
+
+        v = (String) data.get(prefix + SAME_JVM_SAFE_DIRS);
+        if (v != null)
+            setSameJVMSafeDirs(Arrays.asList(StringArray.splitSeparator("\n", v)));
     }
     
     @SuppressWarnings("unchecked")
@@ -204,6 +209,9 @@
         if (jdk != null)
             data.put(prefix + JDK, jdk.getPath());
         
+        if (sameJVMSafeDirs != null)
+            data.put(prefix + SAME_JVM_SAFE_DIRS, StringUtils.join(sameJVMSafeDirs, "\n"));
+        
         if (retainArgs != null)
             data.put(prefix + RETAIN_ARGS, StringUtils.join(retainArgs, "\n"));
         
@@ -592,6 +600,18 @@
     private Pattern retainFilesPattern;
 
     //---------------------------------------------------------------------
+    
+    List<String> getSameJVMSafeDirs() {
+        return sameJVMSafeDirs;
+    }
+    
+    void setSameJVMSafeDirs(List<String> sameJVMSafeDirs) {
+        this.sameJVMSafeDirs= sameJVMSafeDirs;
+    }
+
+    private List<String> sameJVMSafeDirs;
+
+    //---------------------------------------------------------------------
 
     private static final String PATHSEP  = System.getProperty("path.separator");
     private static final String LINESEP  = System.getProperty("line.separator");
--- a/test/jtreg/com/sun/javatest/regtest/RegressionScript.java	Fri Nov 21 10:29:58 2008 +0000
+++ b/test/jtreg/com/sun/javatest/regtest/RegressionScript.java	Tue Dec 02 13:58:24 2008 +0000
@@ -69,6 +69,10 @@
     public Status run(String[] argv, TestDescription td, TestEnvironment env) {
         if (!(env instanceof RegressionEnvironment))
             throw new AssertionError();
+
+	String testFilePath = td.getRootRelativePath();
+	int lastSlash = testFilePath.lastIndexOf('/');
+	testDirPath = testFilePath.substring(0, lastSlash);
         
         regEnv = (RegressionEnvironment) env;
         params = regEnv.params;
@@ -833,7 +837,26 @@
     }
 
     boolean isOtherJVM() {
-        return params.isOtherJVM();
+	boolean samevm = !params.isOtherJVM();
+	if (samevm)
+	    return !isSameJVMSafe();
+	else
+	    return true;
+    }
+
+    // Whether the actions of this script can safely run in the same jvm.
+    // No same jvm safe dirs given means they are all assumed safe.
+    // If our actions come from a file in a subdir of a safe dir that is ok.
+    boolean isSameJVMSafe() {
+        List<String> dirs = params.getSameJVMSafeDirs();
+	if (dirs == null)
+	    return true;
+
+	for (String dir : dirs)
+	    if (testDirPath.startsWith(dir))
+		return true;
+
+	return false;
     }
 
     String getJavaProg() {
@@ -921,5 +944,6 @@
 
     private RegressionEnvironment regEnv;
     private RegressionParameters params;
+    private String testDirPath;
 }