Mercurial > hg > release > icedtea6-1.11
changeset 2643:5deef52b5a9c
Merge
author | Andrew John Hughes <ahughes@redhat.com> |
---|---|
date | Wed, 06 Jul 2011 17:11:34 +0100 |
parents | b1123c5a67f7 (current diff) 73e0d37b9ec3 (diff) |
children | 23404f48955e |
files | ChangeLog Makefile.am acinclude.m4 patches/jamvm/ignore-unknown-options.patch |
diffstat | 236 files changed, 11397 insertions(+), 4403 deletions(-) [+] |
line wrap: on
line diff
--- a/AUTHORS Wed Jun 01 02:35:43 2011 +0100 +++ b/AUTHORS Wed Jul 06 17:11:34 2011 +0100 @@ -8,6 +8,7 @@ Deepak Bhole <dbhole@redhat.com> Tom Callaway <tcallawa@redhat.com> Pablo del Campo <pablogdc@gmail.com> +Danesh Dadachanji <ddadacha@redhat.com> Thomas Fitzsimmons <fitzsim@redhat.com> Matthew Flaschen <matthew.flaschen@gatech.edu> Michael Franz <mvfranz@gmail.com>
--- a/ChangeLog Wed Jun 01 02:35:43 2011 +0100 +++ b/ChangeLog Wed Jul 06 17:11:34 2011 +0100 @@ -1,3 +1,445 @@ +2011-07-01 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patches + * NEWS: updated with backports + * patches/openjdk/6679308-Poor_text_rendering_on_translucent_image.patch: + Backport of 6679308. + +2011-07-01 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * NEWS: updated with backport + * patches/openjdk/7029152-String_intrinsics_miss_optimization.patch: + Backport of 7029152 fix. + +2011-06-29 Andrew John Hughes <ahughes@redhat.com> + + * NEWS: Updated with latest bug fixes. + +2011-06-29 Andrew John Hughes <ahughes@redhat.com> + + * patches/ecj/jaxws-getdtdtype.patch: + Fix patch to still apply after recent + security updates. + +2011-06-29 Andrew John Hughes <ahughes@redhat.com> + + * acinclude.m4: + (IT_FIND_JAVA): Check that the binary is also + a regular file as well as executable. + (IT_FIND_JAVAH): Likewise. + (IT_FIND_JAR): Likewise. + (IT_FIND_RMIC): Likewise. + (IT_FIND_NATIVE2ASCII): Likewise. + +2011-06-29 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patches + * NEWS: updated with backports + * patches/openjdk/6796786-invalid_FP_identity_transform.patch: + * patches/openjdk/7042070-Typo_in_Test6796786.patch: + Backport of 6796786 and 7042070 fixes. + +2011-06-29 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patches + * NEWS: updated with backports + * patches/openjdk/7047069-Array_can_dynamically_change_size.patch: + Backport of 7047069 fix. + +2011-06-28 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * NEWS: updated with backport + * patches/openjdk/6785424-SecurityException_locating_physical_fonts.patch: + Backport of 6785424 fix. + +2011-06-28 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * NEWS: updated with backport + * patches/openjdk/6783910-java_awt_Color_brighter_darker_fix.patch: + Backport of 6783910 fix. + +2011-06-28 Andrew John Hughes <ahughes@redhat.com> + + * Makefile.am: Add new patch. + * patches/support_linux_3.patch: + Allow Linux 3* through the HotSpot OS version + filter. + +2011-06-27 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * NEWS: updated with backport + * patches/openjdk/6623219-Font_canDisplayUpTo_does_not_work.patch + Backport of 6623219 fix. + +2011-06-27 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * NEWS: updated with backport + * patches/openjdk/6918065-Crash_in_Java2D_blit_loop.patch: + Backport of 6918065 fix. + +2011-06-27 Xerxes RÃ¥nby <xerxes@zafena.se> + + JamVM + - Make classlib init functions consistent + warnings. + - Correctly implement sun.misc.Unsafe freeMemory(). + - Move lazy-loading to init function. + - Fix various warnings with -Wall. + - PrintThreadsDump needs "self" as argument. + - CopyMemory, etc. handle negative or truncation in length. + - Extra sun.misc.Unsafe functions. + - Ignore options for jtreg tests. + - Enable shutdownVM to be called with OpenJDK classlib. + - Initial implementation of JVM_FindClassFromBootLoader. + - Fix callJNIMethod on i386 with -fomit-frame-pointer. + - Fix backwards cache conflict resolution code. + - Unify command line options parsing. + - Remove debug printf. + * NEWS: Updated. + * Makefile.am + (ICEDTEA_PATCHES): Remove upstreamed JamVM patch. + (JAMVM_VERSION): Updated JamVM to 2011-06-13 revision. + (JAMVM_SHA256SUM): Updated. + (stamps/jamvm.stamp): + Add -f when creating client symlink to handle repeat builds. + Link the fake libjsig.so to JamVM libjvm.so to work + with latest OpenJDK ALT_HOTSPOT_IMPORT_PATH functionality. + * patches/jamvm/ignore-unknown-options.patch: Removed. + Replaced by upstream, unify command line options parsing, + changeset 1b248439e88ae6cbd1471addc49e2666b8964ced. + +2011-06-24 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * NEWS: updated with backport + * patches/openjdk/6699843-IllegalArgumentException_drawString.patch: + Backport of 6699843 fix. + +2011-06-24 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * NEWS: updated with backport + * patches/openjdk/6956668-misbehavior_of_XOR_operator_with_int: + Backport of 6956668 fix. + +2011-06-23 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * NEWS: updated with backport + * patches/openjdk/7008106-WindowOpacity.patch: + Backport of 7008106 regression test fix. + +2011-06-23 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * patches/jtreg-MappedByteBuffer-Basic.patch: + Make sure that the regression test + openjdk/jdk/test/java/nio/MappedByteBuffer/Basic.java + deletes all its work files. + +2011-06-22 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * patches/openjdk/6818312-com.sun.awt.SecurityWarning.getSize.patch: + Backport of 6818312 regression test. + +2011-06-22 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: Added new patch. + * patches/jtreg-ReadWriteProfileTest.patch: + Added regression test missing from 6733501 backport. + +2011-06-22 Pavel Tisnovsky <ptisnovs@redhat.com> + + * patches/jtreg-png-reader.patch: + Added new regression test which check if PNG + images read by ImageIO subsytstem contains + proper pixel values. + +2011-06-20 Denis Lila <dlila@redhat.com> + + * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c + (SET_STREAM_ENUM): Add an underscore after java_prefix so that + the produced string matches the names in Stream.java. + +2011-06-20 Denis Lila <dlila@redhat.com> + + * Makefile.am: Add patch. + * patches/jtreg-bug7036148-test.patch: + Fix regression test. It used to never end, regardless of + success/failure. + +2011-06-20 Denis Lila <dlila@redhat.com> + + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java + (bufferSize): Remove. + (getBufferSize): Return stream.getBufferSize(). + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java + (connectLine): Improve formatting. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java + (connectLine): Set up flags to adjust the latency, if needed. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java + (bufAttr, bufAttrMutex): New members. + (setBufAttr, bufferAttrCallback): New methods. They both set bufAttr. + (getBufferSize): Return the current buffer size. + (connectForRecording): Add a flags argument to allow callers to chose the + flags. + (stateCallback): When the stream is ready, set the buffer attributes to + the actual ones used by the server. + * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c + (buf_attr_changed_callback): New function. + (Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1new): + Set the buffer attribute callback. + +2011-06-17 Denis Lila <dlila@redhat.com> + + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java + (FLAG_NOFLAGS, FLAG_START_CORKED, FLAG_INTERPOLATE_TIMING, + FLAG_NOT_MONOTONIC, FLAG_AUTO_TIMING_UPDATE, FLAG_NO_REMAP_CHANNELS, + FLAG_NO_REMIX_CHANNELS, FLAG_FIX_FORMAT, FLAG_FIX_RATE, + FLAG_FIX_CHANNELS, FLAG_DONT_MOVE, FLAG_VARIABLE_RATE, FLAG_PEAK_DETECT, + FLAG_START_MUTED, FLAG_ADJUST_LATENCY, FLAG_EARLY_REQUESTS, + FLAG_DONT_INHIBIT_AUTO_SUSPEND, FLAG_START_UNMUTED, FLAG_FAIL_ON_SUSPEND): + New static long variables mirroring pa_stream_flag_t values. + (STATE_UNCONNECTED, STATE_CREATING, STATE_READY, STATE_FAILED, + STATE_TERMINATED): Add the STATE_ prefix to distinguish them from + the flag variables. + (native_pa_stream_connect_playback, native_pa_stream_connect_record): + Change flags parameter to long. + (connectForPlayback, connectForRecording): Start the stream corked. + Change formatting to make it more readable. + * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c + (SET_STREAM_ENUM): Renamed from SET_STREAM_STATE_ENUM, since the + macro could have been used for any PA_STREAM constants, not just + stream states (and indeed, we now use it for flag constants too). + (Java_org_classpath_icedtea_pulseaudio_Stream_init_1constants): + Initialize flag constants in addition to the stream states. + (Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1connect_1playback): + Change flags parameter to jlong (from jint), remove commented out + dead code, remove obsolete comment, and start the stream with whatever + flags were passed in the flags parameter, instead of ignoring that + parameter and using PA_STREAM_START_CORKED. + (Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1connect_1record): + Change flags parameter to jlong (from jint), remove commented out + dead code. + +2011-06-17 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * patches/jtreg-ChannelsWrite.patch: + Make sure that the regression test + openjdk/jdk/test/java/nio/channels/Channels/Write.java + deletes all its work files. + +2011-06-16 Denis Lila <dlila@redhat.com> + + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java + (addStreamListeners): Remove this.notifyAll() from + openCloseListener.update; change this.notifyAll() to + PulseAudioDataLine.this.notifyAll() in startedListener.update. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java + (read): Put fragmentBuffer null check in the synchronized block. + (flush): Make it synchronized to avoid race condition with read(). + +2011-06-16 Denis Lila <dlila@redhat.com> + + * Makefile.am: Add ContextEvent to the list of pulse audio classes that + need javah run on them. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/ContextEvent.java + (Type): Remove and replace with... + (UNCONNECTED, CONNECTING, AUTHORIZING, SETTING_NAME, READY, FAILED, + TERMINATED): New static long variables replacing enum Type. + (init_constants): New native method to initialize the above variables. + (checkNativeEnumReturn): Make sure that the input is one of the longs + representing the type of ContextEvent. + (type): Change type from Type to long. + (ContextEvent): Take a long argument, instead of a Type. + (getType): Return a long, not a Type. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java + (status): Change from int to long. + (native_set_sink_volume): Remove. It was unimplemented in the JNI side. + (getStatus): Return long instead of int. + (update): Replace int argument with long argument. Remove the switch + statement. + (setVolume): Remove. Unused. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Operation.java + (State): Remove and replace with... + (Running, Done, Cancelled): Static longs, enumerating the possible + operation states. + (init_constants): New native method to initialize the above variables. + (checkNativeOperationState): Make sure that the input is one of the longs + representing the operation state. + (native_get_state): Change return type from int to long. + (getState): Change return type to long; remove switch. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java + Remove the names of enums from the names of constants since most of them + were changed to static longs. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java + Same changes as in PulseAudioDataLine.java. + * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java + (State): Remove and replace with... + (UNCONNECTED, CREATING, READY, FAILED, TERMINATED): New static long variables + replacing enum Type. + (init_constants): New native method to initialize the above variables. + (checkNativeStreamState): Make sure that the input is one of the longs + representing the kind of StreamState. + (native_pa_stream_get_state): Change the return from int to long. + (getState): Remove the switch. + * pulseaudio/src/native/jni-common.h + (SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM): Macro that sets one of the java + static longs to the corresponding pa_constant. + * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_ContextEvent.c + New file. + (SET_CONTEXT_ENUM): Macro that sets the ContextEvent types. + (Java_org_classpath_icedtea_pulseaudio_ContextEvent_init_1constants): + Implementation of ContextEvent.init_constants. + * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c + (context_change_callback): Change the fourth argument of GetMethodID + to "(J)V" to reflect the change in the signature of EventLoop.update. + * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Operation.c + (SET_OP_ENUM): Macro that sets the operation types. + (Java_org_classpath_icedtea_pulseaudio_Operation_init_1constants): + Implementation of Operation.init_constants. + (Java_org_classpath_icedtea_pulseaudio_Operation_native_1get_1state): + Change return type to jlong. + * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c + (SET_STREAM_ENUM): Macro that sets the stream states. + (Java_org_classpath_icedtea_pulseaudio_Stream_init_1constants): + Implementation of Stream.init_constants. + (Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1state): + Change return type to jlong. + +2011-06-16 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: fixed indentation (spaces2tabs) + +2011-06-16 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * patches/jtreg-FileMap.patch: + Make sure that the regression test + openjdk/jdk/test/sun/net/www/protocol/file/FileMap.java + deletes all its work files. + +2011-06-15 Danesh Dadachanji <ddadacha@redhat.com> + + * AUTHORS: Added myself. + * Makefile.am: Use explicit xml-commons locations if necessary. + * acinclude.m4: Added explicit xml-commons check. + (IT_CHECK_IF_INSTANTIABLE): Added generic macro to instantiate any + class. Paramaters are the define, name of the class, paramaters + for instatiation and (optional) classpath. + * configure.ac: Invoke IT_FIND_XML_COMMONS_APIS_JAR macro after + IT_FIND_XERCES2_JAR, assigns XML_COMMONS_APIS_JAR if necessary. + +2011-06-15 Denis Lila <dlila@redhat.com> + + * Makefile.am: Add back the -classpath option to javah in + building the pulse audio header files. The bootstrap javah + doesn't recognize -J-Xbootclasspath/p: so it couldn't find + the classfiles. + +2011-06-15 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * patches/jtreg-EncodedMultiByteChar.patch: + Make sure that the regression test + openjdk/jdk/test/sun/net/www/protocol/file/EncodedMultiByteChar.java + deletes all its work files. + +2011-06-14 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * patches/jtreg-FileLoaderTest.patch: + Make sure that the regression test + openjdk/jdk/test/sun/misc/URLClassPath/FileLoaderTest.java + deletes all its work files. + +2011-06-14 Denis Lila <dlila@redhat.com> + + * Makefile.am: Add patch. + * NEWS: Update with backports. + * patches/openjdk/7036148-npe-null-jmenu-name.patch: + Backport of S7036148. Fixes RH712211 too. + +2011-06-14 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * patches/jtreg-TempBuffer.patch: + Make sure that the regression test + openjdk/jdk/test/sun/nio/ch/TempBuffer.java + deletes all its work files. + +2011-06-14 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: added new patch + * patches/jtreg-ChangeDir.patch: + Make sure that the regression test + openjdk/jdk/test/tools/jar/ChangeDir.java + deletes all its work files. + +2011-05-23 Andrew John Hughes <ahughes@redhat.com> + + * Makefile.am: Add security patches. + * patches/nio2.patch: Rerolled post-security + patching. + * patches/security/20110607/6213702.patch, + * patches/security/20110607/6618658.patch, + * patches/security/20110607/7012520.patch, + * patches/security/20110607/7013519.patch, + * patches/security/20110607/7013969.patch, + * patches/security/20110607/7013971.patch, + * patches/security/20110607/7016495.patch, + * patches/security/20110607/7020198.patch, + * patches/security/20110607/7020373.patch: + New security patches. + * patches/xjc.patch: Rerolled after 7013971. + +2011-06-10 Denis Lila <dlila@redhat.com> + + * pulseaudio/*: Fix whitespace. + +2011-06-10 Denis Lila <dlila@redhat.com> + + * Makefile.am + (stamps/pulse-java-headers.stamp): Prepend the java build directory + to the boot class path to avoid generating headers for the system + pulse-java classes. + +2011-06-10 Pavel Tisnovsky <ptisnovs@redhat.com> + + * patches/font-rhel.patch: + * patches/f14-fonts.patch: + * patches/fonts-gentoo.patch: + Patch updated: use only major RHEL version, not minor one. + +2011-06-09 Denis Lila <dlila@redhat.com> + + * Makefile.am: Apply patches. + * NEWS: Update with backports. + * patches/openjdk/6578583-modality-broken-vista.patch: + * patches/openjdk/6610244-modal-fatal-error-windows.patch: + * patches/openjdk/6769607-modal-hangs.patch: + New patches. The last fixes PR677. The other two are + necessary for the last to fully apply. + * patches/openjdk/6693253-security_warning.patch: + Replsace the awt_Dialog.cpp hunk with the corresponding hunk + from the OpenJDK7 changeset of which this patch is a backport. + Without this change, this patch doesn't apply unless the + previous 3 are removed. + +2011-06-09 Pavel Tisnovsky <ptisnovs@redhat.com> + + * Makefile.am: Added new patch + * patches/fonts-rhel-version.patch: + Patch which ensures, that only one fontconfig file + will be needed on particular RHEL version + (ie. only one file for RHEL 6.0, RHEL 6.1 and RHEL 6.2) + 2011-05-30 Andrew John Hughes <ahughes@redhat.com> * patches/openjdk/7036220-shark_llvm_29_headers.patch:
--- a/Makefile.am Wed Jun 01 02:35:43 2011 +0100 +++ b/Makefile.am Wed Jul 06 17:11:34 2011 +0100 @@ -11,8 +11,8 @@ CACAO_URL = $(CACAO_BASE_URL)/$(CACAO_VERSION).tar.gz CACAO_SRC_ZIP = cacao-$(CACAO_VERSION).tar.gz -JAMVM_VERSION = 2e52a601883dda84c824b43363c02881def3e06d -JAMVM_SHA256SUM = b26bc67ddfb50c98761aa4939254470ec9a8f88e9a22628b858603099a784af8 +JAMVM_VERSION = f8b8e8e78ec057a5852ff8c0f3386b48f3eca907 +JAMVM_SHA256SUM = 4107152b0a840656f3551c9b21cb52696417ba6d597457a8b34c86437f9ce64e JAMVM_BASE_URL = http://icedtea.classpath.org/download/drops/jamvm JAMVM_URL = $(JAMVM_BASE_URL)/jamvm-$(JAMVM_VERSION).tar.gz JAMVM_SRC_ZIP = jamvm-$(JAMVM_VERSION).tar.gz @@ -185,10 +185,20 @@ ICEDTEA_FSG_PATCHES = -SECURITY_PATCHES = +SECURITY_PATCHES = patches/security/20110607/6213702.patch \ + patches/security/20110607/6618658.patch \ + patches/security/20110607/7012520.patch \ + patches/security/20110607/7013519.patch \ + patches/security/20110607/7013969.patch \ + patches/security/20110607/7013971.patch \ + patches/security/20110607/7016495.patch \ + patches/security/20110607/7020198.patch \ + patches/security/20110607/7020373.patch ICEDTEA_PATCHES = \ $(SECURITY_PATCHES) \ + patches/openjdk/6578583-modality-broken-vista.patch \ + patches/openjdk/6610244-modal-fatal-error-windows.patch \ patches/stdc-limit-macros.patch \ patches/openjdk/4993545-nativeinlightfixer.patch \ patches/openjdk/6637796-set_bounds.patch \ @@ -201,9 +211,10 @@ patches/openjdk/6725214-direct3d-01.patch \ patches/openjdk/6748082-isDisplayLocal.patch \ patches/openjdk/6633275-shaped_translucent_windows.patch \ - patches/openjdk/6791612-opengl-jni-fix.patch \ - patches/openjdk/6755274-glgetstring-crash.patch \ - patches/openjdk/6984543-onscreen_rendering_resize_test.patch \ + patches/openjdk/6769607-modal-hangs.patch \ + patches/openjdk/6791612-opengl-jni-fix.patch \ + patches/openjdk/6755274-glgetstring-crash.patch \ + patches/openjdk/6984543-onscreen_rendering_resize_test.patch \ patches/openjdk/6693253-security_warning.patch \ patches/openjdk/6444769-windowwithwarningtest.patch \ patches/notice-safepoints.patch \ @@ -327,11 +338,36 @@ patches/openjdk/7037939-hugepage.patch \ patches/openjdk/7043564-hugepage.patch \ patches/openjdk/mutter.patch \ + patches/fonts-rhel-version.patch \ + patches/openjdk/7036148-npe-null-jmenu-name.patch \ + patches/jtreg-ChangeDir.patch \ + patches/jtreg-TempBuffer.patch \ + patches/jtreg-EncodedMultiByteChar.patch \ + patches/jtreg-FileLoaderTest.patch \ + patches/jtreg-FileMap.patch \ + patches/jtreg-ChannelsWrite.patch \ + patches/jtreg-bug7036148-test.patch \ + patches/jtreg-ReadWriteProfileTest.patch \ + patches/openjdk/6818312-com.sun.awt.SecurityWarning.getSize.patch \ + patches/jtreg-MappedByteBuffer-Basic.patch \ + patches/openjdk/7008106-WindowOpacity.patch \ + patches/openjdk/6956668-misbehavior_of_XOR_operator_with_int.patch \ + patches/openjdk/6699843-IllegalArgumentException_drawString.patch \ + patches/openjdk/6918065-Crash_in_Java2D_blit_loop.patch \ + patches/openjdk/6623219-Font_canDisplayUpTo_does_not_work.patch \ + patches/support_linux_3.patch \ + patches/openjdk/6783910-java_awt_Color_brighter_darker_fix.patch \ + patches/openjdk/6785424-SecurityException_locating_physical_fonts.patch \ + patches/openjdk/7047069-Array_can_dynamically_change_size.patch \ + patches/openjdk/6796786-invalid_FP_identity_transform.patch \ + patches/openjdk/7042070-Typo_in_Test6796786.patch \ + patches/openjdk/6679308-Poor_text_rendering_on_translucent_image.patch patches/pr639-broken_shark_build.patch \ patches/powerpc-stacksize.patch \ patches/jtreg-remove-test-6987555.patch \ patches/jtreg-remove-test-6991596.patch \ - patches/openjdk/7036220-shark_llvm_29_headers.patch + patches/openjdk/7036220-shark_llvm_29_headers.patch \ + patches/openjdk/7029152-String_intrinsics_miss_optimization.patch if WITH_RHINO ICEDTEA_PATCHES += \ @@ -351,11 +387,6 @@ patches/cacao/ignore-tests.patch endif -if BUILD_JAMVM -ICEDTEA_PATCHES += \ - patches/jamvm/ignore-unknown-options.patch -endif - if ENABLE_PULSE_JAVA ICEDTEA_PATCHES += \ patches/pulse-soundproperties.patch @@ -1248,7 +1279,12 @@ ln -sf $(XALAN2_JAR) $(ECJ_BOOT_DIR)/lib/endorsed/xalan-j2.jar && \ ln -sf $(XALAN2_SERIALIZER_JAR) \ $(ECJ_BOOT_DIR)/lib/endorsed/xalan-j2-serializer.jar && \ - ln -sf $(XERCES2_JAR) $(ECJ_BOOT_DIR)/lib/endorsed/xerces-j2.jar + ln -sf $(XERCES2_JAR) $(ECJ_BOOT_DIR)/lib/endorsed/xerces-j2.jar && \ + if test -n "$(XML_COMMONS_APIS_JAR)"; \ + then \ + ln -sf $(XML_COMMONS_APIS_JAR) \ + $(ECJ_BOOT_DIR)/lib/endorsed/xml-commons-apis.jar; \ + fi mkdir -p $(ECJ_BOOT_DIR)/jre/lib && \ cp $(SYSTEM_JDK_DIR)/jre/lib/rt.jar $(ECJ_BOOT_DIR)/jre/lib/rt.jar && \ ln -sf $(SYSTEM_JDK_DIR)/jre/lib/$(JRE_ARCH_DIR) \ @@ -1719,15 +1755,17 @@ stamps/pulse-java-headers.stamp: stamps/pulse-java-class.stamp mkdir -p $(PULSE_JAVA_NATIVE_BUILDDIR) $(BOOT_DIR)/bin/javah -d $(PULSE_JAVA_NATIVE_BUILDDIR) -classpath $(PULSE_JAVA_CLASS_DIR) \ - org.classpath.icedtea.pulseaudio.EventLoop ; \ + -J-Xbootclasspath/p:$(PULSE_JAVA_CLASS_DIR) org.classpath.icedtea.pulseaudio.EventLoop ; \ $(BOOT_DIR)/bin/javah -d $(PULSE_JAVA_NATIVE_BUILDDIR) -classpath $(PULSE_JAVA_CLASS_DIR) \ - org.classpath.icedtea.pulseaudio.Stream ; \ + -J-Xbootclasspath/p:$(PULSE_JAVA_CLASS_DIR) org.classpath.icedtea.pulseaudio.Stream ; \ + $(BOOT_DIR)/bin/javah -d $(PULSE_JAVA_NATIVE_BUILDDIR) -classpath $(PULSE_JAVA_CLASS_DIR) \ + -J-Xbootclasspath/p:$(PULSE_JAVA_CLASS_DIR) org.classpath.icedtea.pulseaudio.Operation; \ $(BOOT_DIR)/bin/javah -d $(PULSE_JAVA_NATIVE_BUILDDIR) -classpath $(PULSE_JAVA_CLASS_DIR) \ - org.classpath.icedtea.pulseaudio.Operation; \ + -J-Xbootclasspath/p:$(PULSE_JAVA_CLASS_DIR) org.classpath.icedtea.pulseaudio.PulseAudioSourcePort ; \ $(BOOT_DIR)/bin/javah -d $(PULSE_JAVA_NATIVE_BUILDDIR) -classpath $(PULSE_JAVA_CLASS_DIR) \ - org.classpath.icedtea.pulseaudio.PulseAudioSourcePort ; \ + -J-Xbootclasspath/p:$(PULSE_JAVA_CLASS_DIR) org.classpath.icedtea.pulseaudio.PulseAudioTargetPort ; \ $(BOOT_DIR)/bin/javah -d $(PULSE_JAVA_NATIVE_BUILDDIR) -classpath $(PULSE_JAVA_CLASS_DIR) \ - org.classpath.icedtea.pulseaudio.PulseAudioTargetPort ; \ + -J-Xbootclasspath/p:$(PULSE_JAVA_CLASS_DIR) org.classpath.icedtea.pulseaudio.ContextEvent; \ mkdir -p stamps touch stamps/pulse-java-headers.stamp @@ -1800,9 +1838,9 @@ $(MAKE) install mkdir -p $(abs_top_builddir)/jamvm/install/hotspot/jre/lib/$(INSTALL_ARCH_DIR)/server cp $(abs_top_builddir)/jamvm/install/lib/libjvm.so $(abs_top_builddir)/jamvm/install/hotspot/jre/lib/$(INSTALL_ARCH_DIR)/server - ln -s server $(abs_top_builddir)/jamvm/install/hotspot/jre/lib/$(INSTALL_ARCH_DIR)/client + ln -sf server $(abs_top_builddir)/jamvm/install/hotspot/jre/lib/$(INSTALL_ARCH_DIR)/client touch $(abs_top_builddir)/jamvm/install/hotspot/jre/lib/$(INSTALL_ARCH_DIR)/server/Xusage.txt - touch $(abs_top_builddir)/jamvm/install/hotspot/jre/lib/$(INSTALL_ARCH_DIR)/libjsig.so + ln -sf client/libjvm.so $(abs_top_builddir)/jamvm/install/hotspot/jre/lib/$(INSTALL_ARCH_DIR)/libjsig.so endif mkdir -p stamps touch $@
--- a/NEWS Wed Jun 01 02:35:43 2011 +0100 +++ b/NEWS Wed Jul 06 17:11:34 2011 +0100 @@ -30,10 +30,28 @@ - S7043054: REGRESSION - wrong userBounds in Paint.createContext() - S7043963, RH698295: Window manager workaround in AWT was not applied to mutter. Now it is. - S4685768: Focus set to disabled component, can't Tab/Shift-Tab + - S6769607, PR677: Modal frame hangs for a while. + - S6578583: Modality is broken in windows vista home premium from jdk1.7 b02 onwards. + - S6610244: modal dialog closes with fatal error if -Xcheck:jni is set + - S7037283, RH712211: Null Pointer Exception in SwingUtilities2. + - S7008106: com/sun/awt/Translucency/WindowOpacity.java test fails. + - S6956668: misbehavior of XOR operator (^) with int + - S6699843: IllegalArgumentException when using Graphics.drawString( "", 0, 0 ) + - S6918065: Crash in Java2D blit loop (IntArgbToIntArgbPreSrcOverMaskBlit) in 64bit mode + - S6623219: Font.canDisplayUpTo does not work with supplementary characters + - S6783910: java.awt.Color.brighter()/darker() methods make color opaque + - S6785424: SecurityException locating physical fonts on Windows Terminal Server + - S7047069: Array can dynamically change size when assigned to an object field + - S6796786: invalid FP identity transform - (a - b) -> b - a + - S7042070: Typo in Test6796786.java + - S7029152: Ideal nodes for String intrinsics miss memory edge optimization + - S6679308: Poor text rendering on translucent image * Bug fixes - PR637: make check should exit with an error code if any regression test failed. - G356743: Support libpng 1.5. - S7031385, PR680: Incorrect register allocation in orderAccess_linux_x86.inline.hpp + - PR748: Icedtea6 fails to build with Linux 3.0. + - PR744: icedtea6-1.10.2 : patching error * Allow selection of test suites using the jtreg_checks argument e.g. jtreg_checks="langtools" * CACAO - Threadlist & threadobject improvements. @@ -47,12 +65,25 @@ - CA156: uncaughtExceptionHandler doesn't work with OpenJDK 6 b21. - CA157: ARM SMP Assertion thinlock failed. * JamVM + - Make classlib init functions consistent + warnings. + - Correctly implement sun.misc.Unsafe freeMemory(). + - Move lazy-loading to init function. + - Fix various warnings with -Wall. + - PrintThreadsDump needs "self" as argument. + - CopyMemory, etc. handle negative or truncation in length. + - Extra sun.misc.Unsafe functions. + - Ignore options for jtreg tests. + - Enable shutdownVM to be called with OpenJDK classlib. + - Initial implementation of JVM_FindClassFromBootLoader. + - Fix callJNIMethod on i386 with -fomit-frame-pointer. + - Fix backwards cache conflict resolution code. + - Unify command line options parsing. + - Remove debug printf. - Fix leak of native thread structure. - Consistent naming for classlib functions. - Add extra includes to get rid off compiler warning. - Rework OpenJDK storage of native thread structure. - Implement remaining OpenJDK Array reflection interface. - - Ignore all unknown options. - Handle overflow in getPhysicalMemory(). - Base default min and max heap size on physical memory. - Fix reflective array access.
--- a/acinclude.m4 Wed Jun 01 02:35:43 2011 +0100 +++ b/acinclude.m4 Wed Jul 06 17:11:34 2011 +0100 @@ -238,8 +238,8 @@ if test "x${JAVA}" = "xno"; then JAVA=${JAVA_DEFAULT} fi - AC_MSG_CHECKING([if $JAVA is a valid executable]) - if test -x "${JAVA}"; then + AC_MSG_CHECKING([if $JAVA is a valid executable file]) + if test -x "${JAVA}" && test -f "${JAVA}"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -391,8 +391,8 @@ if test "x${JAVAH}" = "xno"; then JAVAH=${JAVAH_DEFAULT} fi - AC_MSG_CHECKING([if $JAVAH is a valid executable]) - if test -x "${JAVAH}"; then + AC_MSG_CHECKING([if $JAVAH is a valid executable file]) + if test -x "${JAVAH}" && test -f "${JAVAH}"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -428,8 +428,8 @@ if test "x${JAR}" = "xno"; then JAR=${JAR_DEFAULT} fi - AC_MSG_CHECKING([if $JAR is a valid executable]) - if test -x "${JAR}"; then + AC_MSG_CHECKING([if $JAR is a valid executable file]) + if test -x "${JAR}" && test -f "${JAR}"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -498,8 +498,8 @@ if test "x${RMIC}" = "xno"; then RMIC=${RMIC_DEFAULT} fi - AC_MSG_CHECKING([if $RMIC is a valid executable]) - if test -x "${RMIC}"; then + AC_MSG_CHECKING([if $RMIC is a valid executable file]) + if test -x "${RMIC}" && test -f "${RMIC}"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -535,8 +535,8 @@ if test "x${NATIVE2ASCII}" = "xno"; then NATIVE2ASCII=${NATIVE2ASCII_DEFAULT} fi - AC_MSG_CHECKING([if $NATIVE2ASCII is a valid executable]) - if test -x "${NATIVE2ASCII}"; then + AC_MSG_CHECKING([if $NATIVE2ASCII is a valid executable file]) + if test -x "${NATIVE2ASCII}" && test -f "${NATIVE2ASCII}"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -725,6 +725,43 @@ AC_SUBST(XERCES2_JAR) ]) +AC_DEFUN([IT_FIND_XML_COMMONS_APIS_JAR], +[ + AC_MSG_CHECKING([for an xml-commons-apis jar]) + AC_ARG_WITH([xml-commons-apis-jar], + [AS_HELP_STRING(--with-xml-commons-apis-jar,specify location of the xml-commons-apis jar)], + [ + if test -f "${withval}" || test -h "${withval}" ; then + XML_COMMONS_APIS_JAR="${withval}" + fi + ], + [ + XML_COMMONS_APIS_JAR= + ]) + if test -z "${XML_COMMONS_APIS_JAR}"; then + if test -e "/usr/share/java/xml-commons-apis.jar"; then + XML_COMMONS_APIS_JAR=/usr/share/java/xml-commons-apis.jar + elif test -e "/usr/share/java/xml-apis.jar"; then + XML_COMMONS_APIS_JAR=/usr/share/java/xml-apis.jar + elif test -e "/usr/share/xml-commons/lib/xml-apis.jar"; then + XML_COMMONS_APIS_JAR=/usr/share/xml-commons/lib/xml-apis.jar + elif test -e "/usr/share/java/xml-apis-ext.jar"; then + XML_COMMONS_APIS_JAR=/usr/share/java/xml-apis-ext.jar + elif test -e "/usr/share/java/xml-commons-external.jar"; then + XML_COMMONS_APIS_JAR=/usr/share/java/xml-commons-external.jar + elif test -e "/usr/share/java/apache-xml-commons-apis.jar"; then + XML_COMMONS_APIS_JAR=/usr/share/java/apache-xml-commons-apis.jar + else + AC_MSG_RESULT(no) + fi + fi + if test -z "${XML_COMMONS_APIS_JAR}"; then + AC_MSG_ERROR("An xml-commons-apis jar was not found.") + fi + AC_MSG_RESULT(${XML_COMMONS_APIS_JAR}) + AC_SUBST(XML_COMMONS_APIS_JAR) +]) + AC_DEFUN([IT_FIND_RHINO_JAR], [ AC_MSG_CHECKING([whether to include Javascript support via Rhino]) @@ -1374,6 +1411,62 @@ AC_PROVIDE([$0])dnl ]) +dnl Generic macro to instantiate a Java class +dnl Takes three arguments: the name of the macro, +dnl the name of the class and the instantiation +dnl paramaters. The macro name is usually the +dnl name of the class with '.' replaced by '_' +dnl and all letters capitalised. +dnl Also takes optional classpath paramater. +dnl e.g. IT_CHECK_FOR_INSTANTIABLE_CLASS([JAVA_LANG_INTEGER], +dnl [java.lang.Integer],[0],[./bin]) +AC_DEFUN([IT_CHECK_IF_INSTANTIABLE],[ +AC_CACHE_CHECK([if $2 is instantiable], it_cv_$1, [ +CLASS=Test.java +BYTECODE=$(echo $CLASS|sed 's#\.java##') +mkdir tmp.$$ +cd tmp.$$ +cat << \EOF > $CLASS +[/* [#]line __oline__ "configure" */ +public class Test +{ + public static void main(String[] args) + { + new $2($3); + } +} +] +EOF + +if test -z $4; then + WITH_CLASSPATH=. +else + WITH_CLASSPATH=$4:. +fi + +if $JAVAC -cp $WITH_CLASSPATH $JAVACFLAGS -nowarn $CLASS >&AS_MESSAGE_LOG_FD 2>&1; then + if $JAVA -classpath $WITH_CLASSPATH $BYTECODE >&AS_MESSAGE_LOG_FD 2>&1; then + it_cv_$1=yes; + else + it_cv_$1=no; + fi +else + it_cv_$1=no; +fi +]) +rm -f $CLASS *.class +cd .. +rmdir tmp.$$ + +if test x"${it_cv_$1}" = "xyes" +then + $1_INSTANTIABLE=yes +else + $1_INSTANTIABLE=no +fi +AC_PROVIDE([$0])dnl +]) + # Finds number of available processors using sysconf AC_DEFUN_ONCE([IT_FIND_NUMBER_OF_PROCESSORS],[ IT_FIND_TOOL([GETCONF], [getconf])
--- a/configure.ac Wed Jun 01 02:35:43 2011 +0100 +++ b/configure.ac Wed Jul 06 17:11:34 2011 +0100 @@ -159,6 +159,15 @@ IT_FIND_XALAN2_JAR IT_FIND_XALAN2_SERIALIZER_JAR IT_FIND_XERCES2_JAR + IT_CHECK_IF_INSTANTIABLE([ORG_APACHE_XERCES_DOM_DEFERREDDOCUMENTIMPL], +[org.apache.xerces.dom.DeferredDocumentImpl],[], +[$XALAN2_JAR:$XALAN2_SERIALIZER_JAR:$XERCES2_JAR]) + if test x"${ORG_APACHE_XERCES_DOM_DEFERREDDOCUMENTIMPL_INSTANTIABLE}" = "xno" + then + IT_FIND_XML_COMMONS_APIS_JAR + else + XML_COMMONS_APIS_JAR= + fi fi AC_CONFIG_FILES([javac], [chmod +x javac]) AC_CONFIG_FILES([javap], [chmod +x javap])
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi0g01.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi0g02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi0g04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi0g08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi2c16.pam has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi3p01.pam Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,7 @@ +P7 +WIDTH 32 +HEIGHT 32 +DEPTH 4 +MAXVAL 255 +ENDHDR +îÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ \ No newline at end of file
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi4a08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi4a16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi6a08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basi6a16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn0g01.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn0g02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn0g04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn0g08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn2c16.pam has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn3p01.pam Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,7 @@ +P7 +WIDTH 32 +HEIGHT 32 +DEPTH 4 +MAXVAL 255 +ENDHDR +îÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ"fÿÿ"fÿÿ"fÿÿ"fÿÿîÿ"ÿîÿ"ÿîÿ"ÿîÿ"ÿ \ No newline at end of file
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn4a08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn4a16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn6a08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/basn6a16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/bgai4a08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/bgai4a16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/bgan6a08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/bgan6a16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/bgbn4a08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/bggn4a16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/bgwn6a08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/bgyn6a16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ccwn2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ccwn3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cdfn2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cdhn2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cdsn2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cdun2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ch1n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ch2n3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cm0n0g04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cm7n0g04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cm9n0g04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cs3n2c16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cs3n3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cs5n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cs5n3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cs8n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/cs8n3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ct0n0g04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ct1n0g04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ctzn0g04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/f00n0g08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/f00n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/f01n0g08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/f01n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/f02n0g08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/f02n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/f03n0g08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/f03n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/f04n0g08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/f04n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g03n0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g03n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g03n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g04n0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g04n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g04n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g05n0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g05n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g05n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g07n0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g07n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g07n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g10n0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g10n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g10n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g25n0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g25n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/g25n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/oi1n0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/oi1n2c16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/oi2n0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/oi2n2c16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/oi4n0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/oi4n2c16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/oi9n0g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/oi9n2c16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/pngsuite_logo.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/pp0n2c16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/pp0n6a08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ps1n0g08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ps1n2c16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ps2n0g08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/ps2n2c16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s01i3p01.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s01n3p01.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s02i3p01.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s02n3p01.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s03i3p01.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s03n3p01.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s04i3p01.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s04n3p01.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s05i3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s05n3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s06i3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s06n3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s07i3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s07n3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s08i3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s08n3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s09i3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s09n3p02.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s32i3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s32n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s33i3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s33n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s34i3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s34n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s35i3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s35n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s36i3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s36n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s37i3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s37n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s38i3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s38n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s39i3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s39n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s40i3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/s40n3p04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tbbn1g04.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tbbn2c16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tbbn3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tbgn2c16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tbgn3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tbrn2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tbwn1g16.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tbwn3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tbyn3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tp0n1g08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tp0n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tp0n3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/tp1n3p08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/z00n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/z03n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/z06n2c08.pam has changed
Binary file overlays/openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pam_images/z09n2c08.pam has changed
--- a/patches/ecj/jaxws-getdtdtype.patch Wed Jun 01 02:35:43 2011 +0100 +++ b/patches/ecj/jaxws-getdtdtype.patch Wed Jul 06 17:11:34 2011 +0100 @@ -1,18 +1,18 @@ diff -Nru openjdk-ecj.orig/jaxws/build.properties openjdk-ecj/jaxws/build.properties ---- openjdk-ecj.orig/jaxws/build.properties 2010-03-01 15:13:38.000000000 +0000 -+++ openjdk-ecj/jaxws/build.properties 2010-03-01 15:14:30.000000000 +0000 +--- openjdk-ecj.orig/jaxws/build.properties 2011-06-29 23:08:21.756066418 +0100 ++++ openjdk-ecj/jaxws/build.properties 2011-06-29 23:09:51.701491292 +0100 @@ -81,7 +81,7 @@ patches.dir=patches # Patches to apply --jaxws_src.patch.list=xjc.patch -+jaxws_src.patch.list=xjc.patch getdtdtype.patch +-jaxws_src.patch.list=7013971.patch xjc.patch ++jaxws_src.patch.list=7013971.patch xjc.patch getdtdtype.patch # Sanity information sanity.info= Sanity Settings:${line.separator}\ diff -Nru openjdk-ecj.orig/jaxws/patches/jaxws_src/getdtdtype.patch openjdk-ecj/jaxws/patches/jaxws_src/getdtdtype.patch --- openjdk-ecj.orig/jaxws/patches/jaxws_src/getdtdtype.patch 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk-ecj/jaxws/patches/jaxws_src/getdtdtype.patch 2010-03-01 15:15:10.000000000 +0000 ++++ openjdk-ecj/jaxws/patches/jaxws_src/getdtdtype.patch 2011-06-29 23:09:34.609220483 +0100 @@ -0,0 +1,27 @@ +--- src/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXEventConnector.java 2009-11-17 16:37:06.000000000 +0000 ++++ src/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXEventConnector.java 2009-11-17 16:38:00.000000000 +0000
--- a/patches/f14-fonts.patch Wed Jun 01 02:35:43 2011 +0100 +++ b/patches/f14-fonts.patch Wed Jul 06 17:11:34 2011 +0100 @@ -8,7 +8,7 @@ + fontconfig.Fedora.10.properties \ + fontconfig.Fedora.11.properties \ + fontconfig.Fedora.12.properties \ - fontconfig.RedHat.6.0.properties \ + fontconfig.RedHat.6.properties \ fontconfig.Gentoo.properties else
--- a/patches/fonts-gentoo.patch Wed Jun 01 02:35:43 2011 +0100 +++ b/patches/fonts-gentoo.patch Wed Jul 06 17:11:34 2011 +0100 @@ -5,8 +5,8 @@ fontconfig.SuSE.properties \ fontconfig.Ubuntu.properties \ fontconfig.Fedora.properties \ -- fontconfig.RedHat.6.0.properties -+ fontconfig.RedHat.6.0.properties \ +- fontconfig.RedHat.6.properties ++ fontconfig.RedHat.6.properties \ + fontconfig.Gentoo.properties else
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/fonts-rhel-version.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,33 @@ +--- openjdk-orig/jdk/src/solaris/classes/sun/awt/motif/MFontConfiguration.java 2011-06-09 16:04:24.000000000 +0200 ++++ openjdk/jdk/src/solaris/classes/sun/awt/motif/MFontConfiguration.java 2011-06-09 16:04:24.000000000 +0200 +@@ -169,7 +169,9 @@ + osVersion = getVersionString(f); + } else if ((f = new File("/etc/redhat-release")).canRead()) { + osName = "RedHat"; +- osVersion = getVersionString(f); ++ // At this time we don't need to distinguish ++ // between RHEL 6.0 and RHEL 6.1 for example. ++ osVersion = getMajorVersionString(f); + } else if ((f = new File("/etc/turbolinux-release")).canRead()) { + osName = "Turbo"; + osVersion = getVersionString(f); +@@ -208,6 +210,19 @@ + return null; + } + ++ /** ++ * Gets the OS major version string from a Linux release-specific file. ++ */ ++ private String getMajorVersionString(File f){ ++ try { ++ Scanner sc = new Scanner(f); ++ return sc.findInLine("(\\d)+"); ++ } ++ catch (Exception e){ ++ } ++ return null; ++ } ++ + private static final String fontsDirPrefix = "$JRE_LIB_FONTS"; + + protected String mapFileName(String fileName) {
--- a/patches/fonts-rhel.patch Wed Jun 01 02:35:43 2011 +0100 +++ b/patches/fonts-rhel.patch Wed Jul 06 17:11:34 2011 +0100 @@ -7,12 +7,12 @@ fontconfig.Ubuntu.properties \ - fontconfig.Fedora.properties + fontconfig.Fedora.properties \ -+ fontconfig.RedHat.6.0.properties ++ fontconfig.RedHat.6.properties else FONTCONFIGS_SRC = $(CLOSED_SRC)/solaris/classes/sun/awt/fontconfigs --- /dev/null 2010-12-20 09:26:08.850062021 +0100 -+++ openjdk/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.RedHat.6.0.properties 2010-12-22 11:21:32.606781127 +0100 ++++ openjdk/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.RedHat.6.properties 2010-12-22 11:21:32.606781127 +0100 @@ -0,0 +1,441 @@ +# +# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
--- a/patches/jamvm/ignore-unknown-options.patch Wed Jun 01 02:35:43 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -Index: jamvm/jamvm/src/jni.c -=================================================================== ---- jamvm.orig/jamvm/src/jni.c 2011-02-27 04:35:37.000000000 +0100 -+++ jamvm/jamvm/src/jni.c 2011-03-03 13:48:31.897900208 +0100 -@@ -1642,7 +1642,7 @@ - /* Ignore */ - } else if(!vm_args->ignoreUnrecognized) { - optError(args, "Unrecognised option: %s\n", string); -- goto error; -+ /* Ignore */ - } - } -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/jtreg-ChangeDir.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,33 @@ +--- openjdk.orig/jdk/test/tools/jar/ChangeDir.java 2011-05-26 16:13:43.000000000 +0200 ++++ openjdk/jdk/test/tools/jar/ChangeDir.java 2011-05-27 10:59:45.000000000 +0200 +@@ -63,11 +63,14 @@ + + static void doTest(String sep) throws Throwable { + File testDir = null; ++ File parentDir = null; + JarFile jf = null; ++ File tempFile = null; + try { + // Create a subdirectory "a/b" +- File f = File.createTempFile("delete", ".me"); +- String dirName = f.getParent(); ++ tempFile = File.createTempFile("delete", ".me"); ++ String dirName = tempFile.getParent(); ++ parentDir = new File(dirName + sep + "a"); + testDir = new File(dirName + sep + "a" + sep + "b"); + cleanup(testDir); + check(testDir.mkdirs()); +@@ -109,6 +112,13 @@ + jf.close(); + } + cleanup(testDir); ++ // clean all garbage recently created in temporary directory ++ if (parentDir != null) { ++ parentDir.delete(); ++ } ++ if (tempFile != null) { ++ tempFile.delete(); ++ } + } + } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/jtreg-ChannelsWrite.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,51 @@ +--- openjdk.orig/jdk/test/java/nio/channels/Channels/Write.java 2011-02-28 17:06:59.000000000 +0100 ++++ openjdk/jdk/test/java/nio/channels/Channels/Write.java 2011-06-16 14:14:44.000000000 +0200 +@@ -34,18 +34,37 @@ + + public static void main(String[] args) throws Exception { + byte[] bb = new byte[3]; +- File testFile = File.createTempFile("test1", null); +- testFile.deleteOnExit(); ++ File testFile = null; ++ try { ++ testFile = File.createTempFile("test1", null); + +- FileOutputStream fos = new FileOutputStream(testFile); +- FileChannel fc = fos.getChannel(); +- OutputStream out = Channels.newOutputStream(fc); ++ FileOutputStream fos = null; ++ FileChannel fc = null; ++ OutputStream out = null; ++ try { ++ fos = new FileOutputStream(testFile); ++ fc = fos.getChannel(); ++ out = Channels.newOutputStream(fc); + +- out.write(bb,0,1); +- out.write(bb,2,1); +- +- out.close(); +- fc.close(); +- fos.close(); ++ out.write(bb,0,1); ++ out.write(bb,2,1); ++ } ++ finally { ++ if (out != null) { ++ out.close(); ++ } ++ if (fc != null) { ++ fc.close(); ++ } ++ if (fos != null) { ++ fos.close(); ++ } ++ } ++ } ++ finally { ++ if (testFile != null) { ++ testFile.delete(); ++ } ++ } + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/jtreg-EncodedMultiByteChar.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,24 @@ +--- openjdk.orig/jdk/test/sun/net/www/protocol/file/EncodedMultiByteChar.java 2011-02-28 17:07:06.000000000 +0100 ++++ openjdk/jdk/test/sun/net/www/protocol/file/EncodedMultiByteChar.java 2011-06-14 13:21:36.000000000 +0200 +@@ -61,6 +61,9 @@ + } catch (IOException e) { + System.out.println("Failed to create test file "); + e.printStackTrace(); ++ if (file != null) { ++ file.delete(); ++ } + return; + } + +@@ -81,5 +84,11 @@ + } catch (IOException ioe) { + ioe.printStackTrace(); + } ++ finally { ++ if (file != null) { ++ file.delete(); ++ } ++ } ++ System.out.println("test OK"); + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/jtreg-FileLoaderTest.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,36 @@ +--- openjdk.orig/jdk/test/sun/misc/URLClassPath/FileLoaderTest.java 2011-02-28 17:07:05.000000000 +0100 ++++ openjdk/jdk/test/sun/misc/URLClassPath/FileLoaderTest.java 2011-06-14 16:49:57.000000000 +0200 +@@ -31,16 +31,24 @@ + + public class FileLoaderTest { + public static void main (String args[]) throws Exception { +- File tempFile = File.createTempFile("foo", ".txt"); +- tempFile.deleteOnExit(); +- String basestr = tempFile.toURL().toString(); +- basestr = basestr.substring(0, basestr.lastIndexOf("/")+1); +- URL url = new URL(basestr+"."+"/"); ++ File tempFile = null; ++ try ++ { ++ tempFile = File.createTempFile("foo", ".txt"); ++ String basestr = tempFile.toURL().toString(); ++ basestr = basestr.substring(0, basestr.lastIndexOf("/")+1); ++ URL url = new URL(basestr+"."+"/"); + +- ClassLoader cl = new URLClassLoader (new URL[] { url }); +- if (cl.getResource (tempFile.getName()) == null) { +- throw new RuntimeException("Returned null instead of " + +- tempFile.toURL().toString()); ++ ClassLoader cl = new URLClassLoader (new URL[] { url }); ++ if (cl.getResource (tempFile.getName()) == null) { ++ throw new RuntimeException("Returned null instead of " + ++ tempFile.toURL().toString()); ++ } ++ } ++ finally { ++ if (tempFile != null) { ++ tempFile.delete(); ++ } + } + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/jtreg-FileMap.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,24 @@ +--- openjdk.orig/jdk/test/sun/net/www/protocol/file/FileMap.java 2011-02-28 17:07:06.000000000 +0100 ++++ openjdk/jdk/test/sun/net/www/protocol/file/FileMap.java 2011-06-16 11:30:19.000000000 +0200 +@@ -32,8 +32,9 @@ + + public class FileMap { + public static void main(String[] args) { ++ File f = null; + try { +- File f = File.createTempFile("test", null); ++ f = File.createTempFile("test", null); + f.deleteOnExit(); + String s = f.getAbsolutePath(); + s = s.startsWith("/") ? s : "/" + s; +@@ -48,5 +49,10 @@ + } catch (Exception ex) { + throw new RuntimeException("Unexpected exception: " + ex); + } ++ finally { ++ if ( f != null ) { ++ f.delete(); ++ } ++ } + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/jtreg-MappedByteBuffer-Basic.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,95 @@ +--- openjdk.orig/jdk/test/java/nio/MappedByteBuffer/Basic.java 2011-06-16 00:15:19.000000000 +0200 ++++ openjdk/jdk/test/java/nio/MappedByteBuffer/Basic.java 2011-06-16 16:13:50.000000000 +0200 +@@ -35,45 +35,56 @@ + byte[] srcData = new byte[20]; + for (int i=0; i<20; i++) + srcData[i] = 3; +- File blah = File.createTempFile("blah", null); +- blah.deleteOnExit(); +- FileOutputStream fos = new FileOutputStream(blah); +- FileChannel fc = fos.getChannel(); +- fc.write(ByteBuffer.wrap(srcData)); +- fc.close(); +- fos.close(); ++ File blah = null; ++ try { ++ blah = File.createTempFile("blah", null); ++ blah.deleteOnExit(); ++ FileOutputStream fos = new FileOutputStream(blah); ++ FileChannel fc = fos.getChannel(); ++ fc.write(ByteBuffer.wrap(srcData)); ++ fc.close(); ++ fos.close(); + +- FileInputStream fis = new FileInputStream(blah); +- fc = fis.getChannel(); +- MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, 10); +- mbb.load(); +- mbb.isLoaded(); +- mbb.force(); +- if (!mbb.isReadOnly()) +- throw new RuntimeException("Incorrect isReadOnly"); ++ FileInputStream fis = new FileInputStream(blah); ++ fc = fis.getChannel(); ++ MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, 10); ++ mbb.load(); ++ mbb.isLoaded(); ++ mbb.force(); ++ if (!mbb.isReadOnly()) { ++ throw new RuntimeException("Incorrect isReadOnly"); ++ } + +- // repeat with unaligned position in file +- mbb = fc.map(FileChannel.MapMode.READ_ONLY, 1, 10); +- mbb.load(); +- mbb.isLoaded(); +- mbb.force(); +- fc.close(); +- fis.close(); ++ // repeat with unaligned position in file ++ mbb = fc.map(FileChannel.MapMode.READ_ONLY, 1, 10); ++ mbb.load(); ++ mbb.isLoaded(); ++ mbb.force(); ++ fc.close(); ++ fis.close(); + +- RandomAccessFile raf = new RandomAccessFile(blah, "r"); +- fc = raf.getChannel(); +- mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, 10); +- if (!mbb.isReadOnly()) +- throw new RuntimeException("Incorrect isReadOnly"); +- fc.close(); +- raf.close(); ++ RandomAccessFile raf = new RandomAccessFile(blah, "r"); ++ fc = raf.getChannel(); ++ mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, 10); ++ if (!mbb.isReadOnly()) { ++ throw new RuntimeException("Incorrect isReadOnly"); ++ } ++ fc.close(); ++ raf.close(); + +- raf = new RandomAccessFile(blah, "rw"); +- fc = raf.getChannel(); +- mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 10); +- if (mbb.isReadOnly()) +- throw new RuntimeException("Incorrect isReadOnly"); +- fc.close(); +- raf.close(); ++ raf = new RandomAccessFile(blah, "rw"); ++ fc = raf.getChannel(); ++ mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 10); ++ if (mbb.isReadOnly()) { ++ throw new RuntimeException("Incorrect isReadOnly"); ++ } ++ fc.close(); ++ raf.close(); ++ } ++ finally { ++ if (blah != null) { ++ blah.delete(); ++ } ++ } + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/jtreg-ReadWriteProfileTest.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,124 @@ +diff -r 9318628e8eee -r 467e4f25965c test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java Fri Mar 20 20:05:22 2009 +0300 +@@ -0,0 +1,120 @@ ++/* ++ * Copyright 2007-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 6476665 6523403 6733501 ++ * @summary Verifies reading and writing profiles and tags of the standard color ++ * spaces ++ * @run main ReadWriteProfileTest ++ */ ++import java.awt.color.ColorSpace; ++import java.awt.color.ICC_Profile; ++import java.util.*; ++import java.nio.*; ++import java.util.Hashtable; ++ ++public class ReadWriteProfileTest implements Runnable { ++ /* Location of the tag sig counter in 4-byte words */ ++ final static int TAG_COUNT_OFFSET = 32; ++ ++ /* Location of the tag sig table in 4-byte words */ ++ final static int TAG_ELEM_OFFSET = 33; ++ ++ static byte[][] profiles; ++ static int [][] tagSigs; ++ static Hashtable<Integer,byte[]> [] tags; ++ ++ static int [] cspaces = {ColorSpace.CS_sRGB, ColorSpace.CS_PYCC, ++ ColorSpace.CS_LINEAR_RGB, ColorSpace.CS_CIEXYZ, ++ ColorSpace.CS_GRAY}; ++ ++ static String [] csNames = {"sRGB", "PYCC", "LINEAR_RGB", "CIEXYZ", "GRAY"}; ++ ++ static void getProfileTags(byte [] data, Hashtable tags) { ++ ByteBuffer byteBuf = ByteBuffer.wrap(data); ++ IntBuffer intBuf = byteBuf.asIntBuffer(); ++ int tagCount = intBuf.get(TAG_COUNT_OFFSET); ++ intBuf.position(TAG_ELEM_OFFSET); ++ for (int i = 0; i < tagCount; i++) { ++ int tagSig = intBuf.get(); ++ int tagDataOff = intBuf.get(); ++ int tagSize = intBuf.get(); ++ ++ byte [] tagData = new byte[tagSize]; ++ byteBuf.position(tagDataOff); ++ byteBuf.get(tagData); ++ tags.put(tagSig, tagData); ++ } ++ } ++ ++ static { ++ profiles = new byte[cspaces.length][]; ++ tags = new Hashtable[cspaces.length]; ++ ++ for (int i = 0; i < cspaces.length; i++) { ++ ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]); ++ profiles[i] = pf.getData(); ++ tags[i] = new Hashtable(); ++ getProfileTags(profiles[i], tags[i]); ++ } ++ } ++ ++ public void run() { ++ for (int i = 0; i < cspaces.length; i++) { ++ ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]); ++ byte [] data = pf.getData(); ++ pf = ICC_Profile.getInstance(data); ++ if (!Arrays.equals(data, profiles[i])) { ++ System.err.println("Incorrect result of getData() " + "with " + ++ csNames[i] + " profile"); ++ throw new RuntimeException("Incorrect result of getData()"); ++ } ++ ++ for (int tagSig : tags[i].keySet()) { ++ byte [] tagData = pf.getData(tagSig); ++ byte [] empty = new byte[tagData.length]; ++ pf.setData(tagSig, empty); ++ pf.setData(tagSig, tagData); ++ ++ byte [] tagData1 = pf.getData(tagSig); ++ ++ if (!Arrays.equals(tagData1, tags[i].get(tagSig))) ++ { ++ System.err.println("Incorrect result of getData(int) with" + ++ " tag " + ++ Integer.toHexString(tagSig) + ++ " of " + csNames[i] + " profile"); ++ ++ throw new RuntimeException("Incorrect result of " + ++ "getData(int)"); ++ } ++ } ++ } ++ } ++ ++ public static void main(String [] args) { ++ ReadWriteProfileTest test = new ReadWriteProfileTest(); ++ test.run(); ++ } ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/jtreg-TempBuffer.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,61 @@ +--- openjdk.orig/jdk/test/sun/nio/ch/TempBuffer_orig.java 2011-02-28 17:07:06.000000000 +0100 ++++ openjdk/jdk/test/sun/nio/ch/TempBuffer.java 2011-06-13 15:10:29.000000000 +0200 +@@ -48,18 +48,29 @@ + + Thread writerThread = new Thread() { + public void run() { ++ File blah = null; + try { + OutputStream out = Channels.newOutputStream(sinkChannel); +- File blah = File.createTempFile("blah1", null); ++ blah = File.createTempFile("blah1", null); + blah.deleteOnExit(); + TempBuffer.initTestFile(blah); + RandomAccessFile raf = new RandomAccessFile(blah, "rw"); + FileChannel fs = raf.getChannel(); +- fs.transferTo(0, SIZE, Channels.newChannel(out)); ++ try { ++ fs.transferTo(0, SIZE, Channels.newChannel(out)); ++ } finally { ++ fs.close(); ++ raf.close(); ++ } + out.flush(); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } ++ finally { ++ if (blah != null) { ++ blah.delete(); ++ } ++ } + } + }; + +@@ -70,9 +81,16 @@ + blah.deleteOnExit(); + RandomAccessFile raf = new RandomAccessFile(blah, "rw"); + FileChannel fs = raf.getChannel(); +- raf.setLength(SIZE); +- fs.transferFrom(Channels.newChannel(in), 0, SIZE); +- fs.close(); ++ try { ++ raf.setLength(SIZE); ++ fs.transferFrom(Channels.newChannel(in), 0, SIZE); ++ } finally { ++ fs.close(); ++ } ++ ++ sourceChannel.close(); ++ sinkChannel.close(); ++ blah.delete(); + } + + private static void initTestFile(File blah) throws IOException { +@@ -89,5 +107,6 @@ + } + awriter.flush(); + awriter.close(); ++ fos.close(); + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/jtreg-bug7036148-test.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,24 @@ +diff -r e7493c32e598 test/javax/swing/JMenuItem/7036148/bug7036148.java +--- openjdk.orig/jdk/test/javax/swing/JMenuItem/7036148/bug7036148.java Wed Jun 08 10:24:10 2011 -0700 ++++ openjdk/jdk/test/javax/swing/JMenuItem/7036148/bug7036148.java Wed Jun 15 14:25:59 2011 -0400 +@@ -44,10 +44,16 @@ + menu.add(new JMenuItem("test")); + bar.add(menu); + setJMenuBar(bar); +- pack(); + } + +- public static void main(String[] args) { +- new bug7036148(); +- } ++ public static void main(String[] args) { ++ // if the bug is present, an NPE will be thrown on pack() above. ++ JFrame f = new bug7036148(); ++ ++ try { ++ f.pack(); ++ } finally { ++ f.dispose(); ++ } ++ } + }
--- a/patches/jtreg-png-reader.patch Wed Jun 01 02:35:43 2011 +0100 +++ b/patches/jtreg-png-reader.patch Wed Jul 06 17:11:34 2011 +0100 @@ -1,7 +1,7 @@ diff -Nu old/AbstractImageProcessor.java PngReader/AbstractImageProcessor.java --- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/AbstractImageProcessor.java 2011-01-31 13:59:40.976990000 +0100 -@@ -0,0 +1,316 @@ ++++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/AbstractImageProcessor.java 2011-06-21 11:46:22.000000000 +0200 +@@ -0,0 +1,321 @@ +/* + * Copyright 2011 Red Hat, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -190,7 +190,7 @@ + * @param fileName + * @return text containing basic info about image + */ -+ private String getImageInfoFromFileName(String fileName) { ++ protected String getImageInfoFromFileName(String fileName) { + String testType = resolveTestType(fileName.substring(0, 3)); + String interlaced = resolveInterlaced(fileName.charAt(3)); + String colorType = fileName.substring(4, 6); @@ -271,6 +271,12 @@ + return ch == 'i' ? "interlaced" : "non-interlaced"; + } + ++ protected String[] getSortedImageNames(File imageDir) { ++ String[] imageNames = imageDir.list(); ++ Arrays.sort(imageNames); ++ return imageNames; ++ } ++ + /** + * This method tries to read all images from given directory and then + * check if no exception is thrown (expectException==false) or if @@ -282,8 +288,7 @@ + */ + protected void run(String imageDirectoryName, boolean expectException) { + File imageDir = new File(System.getProperty("test.src", "."), imageDirectoryName); -+ String[] imageNames = imageDir.list(); -+ Arrays.sort(imageNames); ++ String[] imageNames = getSortedImageNames(imageDir); + int errors = 0; + for (String imageName : imageNames) { + File imageFile = new File(imageDir, imageName); @@ -320,7 +325,7 @@ +} diff -Nu old/BrokenPngImageProcessor.java PngReader/BrokenPngImageProcessor.java --- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/BrokenPngImageProcessor.java 2011-01-31 13:59:40.976990000 +0100 ++++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/BrokenPngImageProcessor.java 2011-01-28 17:47:13.000000000 +0100 @@ -0,0 +1,36 @@ +/* + * Copyright 2011 Red Hat, Inc. All Rights Reserved. @@ -360,7 +365,7 @@ +} diff -Nu old/GoodPngImageProcessor.java PngReader/GoodPngImageProcessor.java --- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/GoodPngImageProcessor.java 2011-01-31 13:59:40.976990000 +0100 ++++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/GoodPngImageProcessor.java 2011-01-28 17:47:17.000000000 +0100 @@ -0,0 +1,36 @@ +/* + * Copyright 2011 Red Hat, Inc. All Rights Reserved. @@ -398,9 +403,341 @@ + new GoodPngImageProcessor().run(IMAGE_DIR, EXPECT_EXCEPTION); + } +} -diff -Nu old/ImageReadException.java PngReader/ImageReadException.java ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/ImageReadException.java 2011-01-31 13:59:40.976990000 +0100 +--- /dev/null 2011-03-28 09:47:44.855266162 +0200 ++++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/ImageCompareException.java 2011-06-21 11:32:11.000000000 +0200 +@@ -0,0 +1,51 @@ ++/* ++ * Copyright 2011 Red Hat, 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. ++ */ ++ ++public class ImageCompareException extends Exception { ++ /** ++ * Generated serial version UID. ++ */ ++ private static final long serialVersionUID = -8857533785949817059L; ++ ++ private int x; ++ private int y; ++ private int r1; ++ private int g1; ++ private int b1; ++ private int r2; ++ private int g2; ++ private int b2; ++ ++ public ImageCompareException(int x, int y, int r1, int g1, int b1, int r2, int g2, int b2) { ++ this.x = x; ++ this.y = y; ++ this.r1 = r1; ++ this.g1 = g1; ++ this.b1 = b1; ++ this.r2 = r2; ++ this.g2 = g2; ++ this.b2 = b2; ++ } ++ ++ @SuppressWarnings({ "boxing", "unqualified-field-access" }) ++ @Override ++ public String toString() { ++ return String.format("pixel [%d,%d] values differ: (%d, %d, %d) <> (%d, %d, %d)\n", x, y, r1, g1, b1, r2, g2, b2); ++ } ++} +--- /dev/null 2011-03-28 09:47:44.855266162 +0200 ++++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/ImageReaderAndComparator.java 2011-06-21 11:48:38.123378000 +0200 +@@ -0,0 +1,276 @@ ++/* ++ * Copyright 2011 Red Hat, 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. ++ */ ++ ++import java.awt.image.BufferedImage; ++import java.io.BufferedInputStream; ++import java.io.DataInputStream; ++import java.io.File; ++import java.io.FileInputStream; ++import java.io.IOException; ++ ++/** ++ * @test ++ * @summary This test check if the PNG images read by ImageIO system ++ * has proper pixel values. Read images are checked against ++ * corresponding PAM images generated by external tool. ++ * This test are able to work with: ++ * - grayscale images with 1 byte color depth (256 grayscales) ++ * - grayscale images with 2 bytes color depth (65536 grayscales) ++ * - RGB images with 1 byte color depth/color component (2^24 colors) ++ * - RGB images with 2 bytes color depth/color component (2^48 colors) ++ * ++ * @author Pavel Tisnovsky ++ * ++ */ ++public class ImageReaderAndComparator extends AbstractImageProcessor { ++ ++ /** ++ * Directory containing tested PNG images. ++ */ ++ private static final String PNG_IMAGE_DIR = "good_images"; ++ ++ /** ++ * Directory containing corresponding PAM images. ++ */ ++ private static final String PAM_IMAGE_DIR = "pam_images"; ++ ++ /** ++ * Maximum allowable difference between color values of corresponding pixels. ++ */ ++ private static int MAX_COLOR_COMPONENT_DIFF = 1; ++ ++ /** ++ * Parse integer value from PAM file. ++ */ ++ @SuppressWarnings("deprecation") ++ private int readIntegerFromPam(String attributeName, String fileName, DataInputStream input, int lineNumber) ++ throws IOException, PamImageReadException { ++ String line; ++ line = input.readLine(); ++ if (!line.startsWith(attributeName)) { ++ throw new PamImageReadException(fileName, lineNumber); ++ } ++ return Integer.parseInt(line.substring(line.indexOf(' ') + 1)); ++ } ++ ++ /** ++ * Linear to sRGB conversion ++ * @param Clinear color value in linear RGB color space ++ * @return color value in sRGB color space ++ */ ++ private double linear2srgb(double Clinear) ++ { ++ double alpha = 0.055; ++ return (Clinear <= 0.0031308) ? 12.92 * Clinear : (1. + alpha) * Math.pow(Clinear, 1 / 2.4) - alpha; ++ } ++ ++ /** ++ * Read PAM image ++ * @param imageFile file containing image in PAM format ++ * @return raster image ++ * @throws IOException ++ * @throws PamImageReadException ++ */ ++ @SuppressWarnings({ "deprecation", "boxing" }) ++ private BufferedImage readPamImage(File imageFile) throws IOException, PamImageReadException { ++ // PAM image header format: ++ // P7 ++ // WIDTH 32 ++ // HEIGHT 32 ++ // DEPTH 1 ++ // MAXVAL 1 ++ // ENDHDR ++ String fileName = imageFile.getName(); ++ DataInputStream input = new DataInputStream(new BufferedInputStream(new FileInputStream(imageFile))); ++ int lineNumber = 1; ++ String line; ++ ++ // check first line of PAM image ++ line = input.readLine(); ++ if (! "P7".equals(line)) { ++ throw new PamImageReadException(fileName, lineNumber); ++ } ++ ++ lineNumber++; ++ int width = readIntegerFromPam("WIDTH", fileName, input, lineNumber); ++ lineNumber++; ++ int height = readIntegerFromPam("HEIGHT", fileName, input, lineNumber); ++ lineNumber++; ++ int depth = readIntegerFromPam("DEPTH", fileName, input, lineNumber); ++ lineNumber++; ++ int maxval = readIntegerFromPam("MAXVAL", fileName, input, lineNumber); ++ ++ input.readLine(); // ENDHDR ++ System.out.format("width: %d, height: %d, depth: %d, maxval: %d\n", width, height, depth, maxval); ++ ++ BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); ++ for (int y = 0; y < height; y++) { ++ for (int x = 0; x < width; x++) { ++ int rgb; ++ switch (depth) { ++ case 1: ++ int grayLevel = readOneColorComponent(maxval, input, true); ++ rgb = (grayLevel << 16) + (grayLevel << 8) + grayLevel; ++ img.setRGB(x, y, rgb); ++ break; ++ case 4: ++ int r = readOneColorComponent(maxval, input, false); ++ int g = readOneColorComponent(maxval, input, false); ++ int b = readOneColorComponent(maxval, input, false); ++ // ignore alpha channel for the moment ++ input.readUnsignedByte(); ++ if (maxval == 65535) { ++ input.readUnsignedByte(); ++ } ++ rgb = (r << 16) + (g << 8) + b; ++ img.setRGB(x, y, rgb); ++ break; ++ default: ++ throw new PamImageReadException("unknown color depth"); ++ } ++ } ++ } ++ return img; ++ } ++ ++ /** ++ * Read one color component from PAM file ++ * @param maxval ++ * @param input ++ * @param convertToSRGB ++ * @return ++ * @throws IOException ++ */ ++ private int readOneColorComponent(int maxval, DataInputStream input, boolean convertToSRGB) throws IOException { ++ int i = input.readUnsignedByte(); ++ if (maxval == 65535) { ++ int i2 = input.readUnsignedByte(); ++ double c = (double) ((i << 8) + i2) / maxval; ++ if (convertToSRGB) { ++ c = linear2srgb(c); ++ } ++ i = (int) (c * 255.0); ++ } ++ else if (maxval == 255) { ++ double c = (double) i / maxval; ++ if (convertToSRGB) { ++ c = linear2srgb(c); ++ } ++ i = (int) (c * 255.0); ++ } ++ else { ++ i = i * 255 / maxval; ++ } ++ return i; ++ } ++ ++ /** ++ * Compare two images ++ * @param img1 ++ * @param img2 ++ * @throws Exception ++ */ ++ private void compareImages(BufferedImage img1, BufferedImage img2) throws Exception { ++ if (img1 == null || img2 == null) { ++ throw new Exception("at least one image can not be read"); ++ } ++ if (img1.getWidth() != img2.getWidth() || img1.getHeight() != img2.getHeight()) { ++ throw new Exception("image size differs"); ++ } ++ System.out.println(); ++ for (int y = 0; y < img1.getHeight(); y++) { ++ for (int x = 0; x < img1.getWidth(); x++) { ++ int rgb1 = img1.getRGB(x, y); ++ int rgb2 = img2.getRGB(x, y); ++ ++ int r1 = rgb1 & 0xff; ++ int b1 = (rgb1 >> 8) & 0xff; ++ int g1 = (rgb1 >> 16) & 0xff; ++ ++ int r2 = rgb2 & 0xff; ++ int b2 = (rgb2 >> 8) & 0xff; ++ int g2 = (rgb2 >> 16) & 0xff; ++ ++ if (Math.abs(r1 - r2) > MAX_COLOR_COMPONENT_DIFF || Math.abs(g1 - g2) > MAX_COLOR_COMPONENT_DIFF || Math.abs(b1 - b2) > MAX_COLOR_COMPONENT_DIFF ) { ++ throw new ImageCompareException(x, y, r1, g1, b1, r2, g2, b2); ++ } ++ } ++ } ++ System.out.println("OK - images are the same"); ++ } ++ ++ /** ++ * Run the test ++ */ ++ private void run() { ++ File pngImageDir = new File(System.getProperty("test.src", "."), PNG_IMAGE_DIR); ++ File pamImageDir = new File(System.getProperty("test.src", "."), PAM_IMAGE_DIR); ++ String[] imageNames = getSortedImageNames(pngImageDir); ++ int errors = 0; ++ int comparingOk = 0; ++ int comparingErrors = 0; ++ for (String imageName : imageNames) { ++ File imageFile1 = new File(pngImageDir, imageName); ++ File imageFile2 = new File(pamImageDir, imageName.replace(".png", ".pam")); ++ System.out.println("\nChecking images: " + imageFile1.getAbsolutePath() + " and " ++ + imageFile2.getAbsolutePath()); ++ //System.out.println(getImageInfoFromFileName(imageName)); ++ try { ++ BufferedImage img1 = readBufferedImage(imageFile1); ++ BufferedImage img2 = readPamImage(imageFile2); ++ try { ++ compareImages(img1, img2); ++ comparingOk++; ++ } ++ catch (ImageCompareException e) { ++ comparingErrors++; ++ e.printStackTrace(); ++ } ++ catch (Exception e) { ++ comparingErrors++; ++ e.printStackTrace(); ++ } ++ } ++ catch (ImageReadException e) { ++ errors++; ++ e.printStackTrace(); ++ } ++ catch (IOException e) { ++ errors++; ++ e.printStackTrace(); ++ } ++ catch (PamImageReadException e) { ++ errors++; ++ e.printStackTrace(); ++ } ++ } ++ if (comparingErrors > 0) { ++ throw new RuntimeException("Catch " + comparingErrors + " comparison failures"); ++ } ++ if (errors > 0) { ++ throw new RuntimeException("Error processing " + errors + " images"); ++ } ++ System.out.format("Sucessfuly compared %d images!\n", Integer.valueOf(comparingOk)); ++ } ++ ++ public static void main(String args[]) { ++ new ImageReaderAndComparator().run(); ++ } ++ ++} +--- /dev/null 2011-03-28 09:47:44.855266162 +0200 ++++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/ImageReadException.java 2011-01-28 17:47:22.000000000 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright 2011 Red Hat, Inc. All Rights Reserved. @@ -450,9 +787,68 @@ + } + +} -diff -Nu old/pngsuite.doc PngReader/pngsuite.doc ---- /dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pngsuite.doc 2011-01-31 13:59:40.976990000 +0100 +--- /dev/null 2011-03-28 09:47:44.855266162 +0200 ++++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/PamImageReadException.java 2011-06-21 11:32:23.000000000 +0200 +@@ -0,0 +1,57 @@ ++/* ++ * Copyright 2011 Red Hat, 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. ++ */ ++ ++public class PamImageReadException extends Exception { ++ ++ private String message = ""; ++ private String fileName = ""; ++ private int lineNumber = 0; ++ ++ /** ++ * Generated serial version UID ++ */ ++ private static final long serialVersionUID = -1324117718127778562L; ++ ++ public PamImageReadException(String fileName, int lineNumber) { ++ this.setFileName(fileName); ++ this.setLineNumber(lineNumber); ++ } ++ ++ public PamImageReadException(String message) { ++ this.setMessage(message); ++ } ++ ++ private void setMessage(String message) { ++ this.message = message; ++ } ++ ++ private void setFileName(String fileName) { ++ this.fileName = fileName; ++ } ++ ++ private void setLineNumber(int lineNumber) { ++ this.lineNumber = lineNumber; ++ } ++ ++ @Override ++ public String getMessage() { ++ return "Error reading file " + this.fileName + " on line " + this.lineNumber + " message: " + this.message; ++ } ++ ++} +--- /dev/null 2011-03-28 09:47:44.855266162 +0200 ++++ openjdk/jdk/test/javax/imageio/plugins/png/PngReader/pngsuite.doc 1998-04-05 17:02:03.000000000 +0200 @@ -0,0 +1,520 @@ + PNGSUITE +----------------
--- a/patches/nio2.patch Wed Jun 01 02:35:43 2011 +0100 +++ b/patches/nio2.patch Wed Jul 06 17:11:34 2011 +0100 @@ -1,6 +1,6 @@ diff -Nru openjdk.orig/jdk/make/common/shared/Defs-javadoc.gmk openjdk/jdk/make/common/shared/Defs-javadoc.gmk ---- openjdk.orig/jdk/make/common/shared/Defs-javadoc.gmk 2010-06-21 22:15:08.000000000 +0100 -+++ openjdk/jdk/make/common/shared/Defs-javadoc.gmk 2011-02-08 23:10:59.370265518 +0000 +--- openjdk.orig/jdk/make/common/shared/Defs-javadoc.gmk 2011-02-28 16:06:10.000000000 +0000 ++++ openjdk/jdk/make/common/shared/Defs-javadoc.gmk 2011-05-23 23:20:58.640622650 +0100 @@ -41,6 +41,7 @@ TREEAPI_FIRST_COPYRIGHT_YEAR = 2005 JNLP_FIRST_COPYRIGHT_YEAR = 1998 @@ -10,8 +10,8 @@ # Oracle name COMPANY_NAME = Oracle and/or its affiliates diff -Nru openjdk.orig/jdk/make/docs/CORE_PKGS.gmk openjdk/jdk/make/docs/CORE_PKGS.gmk ---- openjdk.orig/jdk/make/docs/CORE_PKGS.gmk 2010-06-21 22:15:08.000000000 +0100 -+++ openjdk/jdk/make/docs/CORE_PKGS.gmk 2011-02-08 23:10:59.374265560 +0000 +--- openjdk.orig/jdk/make/docs/CORE_PKGS.gmk 2011-02-28 16:06:10.000000000 +0000 ++++ openjdk/jdk/make/docs/CORE_PKGS.gmk 2011-05-23 23:20:58.656622907 +0100 @@ -36,6 +36,7 @@ sunw.* \ com.sun.* \ @@ -21,8 +21,8 @@ org.w3c.dom.css \ org.w3c.dom.html \ diff -Nru openjdk.orig/jdk/make/docs/Makefile openjdk/jdk/make/docs/Makefile ---- openjdk.orig/jdk/make/docs/Makefile 2010-06-21 22:15:08.000000000 +0100 -+++ openjdk/jdk/make/docs/Makefile 2011-02-08 23:10:59.374265560 +0000 +--- openjdk.orig/jdk/make/docs/Makefile 2011-02-28 16:06:10.000000000 +0000 ++++ openjdk/jdk/make/docs/Makefile 2011-05-23 23:20:58.656622907 +0100 @@ -1076,6 +1076,58 @@ ############################################################# @@ -83,8 +83,8 @@ $(DIRECTORY_CACHE): $(ALL_SOURCE_DIRS) diff -Nru openjdk.orig/jdk/make/docs/NON_CORE_PKGS.gmk openjdk/jdk/make/docs/NON_CORE_PKGS.gmk ---- openjdk.orig/jdk/make/docs/NON_CORE_PKGS.gmk 2011-02-08 22:57:19.000000000 +0000 -+++ openjdk/jdk/make/docs/NON_CORE_PKGS.gmk 2011-02-08 23:10:59.374265560 +0000 +--- openjdk.orig/jdk/make/docs/NON_CORE_PKGS.gmk 2011-02-28 16:06:10.000000000 +0000 ++++ openjdk/jdk/make/docs/NON_CORE_PKGS.gmk 2011-05-23 23:20:58.656622907 +0100 @@ -65,6 +65,16 @@ HTTPSERVER_PKGS = com.sun.net.httpserver \ com.sun.net.httpserver.spi @@ -102,17 +102,17 @@ DOCLETAPI_PKGS = com.sun.javadoc TAGLETAPI_FILE = com/sun/tools/doclets/Taglet.java -@@ -93,6 +103,7 @@ +@@ -89,6 +99,7 @@ $(MGMT_PKGS) \ $(JAAS_PKGS) \ $(JGSS_PKGS) \ + $(NIO2_PKGS) \ $(OLD_JSSE_PKGS) \ $(HTTPSERVER_PKGS) \ - $(SMARTCARDIO_PKGS) \ + $(SMARTCARDIO_PKGS) diff -Nru openjdk.orig/jdk/make/java/java/FILES_java.gmk openjdk/jdk/make/java/java/FILES_java.gmk ---- openjdk.orig/jdk/make/java/java/FILES_java.gmk 2011-02-08 22:57:17.000000000 +0000 -+++ openjdk/jdk/make/java/java/FILES_java.gmk 2011-02-08 23:10:59.374265560 +0000 +--- openjdk.orig/jdk/make/java/java/FILES_java.gmk 2011-05-23 23:03:36.000000000 +0100 ++++ openjdk/jdk/make/java/java/FILES_java.gmk 2011-05-23 23:20:58.656622907 +0100 @@ -518,6 +518,13 @@ sun/misc/JavaLangAccess.java \ sun/misc/JavaIOAccess.java \ @@ -129,8 +129,8 @@ FILES_java = $(JAVA_JAVA_java) diff -Nru openjdk.orig/jdk/make/java/nio/FILES_java.gmk openjdk/jdk/make/java/nio/FILES_java.gmk ---- openjdk.orig/jdk/make/java/nio/FILES_java.gmk 2011-02-08 22:57:17.000000000 +0000 -+++ openjdk/jdk/make/java/nio/FILES_java.gmk 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/make/java/nio/FILES_java.gmk 2011-05-23 23:03:36.000000000 +0100 ++++ openjdk/jdk/make/java/nio/FILES_java.gmk 2011-05-23 23:20:58.656622907 +0100 @@ -75,12 +75,13 @@ sun/nio/ch/DefaultSelectorProvider.java \ sun/nio/ch/DirectBuffer.java \ @@ -330,8 +330,8 @@ FILES_java = $(FILES_src) $(FILES_gen) diff -Nru openjdk.orig/jdk/make/java/nio/Makefile openjdk/jdk/make/java/nio/Makefile ---- openjdk.orig/jdk/make/java/nio/Makefile 2011-02-08 22:57:17.000000000 +0000 -+++ openjdk/jdk/make/java/nio/Makefile 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/make/java/nio/Makefile 2011-05-23 23:03:36.000000000 +0100 ++++ openjdk/jdk/make/java/nio/Makefile 2011-05-23 23:20:58.656622907 +0100 @@ -40,6 +40,11 @@ SNIO_SRC = $(SHARE_SRC)/classes/sun/nio SNIO_GEN = $(GENSRCDIR)/sun/nio @@ -678,8 +678,8 @@ + .PHONY: sources diff -Nru openjdk.orig/jdk/make/java/nio/mapfile-linux openjdk/jdk/make/java/nio/mapfile-linux ---- openjdk.orig/jdk/make/java/nio/mapfile-linux 2010-06-21 22:15:08.000000000 +0100 -+++ openjdk/jdk/make/java/nio/mapfile-linux 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/make/java/nio/mapfile-linux 2011-02-28 16:06:11.000000000 +0000 ++++ openjdk/jdk/make/java/nio/mapfile-linux 2011-05-23 23:20:58.656622907 +0100 @@ -20,6 +20,14 @@ Java_sun_nio_ch_EPollArrayWrapper_interrupt; Java_sun_nio_ch_EPollArrayWrapper_offsetofData; @@ -796,8 +796,8 @@ local: *; diff -Nru openjdk.orig/jdk/make/java/nio/mapfile-solaris openjdk/jdk/make/java/nio/mapfile-solaris ---- openjdk.orig/jdk/make/java/nio/mapfile-solaris 2010-06-21 22:15:08.000000000 +0100 -+++ openjdk/jdk/make/java/nio/mapfile-solaris 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/make/java/nio/mapfile-solaris 2011-02-28 16:06:11.000000000 +0000 ++++ openjdk/jdk/make/java/nio/mapfile-solaris 2011-05-23 23:20:58.656622907 +0100 @@ -73,6 +73,75 @@ Java_sun_nio_ch_ServerSocketChannelImpl_listen; Java_sun_nio_ch_SocketChannelImpl_checkConnect; @@ -875,8 +875,8 @@ local: *; diff -Nru openjdk.orig/jdk/make/mkdemo/Makefile openjdk/jdk/make/mkdemo/Makefile ---- openjdk.orig/jdk/make/mkdemo/Makefile 2010-06-21 22:15:08.000000000 +0100 -+++ openjdk/jdk/make/mkdemo/Makefile 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/make/mkdemo/Makefile 2011-02-28 16:06:11.000000000 +0000 ++++ openjdk/jdk/make/mkdemo/Makefile 2011-05-23 23:20:58.656622907 +0100 @@ -31,7 +31,7 @@ PRODUCT = demos include $(BUILDDIR)/common/Defs.gmk @@ -887,8 +887,8 @@ all build:: nbproject $(SUBDIRS-loop) diff -Nru openjdk.orig/jdk/make/mksample/nio/Makefile openjdk/jdk/make/mksample/nio/Makefile ---- openjdk.orig/jdk/make/mksample/nio/Makefile 2010-06-21 22:15:08.000000000 +0100 -+++ openjdk/jdk/make/mksample/nio/Makefile 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/make/mksample/nio/Makefile 2011-02-28 16:06:11.000000000 +0000 ++++ openjdk/jdk/make/mksample/nio/Makefile 2011-05-23 23:20:58.656622907 +0100 @@ -31,7 +31,7 @@ PRODUCT = java include $(BUILDDIR)/common/Defs.gmk @@ -899,8 +899,8 @@ $(SUBDIRS-loop) diff -Nru openjdk.orig/jdk/src/share/classes/java/io/File.java openjdk/jdk/src/share/classes/java/io/File.java ---- openjdk.orig/jdk/src/share/classes/java/io/File.java 2010-06-21 22:15:18.000000000 +0100 -+++ openjdk/jdk/src/share/classes/java/io/File.java 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/src/share/classes/java/io/File.java 2011-02-28 16:06:21.000000000 +0000 ++++ openjdk/jdk/src/share/classes/java/io/File.java 2011-05-23 23:20:58.660622971 +0100 @@ -1958,6 +1958,13 @@ } } @@ -916,27 +916,28 @@ diff -Nru openjdk.orig/jdk/src/share/classes/java/net/NetworkInterface.java openjdk/jdk/src/share/classes/java/net/NetworkInterface.java ---- openjdk.orig/jdk/src/share/classes/java/net/NetworkInterface.java 2011-02-08 22:57:12.000000000 +0000 -+++ openjdk/jdk/src/share/classes/java/net/NetworkInterface.java 2011-02-08 23:10:59.378265602 +0000 -@@ -536,4 +536,15 @@ +--- openjdk.orig/jdk/src/share/classes/java/net/NetworkInterface.java 2011-05-23 23:03:33.000000000 +0100 ++++ openjdk/jdk/src/share/classes/java/net/NetworkInterface.java 2011-05-23 23:21:33.029175274 +0100 +@@ -531,4 +531,16 @@ } + private static native void init(); - ++ + // Set up JavaIODeleteOnExitAccess in SharedSecrets + // Added here as getIndex is package-private and SharedSecrets cannot easily access it. + static { -+ org.classpath.icedtea.misc.SharedSecrets.setJavaNetGetIndexAccess( ++ org.classpath.icedtea.misc.SharedSecrets.setJavaNetGetIndexAccess( + new org.classpath.icedtea.misc.JavaNetGetIndexAccess() { -+ public int getIndex(NetworkInterface nf) { return nf.getIndex(); } -+ public NetworkInterface getByIndex(int i) { return getByIndex(i); } ++ public int getIndex(NetworkInterface nf) { return nf.getIndex(); } ++ public NetworkInterface getByIndex(int i) { return getByIndex(i); } + } -+ ); ++ ); + } + } diff -Nru openjdk.orig/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java openjdk/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java ---- openjdk.orig/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java 2010-06-21 22:15:21.000000000 +0100 -+++ openjdk/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java 2011-02-28 16:06:24.000000000 +0000 ++++ openjdk/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java 2011-05-23 23:20:58.660622971 +0100 @@ -2004,4 +2004,23 @@ } } @@ -962,8 +963,8 @@ + } diff -Nru openjdk.orig/jdk/src/share/classes/sun/misc/Unsafe.java openjdk/jdk/src/share/classes/sun/misc/Unsafe.java ---- openjdk.orig/jdk/src/share/classes/sun/misc/Unsafe.java 2010-06-21 22:15:30.000000000 +0100 -+++ openjdk/jdk/src/share/classes/sun/misc/Unsafe.java 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/src/share/classes/sun/misc/Unsafe.java 2011-02-28 16:06:34.000000000 +0000 ++++ openjdk/jdk/src/share/classes/sun/misc/Unsafe.java 2011-05-23 23:20:58.660622971 +0100 @@ -504,9 +504,33 @@ /** * Sets all bytes in a given block of memory to a copy of another @@ -1011,8 +1012,8 @@ * Report the scale factor for addressing elements in the storage * allocation of a given array class. However, arrays of "narrow" types diff -Nru openjdk.orig/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java openjdk/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java ---- openjdk.orig/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java 2011-02-08 22:57:12.000000000 +0000 -+++ openjdk/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java 2011-02-08 23:40:00.916516539 +0000 +--- openjdk.orig/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java 2011-02-28 16:06:34.000000000 +0000 ++++ openjdk/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java 2011-05-23 23:20:58.660622971 +0100 @@ -29,11 +29,30 @@ import java.io.IOException; import java.net.*; @@ -1479,8 +1480,8 @@ + } diff -Nru openjdk.orig/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java openjdk/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java ---- openjdk.orig/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java 2010-06-21 22:15:30.000000000 +0100 -+++ openjdk/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java 2011-02-28 16:06:34.000000000 +0000 ++++ openjdk/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java 2011-05-23 23:20:58.660622971 +0100 @@ -32,8 +32,15 @@ import java.io.IOException; import java.nio.ByteBuffer; @@ -1530,8 +1531,8 @@ ensureOpen(); int rv = -1; diff -Nru openjdk.orig/jdk/src/share/classes/sun/nio/ch/Net.java openjdk/jdk/src/share/classes/sun/nio/ch/Net.java ---- openjdk.orig/jdk/src/share/classes/sun/nio/ch/Net.java 2011-02-08 22:57:12.000000000 +0000 -+++ openjdk/jdk/src/share/classes/sun/nio/ch/Net.java 2011-02-08 23:16:14.657580027 +0000 +--- openjdk.orig/jdk/src/share/classes/sun/nio/ch/Net.java 2011-02-28 16:06:35.000000000 +0000 ++++ openjdk/jdk/src/share/classes/sun/nio/ch/Net.java 2011-05-23 23:20:58.660622971 +0100 @@ -30,6 +30,15 @@ import java.net.*; import java.nio.channels.*; @@ -1892,8 +1893,8 @@ + } diff -Nru openjdk.orig/jdk/src/share/classes/sun/nio/ch/SelectorProviderImpl.java openjdk/jdk/src/share/classes/sun/nio/ch/SelectorProviderImpl.java ---- openjdk.orig/jdk/src/share/classes/sun/nio/ch/SelectorProviderImpl.java 2010-06-21 22:15:30.000000000 +0100 -+++ openjdk/jdk/src/share/classes/sun/nio/ch/SelectorProviderImpl.java 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/src/share/classes/sun/nio/ch/SelectorProviderImpl.java 2011-02-28 16:06:35.000000000 +0000 ++++ openjdk/jdk/src/share/classes/sun/nio/ch/SelectorProviderImpl.java 2011-05-23 23:20:58.660622971 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. @@ -1940,8 +1941,8 @@ - } diff -Nru openjdk.orig/jdk/src/share/classes/sun/security/util/SecurityConstants.java openjdk/jdk/src/share/classes/sun/security/util/SecurityConstants.java ---- openjdk.orig/jdk/src/share/classes/sun/security/util/SecurityConstants.java 2010-06-21 22:15:35.000000000 +0100 -+++ openjdk/jdk/src/share/classes/sun/security/util/SecurityConstants.java 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/src/share/classes/sun/security/util/SecurityConstants.java 2011-02-28 16:06:40.000000000 +0000 ++++ openjdk/jdk/src/share/classes/sun/security/util/SecurityConstants.java 2011-05-23 23:20:58.660622971 +0100 @@ -52,6 +52,7 @@ public static final String FILE_EXECUTE_ACTION = "execute"; public static final String FILE_READ_ACTION = "read"; @@ -1951,8 +1952,8 @@ public static final String SOCKET_RESOLVE_ACTION = "resolve"; public static final String SOCKET_CONNECT_ACTION = "connect"; diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java openjdk/jdk/src/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java ---- openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java 2010-06-21 22:15:44.000000000 +0100 -+++ openjdk/jdk/src/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java 2011-02-28 16:06:48.000000000 +0000 ++++ openjdk/jdk/src/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java 2011-05-23 23:20:58.660622971 +0100 @@ -25,11 +25,12 @@ package sun.nio.ch; @@ -1968,8 +1969,8 @@ * Creates this platform's default SelectorProvider */ diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java openjdk/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java ---- openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java 2010-06-21 22:15:44.000000000 +0100 -+++ openjdk/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java 2011-02-08 23:10:59.378265602 +0000 +--- openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java 2011-02-28 16:06:48.000000000 +0000 ++++ openjdk/jdk/src/solaris/classes/sun/nio/ch/FileDispatcher.java 2011-05-23 23:20:58.660622971 +0100 @@ -35,6 +35,11 @@ class FileDispatcher extends NativeDispatcher { @@ -2031,8 +2032,8 @@ + } diff -Nru openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java openjdk/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java ---- openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java 2010-06-21 22:15:44.000000000 +0100 -+++ openjdk/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java 2011-02-08 23:10:59.382265644 +0000 +--- openjdk.orig/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java 2011-02-28 16:06:48.000000000 +0000 ++++ openjdk/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java 2011-05-23 23:20:58.660622971 +0100 @@ -34,7 +34,8 @@ import java.nio.channels.SocketChannel; import java.nio.channels.ServerSocketChannel; @@ -2044,8 +2045,8 @@ class InheritedChannel { diff -Nru openjdk.orig/jdk/src/solaris/native/sun/nio/ch/Net.c openjdk/jdk/src/solaris/native/sun/nio/ch/Net.c ---- openjdk.orig/jdk/src/solaris/native/sun/nio/ch/Net.c 2010-06-21 22:15:45.000000000 +0100 -+++ openjdk/jdk/src/solaris/native/sun/nio/ch/Net.c 2011-02-08 23:10:59.382265644 +0000 +--- openjdk.orig/jdk/src/solaris/native/sun/nio/ch/Net.c 2011-02-28 16:06:50.000000000 +0000 ++++ openjdk/jdk/src/solaris/native/sun/nio/ch/Net.c 2011-05-23 23:20:58.660622971 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved. @@ -2728,8 +2729,8 @@ /* Declared in nio_util.h */ diff -Nru openjdk.orig/jdk/src/solaris/native/sun/nio/ch/nio_util.h openjdk/jdk/src/solaris/native/sun/nio/ch/nio_util.h ---- openjdk.orig/jdk/src/solaris/native/sun/nio/ch/nio_util.h 2010-06-21 22:15:45.000000000 +0100 -+++ openjdk/jdk/src/solaris/native/sun/nio/ch/nio_util.h 2011-02-08 23:10:59.382265644 +0000 +--- openjdk.orig/jdk/src/solaris/native/sun/nio/ch/nio_util.h 2011-02-28 16:06:50.000000000 +0000 ++++ openjdk/jdk/src/solaris/native/sun/nio/ch/nio_util.h 2011-05-23 23:20:58.660622971 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. @@ -2754,8 +2755,8 @@ /* NIO utility procedures */ diff -Nru openjdk.orig/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java openjdk/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java ---- openjdk.orig/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java 2010-06-21 22:15:46.000000000 +0100 -+++ openjdk/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java 2011-02-08 23:10:59.382265644 +0000 +--- openjdk.orig/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java 2011-02-28 16:06:51.000000000 +0000 ++++ openjdk/jdk/src/windows/classes/sun/nio/ch/FileDispatcher.java 2011-05-23 23:20:58.660622971 +0100 @@ -36,6 +36,11 @@ class FileDispatcher extends NativeDispatcher {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6578583-modality-broken-vista.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,1446 @@ +# HG changeset patch +# User dcherepanov +# Date 1205521233 -10800 +# Node ID 15ba7093f8e64e1facdfc48b8929edc6a4fbb0d3 +# Parent 92e3f57c933b45c678abcbccaa47de059dfe926a +6578583: Regression: Modality is broken in windows vista home premium from jdk1.7 b02 onwards. +Summary: WS_DISABLED style should be used to fix some modality bugs +Reviewed-by: art, son + +diff -r 92e3f57c933b -r 15ba7093f8e6 src/windows/native/sun/windows/awt_Component.cpp +--- openjdk.orig/jdk/src/windows/native/sun/windows/awt_Component.cpp Fri Mar 14 20:40:09 2008 +0300 ++++ openjdk/jdk/src/windows/native/sun/windows/awt_Component.cpp Fri Mar 14 22:00:33 2008 +0300 +@@ -5425,7 +5425,13 @@ + void AwtComponent::Enable(BOOL bEnable) + { + sm_suppressFocusAndActivation = TRUE; ++ ++ if (bEnable && IsTopLevel()) { ++ // we should not enable blocked toplevels ++ bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())); ++ } + ::EnableWindow(GetHWnd(), bEnable); ++ + sm_suppressFocusAndActivation = FALSE; + CriticalSection::Lock l(GetLock()); + VerifyState(); +diff -r 92e3f57c933b -r 15ba7093f8e6 src/windows/native/sun/windows/awt_Dialog.cpp +--- openjdk.orig/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Fri Mar 14 20:40:09 2008 +0300 ++++ openjdk/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Fri Mar 14 22:00:33 2008 +0300 +@@ -273,6 +273,10 @@ + { + HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); + HWND topMostBlocker = blocker; ++ HWND prevForegroundWindow = ::GetForegroundWindow(); ++ if (::IsWindow(blocker)) { ++ ::BringWindowToTop(hWnd); ++ } + while (::IsWindow(blocker)) { + topMostBlocker = blocker; + ::BringWindowToTop(blocker); +@@ -282,7 +286,7 @@ + // no beep/flash if the mouse was clicked in the taskbar menu + // or the dialog is currently inactive + if ((::WindowFromPoint(mhs->pt) == hWnd) && +- (::GetForegroundWindow() == topMostBlocker)) ++ (prevForegroundWindow == topMostBlocker)) + { + ::MessageBeep(MB_OK); + // some heuristics: 3 times x 64 milliseconds +@@ -292,6 +296,7 @@ + ::BringWindowToTop(topMostBlocker); + ::SetForegroundWindow(topMostBlocker); + } ++ return 1; + } + } + } +diff -r 92e3f57c933b -r 15ba7093f8e6 src/windows/native/sun/windows/awt_Window.cpp +--- openjdk.orig/jdk/src/windows/native/sun/windows/awt_Window.cpp Fri Mar 14 20:40:09 2008 +0300 ++++ openjdk/jdk/src/windows/native/sun/windows/awt_Window.cpp Fri Mar 14 22:00:33 2008 +0300 +@@ -180,7 +180,6 @@ + } + + ::RemoveProp(GetHWnd(), ModalBlockerProp); +- ::RemoveProp(GetHWnd(), ModalSaveWSEXProp); + + if (m_grabbedWindow == this) { + Ungrab(); +@@ -1455,20 +1454,17 @@ + if (!::IsWindow(window)) { + return; + } +- DWORD exStyle = ::GetWindowLong(window, GWL_EXSTYLE); ++ + if (::IsWindow(blocker)) { +- // save WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles +- DWORD saveStyle = exStyle & (AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW); +- ::SetProp(window, ModalSaveWSEXProp, reinterpret_cast<HANDLE>(saveStyle)); +- ::SetWindowLong(window, GWL_EXSTYLE, (exStyle | AWT_WS_EX_NOACTIVATE) & ~WS_EX_APPWINDOW); + ::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker)); ++ ::EnableWindow(window, FALSE); + } else { +- // restore WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles +- DWORD saveStyle = reinterpret_cast<DWORD>(::GetProp(window, ModalSaveWSEXProp)); +- ::SetWindowLong(window, GWL_EXSTYLE, +- (exStyle & ~(AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW)) | saveStyle); +- ::RemoveProp(window, ModalSaveWSEXProp); + ::RemoveProp(window, ModalBlockerProp); ++ AwtComponent *comp = AwtComponent::GetComponent(window); ++ // we don't expect to be called with non-java HWNDs ++ DASSERT(comp && comp->IsTopLevel()); ++ // we should not unblock disabled toplevels ++ ::EnableWindow(window, comp->isEnabled()); + } + } + +diff -r 92e3f57c933b -r 15ba7093f8e6 src/windows/native/sun/windows/awt_Window.h +--- openjdk.orig/jdk/src/windows/native/sun/windows/awt_Window.h Fri Mar 14 20:40:09 2008 +0300 ++++ openjdk/jdk/src/windows/native/sun/windows/awt_Window.h Fri Mar 14 22:00:33 2008 +0300 +@@ -33,7 +33,6 @@ + + // property name tagging windows disabled by modality + static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp"); +-static LPCTSTR ModalSaveWSEXProp = TEXT("SunAwtModalSaveWSEXProp"); + static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp"); + + #ifndef WH_MOUSE_LL +diff -r 92e3f57c933b -r 15ba7093f8e6 test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java Fri Mar 14 22:00:33 2008 +0300 +@@ -0,0 +1,466 @@ ++/* ++ * 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. ++ * ++ * 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 %I% %E% ++ @bug 4080029 ++ @summary Modal Dialog block input to all frame windows not just its parent. ++ @author dmitry.cherepanov: area=awt.modal ++ @run main/manual CloseBlocker ++*/ ++ ++/** ++ * ManualMainTest.java ++ * ++ * summary: The test opens and closes blocker dialog, the test verifies ++ * that active window is correct when the dialog is closed. ++ */ ++ ++import java.awt.*; ++import java.awt.event.*; ++ ++public class CloseBlocker ++{ ++ ++ private static void init() ++ { ++ //*** Create instructions for the user here *** ++ ++ String[] instructions = ++ { ++ " the test will be run 6 times, to start next test just close all ", ++ " windows of previous; the instructions are the same for all tests: ", ++ " 1) there are two frames (one the frames has 'show modal' button), ", ++ " 2) press the button to show a dialog, ", ++ " 3) close the dialog (an alternative scenario - activate another", ++ " native window before closing the dialog), ", ++ " 4) the frame with button should become next active window, ", ++ " if it's true, then the test passed, otherwise, it failed. ", ++ " Press 'pass' button only after all of the 6 tests are completed, ", ++ " the number of the currently executed test is displayed on the ", ++ " output window. " ++ }; ++ Sysout.createDialog( ); ++ Sysout.printInstructions( instructions ); ++ ++ test(true, true, false); ++ test(true, true, true); ++ test(false, true, false); // 3rd parameter has no affect for ownerless ++ ++ test(true, false, false); ++ test(true, false, true); ++ test(false, false, false); // 3rd parameter has no affect for ownerless ++ ++ }//End init() ++ ++ private static final Object obj = new Object(); ++ private static int counter = 0; ++ ++ /* ++ * The ownerless parameter indicates whether the blocker dialog ++ * has owner. The usual parameter indicates whether the blocker ++ * dialog is a Java dialog (non-native dialog like file dialog). ++ */ ++ private static void test(final boolean ownerless, final boolean usual, final boolean initiallyOwnerIsActive) { ++ ++ Sysout.print(" * test #" + (++counter) + " is running ... "); ++ ++ final Frame active = new Frame(); ++ final Frame nonactive = new Frame(); ++ Button button = new Button("show modal"); ++ button.addActionListener(new ActionListener() { ++ public void actionPerformed(ActionEvent ae) { ++ Dialog dialog = null; ++ Frame parent = ownerless ? null : (initiallyOwnerIsActive? active : nonactive); ++ if (usual) { ++ dialog = new Dialog(parent, "Sample", true); ++ } else { ++ dialog = new FileDialog(parent, "Sample", FileDialog.LOAD); ++ } ++ dialog.addWindowListener(new WindowAdapter(){ ++ public void windowClosing(WindowEvent e){ ++ e.getWindow().dispose(); ++ } ++ }); ++ dialog.setBounds(200, 200, 200, 200); ++ dialog.setVisible(true); ++ } ++ }); ++ ++ active.add(button); ++ active.setBounds(200, 400, 200, 200); ++ WindowAdapter adapter = new WindowAdapter(){ ++ public void windowClosing(WindowEvent e){ ++ active.dispose(); ++ nonactive.dispose(); ++ synchronized(obj) { ++ obj.notify(); ++ } ++ } ++ }; ++ active.addWindowListener(adapter); ++ active.setVisible(true); ++ ++ nonactive.setBounds(400, 400, 200, 200); ++ nonactive.addWindowListener(adapter); ++ nonactive.setVisible(true); ++ ++ synchronized(obj) { ++ try{ ++ obj.wait(); ++ } catch(Exception e) { ++ throw new RuntimeException(e); ++ } ++ } ++ ++ Sysout.println(" completed. "); ++ ++ } ++ ++ /***************************************************** ++ * Standard Test Machinery Section ++ * DO NOT modify anything in this section -- it's a ++ * standard chunk of code which has all of the ++ * synchronisation necessary for the test harness. ++ * By keeping it the same in all tests, it is easier ++ * to read and understand someone else's test, as ++ * well as insuring that all tests behave correctly ++ * with the test harness. ++ * There is a section following this for test-defined ++ * classes ++ ******************************************************/ ++ private static boolean theTestPassed = false; ++ private static boolean testGeneratedInterrupt = false; ++ private static String failureMessage = ""; ++ ++ private static Thread mainThread = null; ++ ++ private static int sleepTime = 300000; ++ ++ public static void main( String args[] ) throws InterruptedException ++ { ++ mainThread = Thread.currentThread(); ++ try ++ { ++ init(); ++ } ++ catch( TestPassedException e ) ++ { ++ //The test passed, so just return from main and harness will ++ // interepret this return as a pass ++ return; ++ } ++ //At this point, neither test passed nor test failed has been ++ // called -- either would have thrown an exception and ended the ++ // test, so we know we have multiple threads. ++ ++ //Test involves other threads, so sleep and wait for them to ++ // called pass() or fail() ++ try ++ { ++ Thread.sleep( sleepTime ); ++ //Timed out, so fail the test ++ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); ++ } ++ catch (InterruptedException e) ++ { ++ if( ! testGeneratedInterrupt ) throw e; ++ ++ //reset flag in case hit this code more than once for some reason (just safety) ++ testGeneratedInterrupt = false; ++ if ( theTestPassed == false ) ++ { ++ throw new RuntimeException( failureMessage ); ++ } ++ } ++ ++ }//main ++ ++ public static synchronized void setTimeoutTo( int seconds ) ++ { ++ sleepTime = seconds * 1000; ++ } ++ ++ public static synchronized void pass() ++ { ++ Sysout.println( "The test passed." ); ++ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); ++ //first check if this is executing in main thread ++ if ( mainThread == Thread.currentThread() ) ++ { ++ //Still in the main thread, so set the flag just for kicks, ++ // and throw a test passed exception which will be caught ++ // and end the test. ++ theTestPassed = true; ++ throw new TestPassedException(); ++ } ++ //pass was called from a different thread, so set the flag and interrupt ++ // the main thead. ++ theTestPassed = true; ++ testGeneratedInterrupt = true; ++ mainThread.interrupt(); ++ }//pass() ++ ++ public static synchronized void fail() ++ { ++ //test writer didn't specify why test failed, so give generic ++ fail( "it just plain failed! :-)" ); ++ } ++ ++ public static synchronized void fail( String whyFailed ) ++ { ++ Sysout.println( "The test failed: " + whyFailed ); ++ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); ++ //check if this called from main thread ++ if ( mainThread == Thread.currentThread() ) ++ { ++ //If main thread, fail now 'cause not sleeping ++ throw new RuntimeException( whyFailed ); ++ } ++ theTestPassed = false; ++ testGeneratedInterrupt = true; ++ failureMessage = whyFailed; ++ mainThread.interrupt(); ++ }//fail() ++ ++}// class ManualMainTest ++ ++//This exception is used to exit from any level of call nesting ++// when it's determined that the test has passed, and immediately ++// end the test. ++class TestPassedException extends RuntimeException ++{ ++} ++ ++//*********** End Standard Test Machinery Section ********** ++ ++ ++//************ Begin classes defined for the test **************** ++ ++// make listeners in a class defined here, and instantiate them in init() ++ ++/* Example of a class which may be written as part of a test ++class NewClass implements anInterface ++ { ++ static int newVar = 0; ++ ++ public void eventDispatched(AWTEvent e) ++ { ++ //Counting events to see if we get enough ++ eventCount++; ++ ++ if( eventCount == 20 ) ++ { ++ //got enough events, so pass ++ ++ ManualMainTest.pass(); ++ } ++ else if( tries == 20 ) ++ { ++ //tried too many times without getting enough events so fail ++ ++ ManualMainTest.fail(); ++ } ++ ++ }// eventDispatched() ++ ++ }// NewClass class ++ ++*/ ++ ++ ++//************** End classes defined for the test ******************* ++ ++ ++ ++ ++/**************************************************** ++ Standard Test Machinery ++ DO NOT modify anything below -- it's a standard ++ chunk of code whose purpose is to make user ++ interaction uniform, and thereby make it simpler ++ to read and understand someone else's test. ++ ****************************************************/ ++ ++/** ++ This is part of the standard test machinery. ++ It creates a dialog (with the instructions), and is the interface ++ for sending text messages to the user. ++ To print the instructions, send an array of strings to Sysout.createDialog ++ WithInstructions method. Put one line of instructions per array entry. ++ To display a message for the tester to see, simply call Sysout.println ++ with the string to be displayed. ++ This mimics System.out.println but works within the test harness as well ++ as standalone. ++ */ ++ ++class Sysout ++{ ++ private static TestDialog dialog; ++ ++ public static void createDialogWithInstructions( String[] instructions ) ++ { ++ dialog = new TestDialog( new Frame(), "Instructions" ); ++ dialog.printInstructions( instructions ); ++ dialog.setVisible(true); ++ println( "Any messages for the tester will display here." ); ++ } ++ ++ public static void createDialog( ) ++ { ++ dialog = new TestDialog( new Frame(), "Instructions" ); ++ String[] defInstr = { "Instructions will appear here. ", "" } ; ++ dialog.printInstructions( defInstr ); ++ dialog.setVisible(true); ++ println( "Any messages for the tester will display here." ); ++ } ++ ++ ++ public static void printInstructions( String[] instructions ) ++ { ++ dialog.printInstructions( instructions ); ++ } ++ ++ ++ public static void println( String messageIn ) ++ { ++ dialog.displayMessage( messageIn, true ); ++ } ++ ++ public static void print( String messageIn ) ++ { ++ dialog.displayMessage( messageIn, false ); ++ } ++ ++}// Sysout class ++ ++/** ++ This is part of the standard test machinery. It provides a place for the ++ test instructions to be displayed, and a place for interactive messages ++ to the user to be displayed. ++ To have the test instructions displayed, see Sysout. ++ To have a message to the user be displayed, see Sysout. ++ Do not call anything in this dialog directly. ++ */ ++class TestDialog extends Dialog implements ActionListener ++{ ++ ++ TextArea instructionsText; ++ TextArea messageText; ++ int maxStringLength = 80; ++ Panel buttonP = new Panel(); ++ Button passB = new Button( "pass" ); ++ Button failB = new Button( "fail" ); ++ ++ //DO NOT call this directly, go through Sysout ++ public TestDialog( Frame frame, String name ) ++ { ++ super( frame, name ); ++ int scrollBoth = TextArea.SCROLLBARS_BOTH; ++ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); ++ add( "North", instructionsText ); ++ ++ messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); ++ add("Center", messageText); ++ ++ passB = new Button( "pass" ); ++ passB.setActionCommand( "pass" ); ++ passB.addActionListener( this ); ++ buttonP.add( "East", passB ); ++ ++ failB = new Button( "fail" ); ++ failB.setActionCommand( "fail" ); ++ failB.addActionListener( this ); ++ buttonP.add( "West", failB ); ++ ++ add( "South", buttonP ); ++ pack(); ++ ++ setVisible(true); ++ }// TestDialog() ++ ++ //DO NOT call this directly, go through Sysout ++ public void printInstructions( String[] instructions ) ++ { ++ //Clear out any current instructions ++ instructionsText.setText( "" ); ++ ++ //Go down array of instruction strings ++ ++ String printStr, remainingStr; ++ for( int i=0; i < instructions.length; i++ ) ++ { ++ //chop up each into pieces maxSringLength long ++ remainingStr = instructions[ i ]; ++ while( remainingStr.length() > 0 ) ++ { ++ //if longer than max then chop off first max chars to print ++ if( remainingStr.length() >= maxStringLength ) ++ { ++ //Try to chop on a word boundary ++ int posOfSpace = remainingStr. ++ lastIndexOf( ' ', maxStringLength - 1 ); ++ ++ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; ++ ++ printStr = remainingStr.substring( 0, posOfSpace + 1 ); ++ remainingStr = remainingStr.substring( posOfSpace + 1 ); ++ } ++ //else just print ++ else ++ { ++ printStr = remainingStr; ++ remainingStr = ""; ++ } ++ ++ instructionsText.append( printStr + "\n" ); ++ ++ }// while ++ ++ }// for ++ ++ }//printInstructions() ++ ++ //DO NOT call this directly, go through Sysout ++ public void displayMessage( String messageIn, boolean nextLine ) ++ { ++ messageText.append( messageIn + (nextLine? "\n" : "") ); ++ System.out.println(messageIn); ++ } ++ ++ //catch presses of the passed and failed buttons. ++ //simply call the standard pass() or fail() static methods of ++ //ManualMainTest ++ public void actionPerformed( ActionEvent e ) ++ { ++ if( e.getActionCommand() == "pass" ) ++ { ++ CloseBlocker.pass(); ++ } ++ else ++ { ++ CloseBlocker.fail(); ++ } ++ } ++ ++}// TestDialog class +diff -r 92e3f57c933b -r 15ba7093f8e6 test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java Fri Mar 14 22:00:33 2008 +0300 +@@ -0,0 +1,456 @@ ++/* ++ * 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. ++ * ++ * 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 %I% %E% ++ @bug 4080029 ++ @summary Modal Dialog block input to all frame windows not just its parent. ++ @author dmitry.cherepanov: area=awt.modal ++ @run main/manual OverBlocker ++*/ ++ ++/** ++ * OverBlocker.java ++ * ++ * summary: The test verifies that if user tries to activate the blocked dialog ++ * then the blocker dialog appears over the other windows ++ */ ++ ++import java.awt.*; ++import java.awt.event.*; ++ ++public class OverBlocker ++{ ++ ++ private static void init() ++ { ++ //*** Create instructions for the user here *** ++ ++ String[] instructions = ++ { ++ " the test will be run 4 times, to start next test just close all ", ++ " windows of previous; the instructions are the same for all tests: ", ++ " 1) there is a frame with 'show modal' button, ", ++ " 2) press the button to show a dialog, ", ++ " 3) activate any non-Java application, move the app over the dialog, ", ++ " 4) click on the frame by mouse, ", ++ " 5) make sure that the dialog comes up from the application and ", ++ " now the dialog overlaps the app as well as the frame, ", ++ " if it's true, then the test passed, otherwise, it failed. ", ++ " Press 'pass' button only after all of the 4 tests are completed, ", ++ " the number of the currently executed test is displayed on the ", ++ " output window. " ++ }; ++ Sysout.createDialog( ); ++ Sysout.printInstructions( instructions ); ++ ++ test(false, true); ++ test(true, true); ++ test(true, false); ++ test(false, false); ++ ++ }//End init() ++ ++ private static final Object obj = new Object(); ++ private static int counter = 0; ++ ++ /* ++ * The ownerless parameter indicates whether the blocker dialog ++ * has owner. The usual parameter indicates whether the blocker ++ * dialog is a Java dialog (non-native dialog like file dialog). ++ */ ++ private static void test(final boolean ownerless, final boolean usual) { ++ ++ Sysout.print(" * test #" + (++counter) + " is running ... "); ++ ++ final Frame frame = new Frame(); ++ Button button = new Button("show modal"); ++ button.addActionListener(new ActionListener() { ++ public void actionPerformed(ActionEvent ae) { ++ Dialog dialog = null; ++ Frame parent = ownerless ? null : frame; ++ if (usual) { ++ dialog = new Dialog(parent, "Sample", true); ++ } else { ++ dialog = new FileDialog(parent, "Sample", FileDialog.LOAD); ++ } ++ dialog.addWindowListener(new WindowAdapter(){ ++ public void windowClosing(WindowEvent e){ ++ e.getWindow().dispose(); ++ } ++ }); ++ dialog.setBounds(200, 200, 200, 200); ++ dialog.setVisible(true); ++ } ++ }); ++ frame.add(button); ++ frame.setBounds(400, 400, 200, 200); ++ frame.addWindowListener(new WindowAdapter(){ ++ public void windowClosing(WindowEvent e){ ++ e.getWindow().dispose(); ++ synchronized(obj) { ++ obj.notify(); ++ } ++ } ++ }); ++ frame.setVisible(true); ++ ++ synchronized(obj) { ++ try{ ++ obj.wait(); ++ } catch(Exception e) { ++ throw new RuntimeException(e); ++ } ++ } ++ ++ Sysout.println(" completed. "); ++ ++ } ++ ++ /***************************************************** ++ * Standard Test Machinery Section ++ * DO NOT modify anything in this section -- it's a ++ * standard chunk of code which has all of the ++ * synchronisation necessary for the test harness. ++ * By keeping it the same in all tests, it is easier ++ * to read and understand someone else's test, as ++ * well as insuring that all tests behave correctly ++ * with the test harness. ++ * There is a section following this for test-defined ++ * classes ++ ******************************************************/ ++ private static boolean theTestPassed = false; ++ private static boolean testGeneratedInterrupt = false; ++ private static String failureMessage = ""; ++ ++ private static Thread mainThread = null; ++ ++ private static int sleepTime = 300000; ++ ++ public static void main( String args[] ) throws InterruptedException ++ { ++ mainThread = Thread.currentThread(); ++ try ++ { ++ init(); ++ } ++ catch( TestPassedException e ) ++ { ++ //The test passed, so just return from main and harness will ++ // interepret this return as a pass ++ return; ++ } ++ //At this point, neither test passed nor test failed has been ++ // called -- either would have thrown an exception and ended the ++ // test, so we know we have multiple threads. ++ ++ //Test involves other threads, so sleep and wait for them to ++ // called pass() or fail() ++ try ++ { ++ Thread.sleep( sleepTime ); ++ //Timed out, so fail the test ++ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); ++ } ++ catch (InterruptedException e) ++ { ++ if( ! testGeneratedInterrupt ) throw e; ++ ++ //reset flag in case hit this code more than once for some reason (just safety) ++ testGeneratedInterrupt = false; ++ if ( theTestPassed == false ) ++ { ++ throw new RuntimeException( failureMessage ); ++ } ++ } ++ ++ }//main ++ ++ public static synchronized void setTimeoutTo( int seconds ) ++ { ++ sleepTime = seconds * 1000; ++ } ++ ++ public static synchronized void pass() ++ { ++ Sysout.println( "The test passed." ); ++ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); ++ //first check if this is executing in main thread ++ if ( mainThread == Thread.currentThread() ) ++ { ++ //Still in the main thread, so set the flag just for kicks, ++ // and throw a test passed exception which will be caught ++ // and end the test. ++ theTestPassed = true; ++ throw new TestPassedException(); ++ } ++ //pass was called from a different thread, so set the flag and interrupt ++ // the main thead. ++ theTestPassed = true; ++ testGeneratedInterrupt = true; ++ mainThread.interrupt(); ++ }//pass() ++ ++ public static synchronized void fail() ++ { ++ //test writer didn't specify why test failed, so give generic ++ fail( "it just plain failed! :-)" ); ++ } ++ ++ public static synchronized void fail( String whyFailed ) ++ { ++ Sysout.println( "The test failed: " + whyFailed ); ++ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); ++ //check if this called from main thread ++ if ( mainThread == Thread.currentThread() ) ++ { ++ //If main thread, fail now 'cause not sleeping ++ throw new RuntimeException( whyFailed ); ++ } ++ theTestPassed = false; ++ testGeneratedInterrupt = true; ++ failureMessage = whyFailed; ++ mainThread.interrupt(); ++ }//fail() ++ ++}// class ManualMainTest ++ ++//This exception is used to exit from any level of call nesting ++// when it's determined that the test has passed, and immediately ++// end the test. ++class TestPassedException extends RuntimeException ++{ ++} ++ ++//*********** End Standard Test Machinery Section ********** ++ ++ ++//************ Begin classes defined for the test **************** ++ ++// make listeners in a class defined here, and instantiate them in init() ++ ++/* Example of a class which may be written as part of a test ++class NewClass implements anInterface ++ { ++ static int newVar = 0; ++ ++ public void eventDispatched(AWTEvent e) ++ { ++ //Counting events to see if we get enough ++ eventCount++; ++ ++ if( eventCount == 20 ) ++ { ++ //got enough events, so pass ++ ++ ManualMainTest.pass(); ++ } ++ else if( tries == 20 ) ++ { ++ //tried too many times without getting enough events so fail ++ ++ ManualMainTest.fail(); ++ } ++ ++ }// eventDispatched() ++ ++ }// NewClass class ++ ++*/ ++ ++ ++//************** End classes defined for the test ******************* ++ ++ ++ ++ ++/**************************************************** ++ Standard Test Machinery ++ DO NOT modify anything below -- it's a standard ++ chunk of code whose purpose is to make user ++ interaction uniform, and thereby make it simpler ++ to read and understand someone else's test. ++ ****************************************************/ ++ ++/** ++ This is part of the standard test machinery. ++ It creates a dialog (with the instructions), and is the interface ++ for sending text messages to the user. ++ To print the instructions, send an array of strings to Sysout.createDialog ++ WithInstructions method. Put one line of instructions per array entry. ++ To display a message for the tester to see, simply call Sysout.println ++ with the string to be displayed. ++ This mimics System.out.println but works within the test harness as well ++ as standalone. ++ */ ++ ++class Sysout ++{ ++ private static TestDialog dialog; ++ ++ public static void createDialogWithInstructions( String[] instructions ) ++ { ++ dialog = new TestDialog( new Frame(), "Instructions" ); ++ dialog.printInstructions( instructions ); ++ dialog.setVisible(true); ++ println( "Any messages for the tester will display here." ); ++ } ++ ++ public static void createDialog( ) ++ { ++ dialog = new TestDialog( new Frame(), "Instructions" ); ++ String[] defInstr = { "Instructions will appear here. ", "" } ; ++ dialog.printInstructions( defInstr ); ++ dialog.setVisible(true); ++ println( "Any messages for the tester will display here." ); ++ } ++ ++ ++ public static void printInstructions( String[] instructions ) ++ { ++ dialog.printInstructions( instructions ); ++ } ++ ++ ++ public static void println( String messageIn ) ++ { ++ dialog.displayMessage( messageIn, true ); ++ } ++ ++ public static void print( String messageIn ) ++ { ++ dialog.displayMessage( messageIn, false ); ++ } ++ ++}// Sysout class ++ ++/** ++ This is part of the standard test machinery. It provides a place for the ++ test instructions to be displayed, and a place for interactive messages ++ to the user to be displayed. ++ To have the test instructions displayed, see Sysout. ++ To have a message to the user be displayed, see Sysout. ++ Do not call anything in this dialog directly. ++ */ ++class TestDialog extends Dialog implements ActionListener ++{ ++ ++ TextArea instructionsText; ++ TextArea messageText; ++ int maxStringLength = 80; ++ Panel buttonP = new Panel(); ++ Button passB = new Button( "pass" ); ++ Button failB = new Button( "fail" ); ++ ++ //DO NOT call this directly, go through Sysout ++ public TestDialog( Frame frame, String name ) ++ { ++ super( frame, name ); ++ int scrollBoth = TextArea.SCROLLBARS_BOTH; ++ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); ++ add( "North", instructionsText ); ++ ++ messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); ++ add("Center", messageText); ++ ++ passB = new Button( "pass" ); ++ passB.setActionCommand( "pass" ); ++ passB.addActionListener( this ); ++ buttonP.add( "East", passB ); ++ ++ failB = new Button( "fail" ); ++ failB.setActionCommand( "fail" ); ++ failB.addActionListener( this ); ++ buttonP.add( "West", failB ); ++ ++ add( "South", buttonP ); ++ pack(); ++ ++ setVisible(true); ++ }// TestDialog() ++ ++ //DO NOT call this directly, go through Sysout ++ public void printInstructions( String[] instructions ) ++ { ++ //Clear out any current instructions ++ instructionsText.setText( "" ); ++ ++ //Go down array of instruction strings ++ ++ String printStr, remainingStr; ++ for( int i=0; i < instructions.length; i++ ) ++ { ++ //chop up each into pieces maxSringLength long ++ remainingStr = instructions[ i ]; ++ while( remainingStr.length() > 0 ) ++ { ++ //if longer than max then chop off first max chars to print ++ if( remainingStr.length() >= maxStringLength ) ++ { ++ //Try to chop on a word boundary ++ int posOfSpace = remainingStr. ++ lastIndexOf( ' ', maxStringLength - 1 ); ++ ++ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; ++ ++ printStr = remainingStr.substring( 0, posOfSpace + 1 ); ++ remainingStr = remainingStr.substring( posOfSpace + 1 ); ++ } ++ //else just print ++ else ++ { ++ printStr = remainingStr; ++ remainingStr = ""; ++ } ++ ++ instructionsText.append( printStr + "\n" ); ++ ++ }// while ++ ++ }// for ++ ++ }//printInstructions() ++ ++ //DO NOT call this directly, go through Sysout ++ public void displayMessage( String messageIn, boolean nextLine ) ++ { ++ messageText.append( messageIn + (nextLine? "\n" : "") ); ++ System.out.println(messageIn); ++ } ++ ++ //catch presses of the passed and failed buttons. ++ //simply call the standard pass() or fail() static methods of ++ //ManualMainTest ++ public void actionPerformed( ActionEvent e ) ++ { ++ if( e.getActionCommand() == "pass" ) ++ { ++ OverBlocker.pass(); ++ } ++ else ++ { ++ OverBlocker.fail(); ++ } ++ } ++ ++}// TestDialog class +diff -r 92e3f57c933b -r 15ba7093f8e6 test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java Fri Mar 14 22:00:33 2008 +0300 +@@ -0,0 +1,403 @@ ++/* ++ * 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. ++ * ++ * 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 %I% %E% ++ @bug 6572263 6571808 ++ @summary PIT:FileDialog minimized to taskbar(through 'Show Desktop')selecting the fileDialog using windowList ++ @author dmitry.cherepanov: area=awt.modal ++ @run main/manual Winkey ++*/ ++ ++/** ++ * Winkey.java ++ * ++ * summary: the test verifies that pressing combination of Windows key ++ * and M key to minimize all windows doesn't break AWT modality ++ */ ++ ++import java.awt.*; ++import java.awt.event.*; ++ ++public class Winkey ++{ ++ ++ private static void init() ++ { ++ //*** Create instructions for the user here *** ++ ++ String[] instructions = ++ { ++ " 1. there is a frame with a 'show modal' button, ", ++ " 2. press the button to show a modal dialog, ", ++ " 3. the modal dialog will be shown over the frame, ", ++ " 4. please verify that all (5.1, 5.2.1, 5.2.2) the following tests pass: ", ++ " ", ++ " 5.1. press combination Windows Key and M key to minimize all windows, ", ++ " 5.2. press combination Windows Key and D key to show desktop, ", ++ " 5.2.1. restore the dialog by choosing this one in the ALT-TAB list, ", ++ " 5.2.2. restore the dialog by mouse click on taskbar (on java or any other item)", ++ " ", ++ " 6. make sure that the dialog and the frame are visible, ", ++ " the bounds of the windows should be the same as before, ", ++ " if it's true, then the test passed; otherwise, it failed. " ++ }; ++ Sysout.createDialog( ); ++ Sysout.printInstructions( instructions ); ++ ++ final Frame frame = new Frame(); ++ Button button = new Button("show modal"); ++ button.addActionListener(new ActionListener() { ++ public void actionPerformed(ActionEvent ae) { ++ FileDialog dialog = new FileDialog((Frame)null, "Sample", FileDialog.LOAD); ++ dialog.setVisible(true); ++ } ++ }); ++ frame.add(button); ++ frame.setBounds(400, 400, 200, 200); ++ frame.setVisible(true); ++ ++ }//End init() ++ ++ /***************************************************** ++ * Standard Test Machinery Section ++ * DO NOT modify anything in this section -- it's a ++ * standard chunk of code which has all of the ++ * synchronisation necessary for the test harness. ++ * By keeping it the same in all tests, it is easier ++ * to read and understand someone else's test, as ++ * well as insuring that all tests behave correctly ++ * with the test harness. ++ * There is a section following this for test-defined ++ * classes ++ ******************************************************/ ++ private static boolean theTestPassed = false; ++ private static boolean testGeneratedInterrupt = false; ++ private static String failureMessage = ""; ++ ++ private static Thread mainThread = null; ++ ++ private static int sleepTime = 300000; ++ ++ public static void main( String args[] ) throws InterruptedException ++ { ++ mainThread = Thread.currentThread(); ++ try ++ { ++ init(); ++ } ++ catch( TestPassedException e ) ++ { ++ //The test passed, so just return from main and harness will ++ // interepret this return as a pass ++ return; ++ } ++ //At this point, neither test passed nor test failed has been ++ // called -- either would have thrown an exception and ended the ++ // test, so we know we have multiple threads. ++ ++ //Test involves other threads, so sleep and wait for them to ++ // called pass() or fail() ++ try ++ { ++ Thread.sleep( sleepTime ); ++ //Timed out, so fail the test ++ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); ++ } ++ catch (InterruptedException e) ++ { ++ if( ! testGeneratedInterrupt ) throw e; ++ ++ //reset flag in case hit this code more than once for some reason (just safety) ++ testGeneratedInterrupt = false; ++ if ( theTestPassed == false ) ++ { ++ throw new RuntimeException( failureMessage ); ++ } ++ } ++ ++ }//main ++ ++ public static synchronized void setTimeoutTo( int seconds ) ++ { ++ sleepTime = seconds * 1000; ++ } ++ ++ public static synchronized void pass() ++ { ++ Sysout.println( "The test passed." ); ++ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); ++ //first check if this is executing in main thread ++ if ( mainThread == Thread.currentThread() ) ++ { ++ //Still in the main thread, so set the flag just for kicks, ++ // and throw a test passed exception which will be caught ++ // and end the test. ++ theTestPassed = true; ++ throw new TestPassedException(); ++ } ++ //pass was called from a different thread, so set the flag and interrupt ++ // the main thead. ++ theTestPassed = true; ++ testGeneratedInterrupt = true; ++ mainThread.interrupt(); ++ }//pass() ++ ++ public static synchronized void fail() ++ { ++ //test writer didn't specify why test failed, so give generic ++ fail( "it just plain failed! :-)" ); ++ } ++ ++ public static synchronized void fail( String whyFailed ) ++ { ++ Sysout.println( "The test failed: " + whyFailed ); ++ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); ++ //check if this called from main thread ++ if ( mainThread == Thread.currentThread() ) ++ { ++ //If main thread, fail now 'cause not sleeping ++ throw new RuntimeException( whyFailed ); ++ } ++ theTestPassed = false; ++ testGeneratedInterrupt = true; ++ failureMessage = whyFailed; ++ mainThread.interrupt(); ++ }//fail() ++ ++}// class ManualMainTest ++ ++//This exception is used to exit from any level of call nesting ++// when it's determined that the test has passed, and immediately ++// end the test. ++class TestPassedException extends RuntimeException ++{ ++} ++ ++//*********** End Standard Test Machinery Section ********** ++ ++ ++//************ Begin classes defined for the test **************** ++ ++// make listeners in a class defined here, and instantiate them in init() ++ ++/* Example of a class which may be written as part of a test ++class NewClass implements anInterface ++ { ++ static int newVar = 0; ++ ++ public void eventDispatched(AWTEvent e) ++ { ++ //Counting events to see if we get enough ++ eventCount++; ++ ++ if( eventCount == 20 ) ++ { ++ //got enough events, so pass ++ ++ ManualMainTest.pass(); ++ } ++ else if( tries == 20 ) ++ { ++ //tried too many times without getting enough events so fail ++ ++ ManualMainTest.fail(); ++ } ++ ++ }// eventDispatched() ++ ++ }// NewClass class ++ ++*/ ++ ++ ++//************** End classes defined for the test ******************* ++ ++ ++ ++ ++/**************************************************** ++ Standard Test Machinery ++ DO NOT modify anything below -- it's a standard ++ chunk of code whose purpose is to make user ++ interaction uniform, and thereby make it simpler ++ to read and understand someone else's test. ++ ****************************************************/ ++ ++/** ++ This is part of the standard test machinery. ++ It creates a dialog (with the instructions), and is the interface ++ for sending text messages to the user. ++ To print the instructions, send an array of strings to Sysout.createDialog ++ WithInstructions method. Put one line of instructions per array entry. ++ To display a message for the tester to see, simply call Sysout.println ++ with the string to be displayed. ++ This mimics System.out.println but works within the test harness as well ++ as standalone. ++ */ ++ ++class Sysout ++{ ++ private static TestDialog dialog; ++ ++ public static void createDialogWithInstructions( String[] instructions ) ++ { ++ dialog = new TestDialog( new Frame(), "Instructions" ); ++ dialog.printInstructions( instructions ); ++ dialog.setVisible(true); ++ println( "Any messages for the tester will display here." ); ++ } ++ ++ public static void createDialog( ) ++ { ++ dialog = new TestDialog( new Frame(), "Instructions" ); ++ String[] defInstr = { "Instructions will appear here. ", "" } ; ++ dialog.printInstructions( defInstr ); ++ dialog.setVisible(true); ++ println( "Any messages for the tester will display here." ); ++ } ++ ++ ++ public static void printInstructions( String[] instructions ) ++ { ++ dialog.printInstructions( instructions ); ++ } ++ ++ ++ public static void println( String messageIn ) ++ { ++ dialog.displayMessage( messageIn ); ++ } ++ ++}// Sysout class ++ ++/** ++ This is part of the standard test machinery. It provides a place for the ++ test instructions to be displayed, and a place for interactive messages ++ to the user to be displayed. ++ To have the test instructions displayed, see Sysout. ++ To have a message to the user be displayed, see Sysout. ++ Do not call anything in this dialog directly. ++ */ ++class TestDialog extends Dialog implements ActionListener ++{ ++ ++ TextArea instructionsText; ++ TextArea messageText; ++ int maxStringLength = 80; ++ Panel buttonP = new Panel(); ++ Button passB = new Button( "pass" ); ++ Button failB = new Button( "fail" ); ++ ++ //DO NOT call this directly, go through Sysout ++ public TestDialog( Frame frame, String name ) ++ { ++ super( frame, name ); ++ int scrollBoth = TextArea.SCROLLBARS_BOTH; ++ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); ++ add( "North", instructionsText ); ++ ++ messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); ++ add("Center", messageText); ++ ++ passB = new Button( "pass" ); ++ passB.setActionCommand( "pass" ); ++ passB.addActionListener( this ); ++ buttonP.add( "East", passB ); ++ ++ failB = new Button( "fail" ); ++ failB.setActionCommand( "fail" ); ++ failB.addActionListener( this ); ++ buttonP.add( "West", failB ); ++ ++ add( "South", buttonP ); ++ pack(); ++ ++ setVisible(true); ++ }// TestDialog() ++ ++ //DO NOT call this directly, go through Sysout ++ public void printInstructions( String[] instructions ) ++ { ++ //Clear out any current instructions ++ instructionsText.setText( "" ); ++ ++ //Go down array of instruction strings ++ ++ String printStr, remainingStr; ++ for( int i=0; i < instructions.length; i++ ) ++ { ++ //chop up each into pieces maxSringLength long ++ remainingStr = instructions[ i ]; ++ while( remainingStr.length() > 0 ) ++ { ++ //if longer than max then chop off first max chars to print ++ if( remainingStr.length() >= maxStringLength ) ++ { ++ //Try to chop on a word boundary ++ int posOfSpace = remainingStr. ++ lastIndexOf( ' ', maxStringLength - 1 ); ++ ++ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; ++ ++ printStr = remainingStr.substring( 0, posOfSpace + 1 ); ++ remainingStr = remainingStr.substring( posOfSpace + 1 ); ++ } ++ //else just print ++ else ++ { ++ printStr = remainingStr; ++ remainingStr = ""; ++ } ++ ++ instructionsText.append( printStr + "\n" ); ++ ++ }// while ++ ++ }// for ++ ++ }//printInstructions() ++ ++ //DO NOT call this directly, go through Sysout ++ public void displayMessage( String messageIn ) ++ { ++ messageText.append( messageIn + "\n" ); ++ System.out.println(messageIn); ++ } ++ ++ //catch presses of the passed and failed buttons. ++ //simply call the standard pass() or fail() static methods of ++ //ManualMainTest ++ public void actionPerformed( ActionEvent e ) ++ { ++ if( e.getActionCommand() == "pass" ) ++ { ++ Winkey.pass(); ++ } ++ else ++ { ++ Winkey.fail(); ++ } ++ } ++ ++}// TestDialog class +exporting patch: +<fdopen>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6610244-modal-fatal-error-windows.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,125 @@ +# HG changeset patch +# User dav +# Date 1206447363 -10800 +# Node ID 58c90502785df64cd26e9f2d400429dcfcaa3b91 +# Parent de9e902b1f24bef3ec7248890caa1722983e68f5 +6610244: modal dialog closes with fatal error if -Xcheck:jni is set +Summary: obtain WWindowPeer class every time it is required +Reviewed-by: art + +diff -r de9e902b1f24 -r 58c90502785d src/windows/native/sun/windows/awt_Dialog.cpp +--- openjdk.orig/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Mon Mar 24 18:24:15 2008 +0300 ++++ openjdk/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Tue Mar 25 15:16:03 2008 +0300 +@@ -428,8 +428,12 @@ + { + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + +- jlongArray windows = (jlongArray)(env->CallStaticObjectMethod(AwtWindow::wwindowPeerCls, +- AwtWindow::getActiveWindowsMID)); ++ jclass wwindowPeerCls = env->FindClass("sun/awt/windows/WWindowPeer"); ++ jmethodID getActiveWindowsMID = env->GetStaticMethodID(wwindowPeerCls, ++ "getActiveWindowHandles", "()[J"); ++ DASSERT(getActiveWindowsMID != NULL); ++ jlongArray windows = (jlongArray)(env->CallStaticObjectMethod(wwindowPeerCls, ++ getActiveWindowsMID)); + if (windows == NULL) { + return; + } +diff -r de9e902b1f24 -r 58c90502785d src/windows/native/sun/windows/awt_Window.cpp +--- openjdk.orig/jdk/src/windows/native/sun/windows/awt_Window.cpp Mon Mar 24 18:24:15 2008 +0300 ++++ openjdk/jdk/src/windows/native/sun/windows/awt_Window.cpp Tue Mar 25 15:16:03 2008 +0300 +@@ -122,9 +122,6 @@ + jfieldID AwtWindow::locationByPlatformID; + jfieldID AwtWindow::autoRequestFocusID; + +-jclass AwtWindow::wwindowPeerCls; +-jmethodID AwtWindow::getActiveWindowsMID; +- + jfieldID AwtWindow::sysXID; + jfieldID AwtWindow::sysYID; + jfieldID AwtWindow::sysWID; +diff -r de9e902b1f24 -r 58c90502785d src/windows/native/sun/windows/awt_Window.h +--- openjdk.orig/jdk/src/windows/native/sun/windows/awt_Window.h Mon Mar 24 18:24:15 2008 +0300 ++++ openjdk/jdk/src/windows/native/sun/windows/awt_Window.h Tue Mar 25 15:16:03 2008 +0300 +@@ -57,11 +57,6 @@ + static jfieldID screenID; /* screen number passed over from WindowPeer */ + static jfieldID autoRequestFocusID; + +- /* WWindowPeer class */ +- static jclass wwindowPeerCls; +- /* long[] getActiveWindowHandles() method in WWindowPeer */ +- static jmethodID getActiveWindowsMID; +- + // The coordinates at the peer. + static jfieldID sysXID; + static jfieldID sysYID; +diff -r de9e902b1f24 -r 58c90502785d test/java/awt/Dialog/CrashXCheckJni/CrashXCheckJni.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/awt/Dialog/CrashXCheckJni/CrashXCheckJni.java Tue Mar 25 15:16:03 2008 +0300 +@@ -0,0 +1,64 @@ ++/* ++ * 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 6610244 ++ @library ../../regtesthelpers ++ @build Util Sysout AbstractTest ++ @summary modal dialog closes with fatal error if -Xcheck:jni is set ++ @author Andrei Dmitriev : area=awt.dialog ++ @run main/othervm -Xcheck:jni CrashXCheckJni ++*/ ++ ++import java.awt.*; ++import java.awt.event.*; ++import java.util.Timer; ++import java.util.TimerTask; ++import test.java.awt.regtesthelpers.Util; ++import test.java.awt.regtesthelpers.AbstractTest; ++import test.java.awt.regtesthelpers.Sysout; ++ ++public class CrashXCheckJni { ++ ++ public static void main(String []s) ++ { ++ final Dialog fd = new Dialog(new Frame(), true); ++ Timer t = new Timer(); ++ t.schedule(new TimerTask() { ++ ++ public void run() { ++ System.out.println("RUNNING TASK"); ++ fd.setVisible(false); ++ fd.dispose(); ++ System.out.println("FINISHING TASK"); ++ } ++ }, 3000L); ++ ++ fd.setVisible(true); ++ t.cancel(); ++ Util.waitForIdle(null); ++ ++ AbstractTest.pass(); ++ } ++} +exporting patch: +<fdopen>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6623219-Font_canDisplayUpTo_does_not_work.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,204 @@ +# HG changeset patch +# User okutsu +# Date 1298437763 -32400 +# Node ID 5957bd3cfdc3fa2014ff1d9abbb51fbb2f8a5779 +# Parent f8fdf9bca1592dd55ff0fad08114cbd00e08c77d +6623219: Font.canDisplayUpTo does not work with supplementary characters +Reviewed-by: prr, peytoia + +diff -r f8fdf9bca159 -r 5957bd3cfdc3 src/share/classes/java/awt/Font.java +--- openjdk.orig/jdk/src/share/classes/java/awt/Font.java Tue Feb 22 14:51:43 2011 +0900 ++++ openjdk/jdk/src/share/classes/java/awt/Font.java Wed Feb 23 14:09:23 2011 +0900 +@@ -1985,8 +1985,22 @@ + * @since 1.2 + */ + public int canDisplayUpTo(String str) { +- return canDisplayUpTo(new StringCharacterIterator(str), 0, +- str.length()); ++ Font2D font2d = getFont2D(); ++ int len = str.length(); ++ for (int i = 0; i < len; i++) { ++ char c = str.charAt(i); ++ if (font2d.canDisplay(c)) { ++ continue; ++ } ++ if (!Character.isHighSurrogate(c)) { ++ return i; ++ } ++ if (!font2d.canDisplay(str.codePointAt(i))) { ++ return i; ++ } ++ i++; ++ } ++ return -1; + } + + /** +@@ -2009,11 +2023,21 @@ + * @since 1.2 + */ + public int canDisplayUpTo(char[] text, int start, int limit) { +- while (start < limit && canDisplay(text[start])) { +- ++start; ++ Font2D font2d = getFont2D(); ++ for (int i = start; i < limit; i++) { ++ char c = text[i]; ++ if (font2d.canDisplay(c)) { ++ continue; ++ } ++ if (!Character.isHighSurrogate(c)) { ++ return i; ++ } ++ if (!font2d.canDisplay(Character.codePointAt(text, i, limit))) { ++ return i; ++ } ++ i++; + } +- +- return start == limit ? -1 : start; ++ return -1; + } + + /** +@@ -2034,13 +2058,26 @@ + * @since 1.2 + */ + public int canDisplayUpTo(CharacterIterator iter, int start, int limit) { +- for (char c = iter.setIndex(start); +- iter.getIndex() < limit && canDisplay(c); +- c = iter.next()) { ++ Font2D font2d = getFont2D(); ++ char c = iter.setIndex(start); ++ for (int i = start; i < limit; i++, c = iter.next()) { ++ if (font2d.canDisplay(c)) { ++ continue; ++ } ++ if (!Character.isHighSurrogate(c)) { ++ return i; ++ } ++ char c2 = iter.next(); ++ // c2 could be CharacterIterator.DONE which is not a low surrogate. ++ if (!Character.isLowSurrogate(c2)) { ++ return i; ++ } ++ if (!font2d.canDisplay(Character.toCodePoint(c, c2))) { ++ return i; ++ } ++ i++; + } +- +- int result = iter.getIndex(); +- return result == limit ? -1 : result; ++ return -1; + } + + /** +diff -r f8fdf9bca159 -r 5957bd3cfdc3 test/java/awt/FontClass/SurrogateTest/SupplementaryCanDisplayUpToTest.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/awt/FontClass/SurrogateTest/SupplementaryCanDisplayUpToTest.java Wed Feb 23 14:09:23 2011 +0900 +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++/* ++ * @test ++ * @bug 6623219 ++ * @summary Test canDisplayUpTo with supplementary characters. ++ */ ++ ++import java.awt.*; ++import java.text.*; ++ ++public class SupplementaryCanDisplayUpToTest { ++ // Lists consisting of a font name, test text, and its expected ++ // return value. Test text uses private area code point U+F0000 ++ // (\udb80\udc00). ++ private static String[][] DATA = { ++ // Windows ++ { "Meiryo", "\ud87e\udd45\ud87e\udd47\udb80\udc00", "4" }, ++ { "Meiryo", "\ud87e\udd45\ud87e\udd47\udb80Z", "4" }, ++ { "Meiryo", "\ud87e\udd45\ud87e\udd47\udb80", "4" }, ++ { "Meiryo", "\ud87e\udd45\ud87e\udd47\udc00", "4" }, ++ { "Meiryo", "\ud87e\udd45\ud87e\udd47", "-1" }, ++ ++ // Linux ++ { "AR PL UMing TW", "\ud87e\udc25\ud87e\udc3b\udb80\udc00", "4" }, ++ { "AR PL UMing TW", "\ud87e\udc25\ud87e\udc3b\udb80Z", "4" }, ++ { "AR PL UMing TW", "\ud87e\udc25\ud87e\udc3b\udb80", "4" }, ++ { "AR PL UMing TW", "\ud87e\udc25\ud87e\udc3b\udc00", "4" }, ++ { "AR PL UMing TW", "\ud87e\udc25\ud87e\udc3b", "-1" }, ++ ++ // Solaris ++ { "FZMingTi", "\ud87e\udc25\ud87e\udc3b\udb80\udc00", "4" }, ++ { "FZMingTi", "\ud87e\udc25\ud87e\udc3b\udb80Z", "4" }, ++ { "FZMingTi", "\ud87e\udc25\ud87e\udc3b\udb80", "4" }, ++ { "FZMingTi", "\ud87e\udc25\ud87e\udc3b\udc00", "4" }, ++ { "FZMingTi", "\ud87e\udc25\ud87e\udc3b", "-1" }, ++ }; ++ private static int errorcount = 0; ++ ++ public static void main(String[] args) { ++ for (String[] data : DATA) { ++ String fontname = data[0]; ++ Font font = new Font(fontname, Font.PLAIN, 16); ++ if (font.getFamily().equals(Font.DIALOG)) { ++ // Skip any unavailable fonts. ++ continue; ++ } ++ ++ System.out.printf("Testing with font '%s'... ", fontname); ++ int errors = 0; ++ String text = data[1]; ++ int expected = Integer.parseInt(data[2]); ++ ++ int result = font.canDisplayUpTo(text); ++ if (result != expected) { ++ System.err.println("canDisplayUpTo(String) returns " + result); ++ errors++; ++ } ++ ++ result = font.canDisplayUpTo(text.toCharArray(), 0, text.length()); ++ if (result != expected) { ++ System.err.println("canDisplayUpTo(char[], int, int) returns " + result); ++ errors++; ++ } ++ ++ CharacterIterator iter = new StringCharacterIterator(text); ++ result = font.canDisplayUpTo(iter, iter.getBeginIndex(), iter.getEndIndex()); ++ if (result != expected) { ++ System.err.println("canDisplayUpTo(CharacterIterator, int, int) returns " + result); ++ errors++; ++ } ++ ++ if (errors == 0) { ++ System.out.println("passed"); ++ } else { ++ System.out.println("failed"); ++ errorcount += errors; ++ } ++ } ++ if (errorcount > 0) { ++ throw new RuntimeException("SupplementaryCanDisplayUpToTest: failed"); ++ } ++ } ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6679308-Poor_text_rendering_on_translucent_image.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,535 @@ +# HG changeset patch +# User prr +# Date 1209423466 25200 +# Node ID d7accc312aec0905bb1ad1685c8aa8f66cfd84cb +# Parent f50304904b8f181be07595be0e88416186001088 +6679308: Poor text rendering on translucent image. +Reviewed-by: flar, campbell + +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/AlphaMacros.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/AlphaMacros.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/AlphaMacros.h Mon Apr 28 15:57:46 2008 -0700 +@@ -416,7 +416,8 @@ + MultiplyAndStore ## STRATEGY ## Comps(res, \ + srcF, res);\ + } \ +- if (!(DST ## IsPremultiplied) && resA && \ ++ if (!(DST ## IsOpaque) && \ ++ !(DST ## IsPremultiplied) && resA && \ + resA < MaxValFor ## STRATEGY) \ + { \ + DivideAndStore ## STRATEGY ## Comps(res, \ +@@ -475,7 +476,8 @@ + MultiplyAndStore ## STRATEGY ## Comps(res, \ + srcF, res); \ + } \ +- if (!(DST ## IsPremultiplied) && resA && \ ++ if (!(DST ## IsOpaque) && \ ++ !(DST ## IsPremultiplied) && resA && \ + resA < MaxValFor ## STRATEGY) \ + { \ + DivideAndStore ## STRATEGY ## Comps(res, res, resA); \ +@@ -797,7 +799,8 @@ + Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \ + } \ + } \ +- if (!(TYPE ## IsPremultiplied) && resA && \ ++ if (!(TYPE ## IsOpaque) && \ ++ !(TYPE ## IsPremultiplied) && resA && \ + resA < MaxValFor ## STRATEGY) \ + { \ + DivideAndStore ## STRATEGY ## Comps(res, res, resA); \ +@@ -831,7 +834,8 @@ + Postload ## STRATEGY ## From ## TYPE(pRas, DstPix, res); \ + MultiplyAddAndStore ## STRATEGY ## Comps(res, \ + dstF, res, src); \ +- if (!(TYPE ## IsPremultiplied) && resA && \ ++ if (!(TYPE ## IsOpaque) && \ ++ !(TYPE ## IsPremultiplied) && resA && \ + resA < MaxValFor ## STRATEGY) \ + { \ + DivideAndStore ## STRATEGY ## Comps(res, res, resA); \ +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/ByteGray.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/ByteGray.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/ByteGray.h Mon Apr 28 15:57:46 2008 -0700 +@@ -36,6 +36,8 @@ + typedef jubyte ByteGrayPixelType; + typedef jubyte ByteGrayDataType; + ++#define ByteGrayIsOpaque 1 ++ + #define ByteGrayPixelStride 1 + #define ByteGrayBitsPerPixel 8 + +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/FourByteAbgr.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/FourByteAbgr.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/FourByteAbgr.h Mon Apr 28 15:57:46 2008 -0700 +@@ -34,6 +34,8 @@ + typedef jint FourByteAbgrPixelType; + typedef jubyte FourByteAbgrDataType; + ++#define FourByteAbgrIsOpaque 0 ++ + #define FourByteAbgrPixelStride 4 + + #define DeclareFourByteAbgrLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/FourByteAbgrPre.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/FourByteAbgrPre.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/FourByteAbgrPre.h Mon Apr 28 15:57:46 2008 -0700 +@@ -34,6 +34,8 @@ + typedef jint FourByteAbgrPrePixelType; + typedef jubyte FourByteAbgrPreDataType; + ++#define FourByteAbgrPreIsOpaque 0 ++ + #define FourByteAbgrPrePixelStride 4 + + #define DeclareFourByteAbgrPreLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/Index12Gray.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/Index12Gray.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/Index12Gray.h Mon Apr 28 15:57:46 2008 -0700 +@@ -37,6 +37,8 @@ + typedef jushort Index12GrayPixelType; + typedef jushort Index12GrayDataType; + ++#define Index12GrayIsOpaque 1 ++ + #define Index12GrayPixelStride 2 + #define Index12GrayBitsPerPixel 12 + +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/Index8Gray.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/Index8Gray.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/Index8Gray.h Mon Apr 28 15:57:46 2008 -0700 +@@ -37,6 +37,8 @@ + typedef jubyte Index8GrayPixelType; + typedef jubyte Index8GrayDataType; + ++#define Index8GrayIsOpaque 1 ++ + #define Index8GrayPixelStride 1 + #define Index8GrayBitsPerPixel 8 + +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/IntArgb.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/IntArgb.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/IntArgb.h Mon Apr 28 15:57:46 2008 -0700 +@@ -38,6 +38,8 @@ + typedef jint IntArgbPixelType; + typedef jint IntArgbDataType; + ++#define IntArgbIsOpaque 0 ++ + #define IntArgbPixelStride 4 + + #define DeclareIntArgbLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/IntArgbBm.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/IntArgbBm.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/IntArgbBm.h Mon Apr 28 15:57:46 2008 -0700 +@@ -38,6 +38,8 @@ + typedef jint IntArgbBmPixelType; + typedef jint IntArgbBmDataType; + ++#define IntArgbBmIsOpaque 0 ++ + #define IntArgbBmPixelStride 4 + + #define DeclareIntArgbBmLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/IntArgbPre.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/IntArgbPre.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/IntArgbPre.h Mon Apr 28 15:57:46 2008 -0700 +@@ -36,6 +36,8 @@ + typedef jint IntArgbPrePixelType; + typedef jint IntArgbPreDataType; + ++#define IntArgbPreIsOpaque 0 ++ + #define IntArgbPrePixelStride 4 + + #define DeclareIntArgbPreLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/IntBgr.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/IntBgr.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/IntBgr.h Mon Apr 28 15:57:46 2008 -0700 +@@ -38,6 +38,8 @@ + typedef jint IntBgrPixelType; + typedef jint IntBgrDataType; + ++#define IntBgrIsOpaque 1 ++ + #define IntBgrPixelStride 4 + + #define DeclareIntBgrLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/IntRgb.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/IntRgb.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/IntRgb.h Mon Apr 28 15:57:46 2008 -0700 +@@ -38,6 +38,8 @@ + typedef jint IntRgbPixelType; + typedef jint IntRgbDataType; + ++#define IntRgbIsOpaque 1 ++ + #define IntRgbPixelStride 4 + + #define DeclareIntRgbLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/IntRgbx.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/IntRgbx.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/IntRgbx.h Mon Apr 28 15:57:46 2008 -0700 +@@ -36,6 +36,8 @@ + typedef jint IntRgbxPixelType; + typedef jint IntRgbxDataType; + ++#define IntRgbxIsOpaque 1 ++ + #define IntRgbxPixelStride 4 + + #define DeclareIntRgbxLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/LoopMacros.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/LoopMacros.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/LoopMacros.h Mon Apr 28 15:57:46 2008 -0700 +@@ -1610,8 +1610,12 @@ + MUL8(SRC_PREFIX ## A, mixValSrc); \ + MultMultAddAndStore4ByteArgbComps(dst, mixValDst, dst, \ + mixValSrc, SRC_PREFIX); \ +- Store ## DST ## From4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \ +- dstA, dstR, dstG, dstB); \ ++ if (!(DST ## IsOpaque) && \ ++ !(DST ## IsPremultiplied) && dstA && dstA < 255) { \ ++ DivideAndStore4ByteArgbComps(dst, dst, dstA); \ ++ } \ ++ Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \ ++ PIXEL_INDEX, dst); \ + } else { \ + Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ + FG_PIXEL, PREFIX); \ +@@ -1793,8 +1797,12 @@ + dstR = gammaLut[dstR]; \ + dstG = gammaLut[dstG]; \ + dstB = gammaLut[dstB]; \ +- Store ## DST ## From4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \ +- dstA, dstR, dstG, dstB); \ ++ if (!(DST ## IsOpaque) && \ ++ !(DST ## IsPremultiplied) && dstA && dstA < 255) { \ ++ DivideAndStore4ByteArgbComps(dst, dst, dstA); \ ++ } \ ++ Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \ ++ PIXEL_INDEX, dst); \ + } else { \ + Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ + FG_PIXEL, PREFIX); \ +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/ThreeByteBgr.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/ThreeByteBgr.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/ThreeByteBgr.h Mon Apr 28 15:57:46 2008 -0700 +@@ -34,6 +34,8 @@ + typedef jint ThreeByteBgrPixelType; + typedef jubyte ThreeByteBgrDataType; + ++#define ThreeByteBgrIsOpaque 1 ++ + #define ThreeByteBgrPixelStride 3 + + #define DeclareThreeByteBgrLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/Ushort4444Argb.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/Ushort4444Argb.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/Ushort4444Argb.h Mon Apr 28 15:57:46 2008 -0700 +@@ -34,6 +34,8 @@ + typedef jushort Ushort4444ArgbPixelType; + typedef jushort Ushort4444ArgbDataType; + ++#define Ushort4444ArgbIsOpaque 0 ++ + #define Ushort4444ArgbPixelStride 2 + + #define DeclareUshort4444ArgbLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/Ushort555Rgb.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/Ushort555Rgb.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/Ushort555Rgb.h Mon Apr 28 15:57:46 2008 -0700 +@@ -34,6 +34,8 @@ + typedef jushort Ushort555RgbPixelType; + typedef jushort Ushort555RgbDataType; + ++#define Ushort555RgbIsOpaque 1 ++ + #define Ushort555RgbPixelStride 2 + + #define DeclareUshort555RgbLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/Ushort555Rgbx.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/Ushort555Rgbx.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/Ushort555Rgbx.h Mon Apr 28 15:57:46 2008 -0700 +@@ -34,6 +34,8 @@ + typedef jushort Ushort555RgbxPixelType; + typedef jushort Ushort555RgbxDataType; + ++#define Ushort555RgbxIsOpaque 1 ++ + #define Ushort555RgbxPixelStride 2 + + #define DeclareUshort555RgbxLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/Ushort565Rgb.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/Ushort565Rgb.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/Ushort565Rgb.h Mon Apr 28 15:57:46 2008 -0700 +@@ -34,6 +34,8 @@ + typedef jushort Ushort565RgbPixelType; + typedef jushort Ushort565RgbDataType; + ++#define Ushort565RgbIsOpaque 1 ++ + #define Ushort565RgbPixelStride 2 + + #define DeclareUshort565RgbLoadVars(PREFIX) +diff -r f50304904b8f -r d7accc312aec src/share/native/sun/java2d/loops/UshortGray.h +--- openjdk.orig/jdk/src/share/native/sun/java2d/loops/UshortGray.h Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/share/native/sun/java2d/loops/UshortGray.h Mon Apr 28 15:57:46 2008 -0700 +@@ -36,6 +36,8 @@ + typedef jushort UshortGrayPixelType; + typedef jushort UshortGrayDataType; + ++#define UshortGrayIsOpaque 1 ++ + #define UshortGrayPixelStride 2 + #define UshortGrayBitsPerPixel 16 + +diff -r f50304904b8f -r d7accc312aec src/solaris/native/sun/java2d/loops/vis_FourByteAbgr.c +--- openjdk.orig/jdk/src/solaris/native/sun/java2d/loops/vis_FourByteAbgr.c Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/solaris/native/sun/java2d/loops/vis_FourByteAbgr.c Mon Apr 28 15:57:46 2008 -0700 +@@ -1936,6 +1936,7 @@ + for (j = 0; j < height; j++) { + mlib_u8 *src = (void*)pixels; + mlib_s32 *dst, *dst_end; ++ mlib_u8 *dst_start; + + if ((mlib_s32)dstBase & 3) { + COPY_NA(dstBase, pbuff, width*sizeof(mlib_s32)); +@@ -1943,8 +1944,14 @@ + } else { + dst = (void*)dstBase; + } ++ dst_start = (void*)dst; + dst_end = dst + width; + ++ /* Need to reset the GSR from the values set by the ++ * convert call near the end of this loop. ++ */ ++ vis_write_gsr(7 << 0); ++ + if ((mlib_s32)dst & 7) { + pix = *src++; + dd = vis_fpadd16(MUL8_VIS(srcG_f, pix), d_half); +@@ -1984,8 +1991,13 @@ + dst++; + } + ++ ADD_SUFF(IntArgbPreToIntArgbConvert)(dst_start, dst_start, ++ width, 1, ++ pRasInfo, pRasInfo, ++ pPrim, pCompInfo); ++ + if ((mlib_s32)dstBase & 3) { +- COPY_NA(pbuff, dstBase, width*sizeof(mlib_s32)); ++ COPY_NA(dst_start, dstBase, width*sizeof(mlib_s32)); + } + + PTR_ADD(dstBase, scan); +diff -r f50304904b8f -r d7accc312aec src/solaris/native/sun/java2d/loops/vis_FourByteAbgrPre.c +--- openjdk.orig/jdk/src/solaris/native/sun/java2d/loops/vis_FourByteAbgrPre.c Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/solaris/native/sun/java2d/loops/vis_FourByteAbgrPre.c Mon Apr 28 15:57:46 2008 -0700 +@@ -181,6 +181,7 @@ + d_half = vis_to_double_dup((1 << (16 + 6)) | (1 << 6)); + + srcG_f = vis_to_float(argbcolor); ++ ARGB2ABGR_FL(srcG_f); + + for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) { + const jubyte *pixels; +@@ -238,8 +239,33 @@ + mlib_u8 *src = (void*)pixels; + mlib_s32 *dst, *dst_end; + mlib_u8 *dst8; ++ mlib_u8* dst_start = dstBase; + +- ADD_SUFF(FourByteAbgrPreToIntArgbConvert)(dstBase, pbuff, width, 1, ++ /* ++ * Typically the inner loop here works on Argb input data, an ++ * Argb color, and produces ArgbPre output data. To use that ++ * standard approach we would need a FourByteAbgrPre to IntArgb ++ * converter for the front end and an IntArgbPre to FourByteAbgrPre ++ * converter for the back end. The converter exists for the ++ * front end, but it is a workaround implementation that uses a 2 ++ * stage conversion and an intermediate buffer that is allocated ++ * on every call. The converter for the back end doesn't really ++ * exist, but we could reuse the IntArgb to FourByteAbgr converter ++ * to do the same work - at the cost of swapping the components as ++ * we copy the data back. All of this is more work than we really ++ * need so we use an alternate procedure: ++ * - Copy the data into an int-aligned temporary buffer (if needed) ++ * - Convert the data from FourByteAbgrPre to IntAbgr by using the ++ * IntArgbPre to IntArgb converter in the int-aligned buffer. ++ * - Swap the color data to Abgr so that the inner loop goes from ++ * IntAbgr data to IntAbgrPre data ++ * - Simply copy the IntAbgrPre data back into place. ++ */ ++ if (((mlib_s32)dstBase) & 3) { ++ COPY_NA(dstBase, pbuff, width*sizeof(mlib_s32)); ++ dst_start = pbuff; ++ } ++ ADD_SUFF(IntArgbPreToIntArgbConvert)(dst_start, pbuff, width, 1, + pRasInfo, pRasInfo, + pPrim, pCompInfo); + +@@ -283,9 +309,7 @@ + dst++; + } + +- ADD_SUFF(IntArgbToFourByteAbgrPreConvert)(pbuff, dstBase, width, 1, +- pRasInfo, pRasInfo, +- pPrim, pCompInfo); ++ COPY_NA(pbuff, dstBase, width*sizeof(mlib_s32)); + + src = (void*)pixels; + dst8 = (void*)dstBase; +diff -r f50304904b8f -r d7accc312aec src/solaris/native/sun/java2d/loops/vis_IntArgb.c +--- openjdk.orig/jdk/src/solaris/native/sun/java2d/loops/vis_IntArgb.c Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/solaris/native/sun/java2d/loops/vis_IntArgb.c Mon Apr 28 15:57:46 2008 -0700 +@@ -428,6 +428,11 @@ + dst = (void*)dstBase; + dst_end = dst + width; + ++ /* Clearing the Graphics Status Register is necessary otherwise ++ * left over scale settings affect the pack instructions. ++ */ ++ vis_write_gsr(0 << 3); ++ + if ((mlib_s32)dst & 7) { + pix = *src++; + dd = vis_fpadd16(MUL8_VIS(srcG_f, pix), d_half); +@@ -467,6 +472,9 @@ + dst++; + } + ++ ADD_SUFF(IntArgbPreToIntArgbConvert)(dstBase, dstBase, width, 1, ++ pRasInfo, pRasInfo, ++ pPrim, pCompInfo); + PTR_ADD(dstBase, scan); + pixels += rowBytes; + } +diff -r f50304904b8f -r d7accc312aec src/solaris/native/sun/java2d/loops/vis_IntArgbPre.c +--- openjdk.orig/jdk/src/solaris/native/sun/java2d/loops/vis_IntArgbPre.c Mon Apr 28 11:06:18 2008 -0700 ++++ openjdk/jdk/src/solaris/native/sun/java2d/loops/vis_IntArgbPre.c Mon Apr 28 15:57:46 2008 -0700 +@@ -1193,10 +1193,6 @@ + dst++; + } + +- ADD_SUFF(IntArgbToIntArgbPreConvert)(dstBase, dstBase, width, 1, +- pRasInfo, pRasInfo, +- pPrim, pCompInfo); +- + PTR_ADD(dstBase, scan); + pixels += rowBytes; + } +diff -r f50304904b8f -r d7accc312aec test/java/awt/Graphics2D/DrawString/AlphaSurfaceText.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/test/java/awt/Graphics2D/DrawString/AlphaSurfaceText.java Mon Apr 28 15:57:46 2008 -0700 +@@ -0,0 +1,106 @@ ++/* ++ * 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 6679308 ++ * @summary test drawing to Alpha surfaces ++ */ ++ ++import java.awt.*; ++import java.awt.image.*; ++ ++public class AlphaSurfaceText { ++ ++ int wid=400, hgt=200; ++ ++ public AlphaSurfaceText(int biType, Color c) { ++ BufferedImage opaquebi0 = ++ new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB); ++ drawText(opaquebi0, c); ++ ++ BufferedImage alphabi = new BufferedImage(wid, hgt, biType); ++ drawText(alphabi, c); ++ BufferedImage opaquebi1 = ++ new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB); ++ Graphics2D g2d = opaquebi1.createGraphics(); ++ g2d.drawImage(alphabi, 0, 0, null); ++ compare(opaquebi0, opaquebi1, biType, c); ++ } ++ ++ private void drawText(BufferedImage bi, Color c) { ++ Graphics2D g = bi.createGraphics(); ++ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, ++ RenderingHints.VALUE_TEXT_ANTIALIAS_ON); ++ g.setColor(c); ++ g.setFont(new Font("sansserif", Font.PLAIN, 70)); ++ g.drawString("Hello!", 20, 100); ++ g.setFont(new Font("sansserif", Font.PLAIN, 12)); ++ g.drawString("Hello!", 20, 130); ++ g.setFont(new Font("sansserif", Font.PLAIN, 10)); ++ g.drawString("Hello!", 20, 150); ++ } ++ ++ // Need to allow for minimal rounding error, so allow each component ++ // to differ by 1. ++ void compare(BufferedImage bi0, BufferedImage bi1, int biType, Color c) { ++ for (int x=0; x<wid; x++) { ++ for (int y=0; y<hgt; y++) { ++ int rgb0 = bi0.getRGB(x, y); ++ int rgb1 = bi1.getRGB(x, y); ++ if (rgb0 == rgb1) continue; ++ int r0 = (rgb0 & 0xff0000) >> 16; ++ int r1 = (rgb1 & 0xff0000) >> 16; ++ int rdiff = r0-r1; if (rdiff<0) rdiff = -rdiff; ++ int g0 = (rgb0 & 0x00ff00) >> 8; ++ int g1 = (rgb1 & 0x00ff00) >> 8; ++ int gdiff = g0-g1; if (gdiff<0) gdiff = -gdiff; ++ int b0 = (rgb0 & 0x0000ff); ++ int b1 = (rgb1 & 0x0000ff); ++ int bdiff = b0-b1; if (bdiff<0) bdiff = -bdiff; ++ if (rdiff > 1 || gdiff > 1 || bdiff > 1) { ++ throw new RuntimeException( ++ "Images differ for type "+biType + " col="+c + ++ " at x=" + x + " y="+ y + " " + ++ Integer.toHexString(rgb0) + " vs " + ++ Integer.toHexString(rgb1)); ++ } ++ } ++ } ++ ++ } ++ public static void main(String[] args) { ++ new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.white); ++ new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.red); ++ new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.blue); ++ new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.white); ++ new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.red); ++ new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.blue); ++ new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.white); ++ new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.red); ++ new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.blue); ++ new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.white); ++ new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.red); ++ new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.blue); ++ } ++}
--- a/patches/openjdk/6693253-security_warning.patch Wed Jun 01 02:35:43 2011 +0100 +++ b/patches/openjdk/6693253-security_warning.patch Wed Jul 06 17:11:34 2011 +0100 @@ -3280,19 +3280,18 @@ diff -Nru openjdk.orig/jdk/src/windows/native/sun/windows/awt_Dialog.cpp openjdk/jdk/src/windows/native/sun/windows/awt_Dialog.cpp --- openjdk.orig/jdk/src/windows/native/sun/windows/awt_Dialog.cpp 2011-01-20 23:54:44.000000000 +0000 +++ openjdk/jdk/src/windows/native/sun/windows/awt_Dialog.cpp 2011-02-17 15:50:10.732056235 +0000 -@@ -284,9 +284,7 @@ - if ((::WindowFromPoint(mhs->pt) == hWnd) && - (::GetForegroundWindow() == topMostBlocker)) - { -- ::MessageBeep(MB_OK); -- // some heuristics: 3 times x 64 milliseconds -- AwtWindow::FlashWindowEx(topMostBlocker, 3, 64, FLASHW_CAPTION); -+ AnimateModalBlocker(dialog); - } - if (topMostBlocker != AwtToolkit::GetInstance().GetHWnd()) { - ::BringWindowToTop(topMostBlocker); -@@ -299,6 +297,13 @@ - return CallNextHookEx(0, nCode, wParam, lParam); +@@ -310,15 +310,20 @@ + // no beep/flash if the mouse was clicked in the taskbar menu + // or the dialog is currently inactive + if (!isModalHook && !onTaskbar && (dialog == prevFGWindow)) { +- ::MessageBeep(MB_OK); +- // some heuristics: 3 times x 64 milliseconds +- AwtWindow::FlashWindowEx(dialog, 3, 64, FLASHW_CAPTION); ++ AnimateModalBlocker(dialog); + } + ::BringWindowToTop(dialog); + ::SetForegroundWindow(dialog); + } } +void AwtDialog::AnimateModalBlocker(HWND window)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6699843-IllegalArgumentException_drawString.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,133 @@ +# HG changeset patch +# User prr +# Date 1210720710 25200 +# Node ID fb61ff1cc5fd6850289e94b69b5308dadafc0bf9 +# Parent 55e6548451dfdc5e9c8b00a39930d53c70b578a0 +6699843: IllegalArgumentException when using Graphics.drawString( "", 0, 0 ) +Reviewed-by: igor, tdv + +diff -r 55e6548451df -r fb61ff1cc5fd src/share/classes/sun/java2d/SunGraphics2D.java +--- openjdk.orig/jdk/src/share/classes/sun/java2d/SunGraphics2D.java Wed Apr 30 13:10:39 2008 -0700 ++++ openjdk/jdk/src/share/classes/sun/java2d/SunGraphics2D.java Tue May 13 16:18:30 2008 -0700 +@@ -2805,6 +2805,9 @@ + } + + if (font.hasLayoutAttributes()) { ++ if (str.length() == 0) { ++ return; ++ } + new TextLayout(str, font, getFontRenderContext()).draw(this, x, y); + return; + } +@@ -2831,6 +2834,9 @@ + } + + if (font.hasLayoutAttributes()) { ++ if (str.length() == 0) { ++ return; ++ } + new TextLayout(str, font, getFontRenderContext()).draw(this, x, y); + return; + } +@@ -2856,6 +2862,9 @@ + if (iterator == null) { + throw new NullPointerException("AttributedCharacterIterator is null"); + } ++ if (iterator.getBeginIndex() == iterator.getEndIndex()) { ++ return; /* nothing to draw */ ++ } + TextLayout tl = new TextLayout(iterator, getFontRenderContext()); + tl.draw(this, (float) x, (float) y); + } +@@ -2865,6 +2874,9 @@ + if (iterator == null) { + throw new NullPointerException("AttributedCharacterIterator is null"); + } ++ if (iterator.getBeginIndex() == iterator.getEndIndex()) { ++ return; /* nothing to draw */ ++ } + TextLayout tl = new TextLayout(iterator, getFontRenderContext()); + tl.draw(this, x, y); + } +@@ -2900,6 +2912,9 @@ + throw new ArrayIndexOutOfBoundsException("bad offset/length"); + } + if (font.hasLayoutAttributes()) { ++ if (data.length == 0) { ++ return; ++ } + new TextLayout(new String(data, offset, length), + font, getFontRenderContext()).draw(this, x, y); + return; +@@ -2934,6 +2949,9 @@ + chData[i] = (char)(data[i+offset] & 0xff); + } + if (font.hasLayoutAttributes()) { ++ if (data.length == 0) { ++ return; ++ } + new TextLayout(new String(chData), + font, getFontRenderContext()).draw(this, x, y); + return; +diff -r 55e6548451df -r fb61ff1cc5fd test/java/awt/Graphics2D/DrawString/EmptyAttrString.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/awt/Graphics2D/DrawString/EmptyAttrString.java Tue May 13 16:18:30 2008 -0700 +@@ -0,0 +1,58 @@ ++/* ++ * 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 6699843 ++ * @summary IllegalArgumentException when using Graphics.drawString( "", 0, 0 ) ++ */ ++ ++import java.awt.*; ++import java.awt.font.*; ++import java.awt.image.*; ++import java.text.*; ++import java.util.*; ++ ++public class EmptyAttrString { ++ ++ public static void main(String[] args) { ++ BufferedImage bi = ++ new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); ++ Graphics2D g = bi.createGraphics(); ++ Font f = new Font( "Dialog", Font.PLAIN, 12 ); ++ Map map = new HashMap(); ++ map.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON); ++ f = f.deriveFont(map); ++ g.setFont(f); ++ g.drawString("", 50, 50); ++ g.drawString("", 50f, 50f); ++ char[] chs = { } ; ++ g.drawChars(chs, 0, 0, 50, 50); ++ byte[] bytes = { } ; ++ g.drawBytes(bytes, 0, 0, 50, 50); ++ AttributedString astr = new AttributedString(""); ++ g.drawString(astr.getIterator(), 50, 50); ++ g.drawString(astr.getIterator(), 50f, 50f); ++ return; ++ } ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6769607-modal-hangs.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,164 @@ +# HG changeset patch +# User dcherepanov +# Date 1234870023 -10800 +# Node ID 5453a374c1d5838bf924e27fcd790d4bd9cadb2a +# Parent 03276203c39cd11758db94645f9173e04ae47c3a +6769607: PIT : Modal frame hangs for a while for few seconds in 6u12 b01 pit build +Reviewed-by: art, anthony + +diff -r 03276203c39c -r 5453a374c1d5 src/share/classes/java/awt/Window.java +--- openjdk.orig/jdk/src/share/classes/java/awt/Window.java Tue Feb 17 10:42:12 2009 +0300 ++++ openjdk/jdk/src/share/classes/java/awt/Window.java Tue Feb 17 14:27:03 2009 +0300 +@@ -687,9 +687,9 @@ + } + if (peer == null) { + peer = getToolkit().createWindow(this); +- synchronized (allWindows) { +- allWindows.add(this); +- } ++ } ++ synchronized (allWindows) { ++ allWindows.add(this); + } + super.addNotify(); + } +diff -r 03276203c39c -r 5453a374c1d5 src/windows/native/sun/windows/awt_Dialog.cpp +--- openjdk.orig/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Tue Feb 17 10:42:12 2009 +0300 ++++ openjdk/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Tue Feb 17 14:27:03 2009 +0300 +@@ -230,25 +230,8 @@ + if (::IsIconic(hWnd)) { + ::ShowWindow(hWnd, SW_RESTORE); + } +- HWND topMostBlocker = blocker; +- HWND toolkitHWnd = AwtToolkit::GetInstance().GetHWnd(); +- while (::IsWindow(blocker)) { +- topMostBlocker = blocker; +- // fix for 6494032: restore the blocker if it was minimized +- // together with its parent frame; in such cases the check +- // ::IsIconic() for the blocker returns false, so we use +- // ::IsWindowVisible() instead +- if (!::IsWindowVisible(topMostBlocker) && +- (topMostBlocker != toolkitHWnd)) +- { +- ::ShowWindow(topMostBlocker, SW_SHOWNA); +- } +- ::BringWindowToTop(blocker); +- blocker = AwtWindow::GetModalBlocker(blocker); +- } +- if (topMostBlocker != toolkitHWnd) { +- ::SetForegroundWindow(topMostBlocker); +- } ++ PopupAllDialogs(blocker, TRUE, ::GetForegroundWindow(), FALSE); ++ // return 1 to prevent the system from allowing the operation + return 1; + } + return CallNextHookEx(0, code, wParam, lParam); +@@ -271,30 +254,11 @@ + (wParam == WM_NCRBUTTONDOWN)) + { + HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); +- HWND topMostBlocker = blocker; +- HWND prevForegroundWindow = ::GetForegroundWindow(); + if (::IsWindow(blocker)) { +- ::BringWindowToTop(hWnd); +- } +- while (::IsWindow(blocker)) { +- topMostBlocker = blocker; +- ::BringWindowToTop(blocker); +- blocker = AwtWindow::GetModalBlocker(blocker); +- } +- if (::IsWindow(topMostBlocker)) { +- // no beep/flash if the mouse was clicked in the taskbar menu +- // or the dialog is currently inactive +- if ((::WindowFromPoint(mhs->pt) == hWnd) && +- (prevForegroundWindow == topMostBlocker)) +- { +- ::MessageBeep(MB_OK); +- // some heuristics: 3 times x 64 milliseconds +- AwtWindow::FlashWindowEx(topMostBlocker, 3, 64, FLASHW_CAPTION); +- } +- if (topMostBlocker != AwtToolkit::GetInstance().GetHWnd()) { +- ::BringWindowToTop(topMostBlocker); +- ::SetForegroundWindow(topMostBlocker); +- } ++ BOOL onTaskbar = !(::WindowFromPoint(mhs->pt) == hWnd); ++ PopupAllDialogs(hWnd, FALSE, ::GetForegroundWindow(), onTaskbar); ++ // return a nonzero value to prevent the system from passing ++ // the message to the target window procedure + return 1; + } + } +@@ -303,6 +267,58 @@ + return CallNextHookEx(0, nCode, wParam, lParam); + } + ++/* ++ * The function goes through the heirarchy of the blocker dialogs and ++ * popups all the dialogs. Note that the function starts from the top ++ * blocker dialog and goes down to the dialog which is the bottom dialog. ++ * Using another traversal may cause to the flickering issue as a bottom ++ * dialog will cover a top dialog for some period of time. ++ */ ++void AwtDialog::PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) ++{ ++ HWND blocker = AwtWindow::GetModalBlocker(dialog); ++ BOOL isBlocked = ::IsWindow(blocker); ++ if (isBlocked) { ++ PopupAllDialogs(blocker, isModalHook, prevFGWindow, onTaskbar); ++ } ++ PopupOneDialog(dialog, blocker, isModalHook, prevFGWindow, onTaskbar); ++} ++ ++/* ++ * The function popups the dialog, it distinguishes non-blocked dialogs ++ * and activates the dialogs (sets as foreground window). If the dialog is ++ * blocked, then it changes the Z-order of the dialog. ++ */ ++void AwtDialog::PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) ++{ ++ if (dialog == AwtToolkit::GetInstance().GetHWnd()) { ++ return; ++ } ++ ++ // fix for 6494032 ++ if (isModalHook && !::IsWindowVisible(dialog)) { ++ ::ShowWindow(dialog, SW_SHOWNA); ++ } ++ ++ BOOL isBlocked = ::IsWindow(blocker); ++ UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; ++ ++ if (isBlocked) { ++ ::SetWindowPos(dialog, blocker, 0, 0, 0, 0, flags); ++ } else { ++ ::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags); ++ // no beep/flash if the mouse was clicked in the taskbar menu ++ // or the dialog is currently inactive ++ if (!isModalHook && !onTaskbar && (dialog == prevFGWindow)) { ++ ::MessageBeep(MB_OK); ++ // some heuristics: 3 times x 64 milliseconds ++ AwtWindow::FlashWindowEx(dialog, 3, 64, FLASHW_CAPTION); ++ } ++ ::BringWindowToTop(dialog); ++ ::SetForegroundWindow(dialog); ++ } ++} ++ + LRESULT CALLBACK AwtDialog::MouseHookProc_NonTT(int nCode, + WPARAM wParam, LPARAM lParam) + { +diff -r 03276203c39c -r 5453a374c1d5 src/windows/native/sun/windows/awt_Dialog.h +--- openjdk.orig/jdk/src/windows/native/sun/windows/awt_Dialog.h Tue Feb 17 10:42:12 2009 +0300 ++++ openjdk/jdk/src/windows/native/sun/windows/awt_Dialog.h Tue Feb 17 14:27:03 2009 +0300 +@@ -113,6 +113,9 @@ + */ + static void ModalPerformActivation(HWND hWnd); + ++ static void PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar); ++ static void PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar); ++ + public: + + // WH_CBT hook procedure used in modality, prevents modal +exporting patch: +<fdopen>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6783910-java_awt_Color_brighter_darker_fix.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,141 @@ +# HG changeset patch +# User dav +# Date 1291143295 -10800 +# Node ID 357ecafd727b56555e8adc7dd39bfa01abdd12f7 +# Parent 4becb3dd78618a7d211778d8b1d1f0029512f5fb +6783910: (dav) java.awt.Color.brighter()/darker() methods make color opaque +Reviewed-by: art, yan + +diff -r 4becb3dd7861 -r 357ecafd727b src/share/classes/java/awt/Color.java +--- openjdk.orig/jdk/src/share/classes/java/awt/Color.java Tue Nov 30 17:36:56 2010 +0300 ++++ openjdk/jdk/src/share/classes/java/awt/Color.java Tue Nov 30 21:54:55 2010 +0300 +@@ -611,12 +611,15 @@ + * <p> + * This method applies an arbitrary scale factor to each of the three RGB + * components of this <code>Color</code> to create a brighter version +- * of this <code>Color</code>. Although <code>brighter</code> and ++ * of this <code>Color</code>. ++ * The {@code alpha} value is preserved. ++ * Although <code>brighter</code> and + * <code>darker</code> are inverse operations, the results of a + * series of invocations of these two methods might be inconsistent + * because of rounding errors. + * @return a new <code>Color</code> object that is +- * a brighter version of this <code>Color</code>. ++ * a brighter version of this <code>Color</code> ++ * with the same {@code alpha} value. + * @see java.awt.Color#darker + * @since JDK1.0 + */ +@@ -624,6 +627,7 @@ + int r = getRed(); + int g = getGreen(); + int b = getBlue(); ++ int alpha = getAlpha(); + + /* From 2D group: + * 1. black.brighter() should return grey +@@ -632,7 +636,7 @@ + */ + int i = (int)(1.0/(1.0-FACTOR)); + if ( r == 0 && g == 0 && b == 0) { +- return new Color(i, i, i); ++ return new Color(i, i, i, alpha); + } + if ( r > 0 && r < i ) r = i; + if ( g > 0 && g < i ) g = i; +@@ -640,7 +644,8 @@ + + return new Color(Math.min((int)(r/FACTOR), 255), + Math.min((int)(g/FACTOR), 255), +- Math.min((int)(b/FACTOR), 255)); ++ Math.min((int)(b/FACTOR), 255), ++ alpha); + } + + /** +@@ -649,19 +654,23 @@ + * <p> + * This method applies an arbitrary scale factor to each of the three RGB + * components of this <code>Color</code> to create a darker version of +- * this <code>Color</code>. Although <code>brighter</code> and ++ * this <code>Color</code>. ++ * The {@code alpha} value is preserved. ++ * Although <code>brighter</code> and + * <code>darker</code> are inverse operations, the results of a series + * of invocations of these two methods might be inconsistent because + * of rounding errors. + * @return a new <code>Color</code> object that is +- * a darker version of this <code>Color</code>. ++ * a darker version of this <code>Color</code> ++ * with the same {@code alpha} value. + * @see java.awt.Color#brighter + * @since JDK1.0 + */ + public Color darker() { + return new Color(Math.max((int)(getRed() *FACTOR), 0), + Math.max((int)(getGreen()*FACTOR), 0), +- Math.max((int)(getBlue() *FACTOR), 0)); ++ Math.max((int)(getBlue() *FACTOR), 0), ++ getAlpha()); + } + + /** +diff -r 4becb3dd7861 -r 357ecafd727b test/java/awt/Color/OpacityChange/OpacityChange.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/awt/Color/OpacityChange/OpacityChange.java Tue Nov 30 21:54:55 2010 +0300 +@@ -0,0 +1,54 @@ ++/* ++ * Copyright (c) 2010, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++/* ++ @test ++ @bug 6783910 ++ @summary java.awt.Color.brighter()/darker() methods make color opaque ++ @author Andrei Dmitriev: area=awt-color ++ @run main OpacityChange ++*/ ++ ++import java.awt.*; ++ ++public class OpacityChange { ++ private final static int INITIAL_ALPHA = 125; ++ ++ public static void main(String argv[]) { ++ Color color = new Color(20, 20, 20, INITIAL_ALPHA); ++ System.out.println("Initial alpha: " + color.getAlpha()); ++ Color colorBrighter = color.brighter(); ++ System.out.println("New alpha (after brighter): " + colorBrighter.getAlpha()); ++ ++ Color colorDarker = color.darker(); ++ System.out.println("New alpha (after darker): " + colorDarker.getAlpha()); ++ ++ ++ if (INITIAL_ALPHA != colorBrighter.getAlpha()) { ++ throw new RuntimeException("Brighter color alpha has changed from : " +INITIAL_ALPHA + " to " + colorBrighter.getAlpha()); ++ } ++ if (INITIAL_ALPHA != colorDarker.getAlpha()) { ++ throw new RuntimeException("Darker color alpha has changed from : " +INITIAL_ALPHA + " to " + colorDarker.getAlpha()); ++ } ++ } ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6785424-SecurityException_locating_physical_fonts.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,97 @@ +# HG changeset patch +# User prr +# Date 1231278723 28800 +# Node ID eaeaacda1c568a3e013ade338c9b833d767e8591 +# Parent 40ec164889bd9ec1955e36864593bc222474ba43 +6785424: SecurityException locating physical fonts on Windows Terminal Server +Reviewed-by: campbell, jgodinez + +diff -r 40ec164889bd -r eaeaacda1c56 src/share/classes/sun/font/FontManager.java +--- openjdk.orig/jdk/src/share/classes/sun/font/FontManager.java Wed Dec 24 09:57:48 2008 -0800 ++++ openjdk/jdk/src/share/classes/sun/font/FontManager.java Tue Jan 06 13:52:03 2009 -0800 +@@ -1601,18 +1601,27 @@ + /* Path may be absolute or a base file name relative to one of + * the platform font directories + */ +- private static String getPathName(String s) { ++ private static String getPathName(final String s) { + File f = new File(s); + if (f.isAbsolute()) { + return s; + } else if (pathDirs.length==1) { + return pathDirs[0] + File.separator + s; + } else { +- for (int p=0; p<pathDirs.length; p++) { +- f = new File(pathDirs[p] + File.separator + s); +- if (f.exists()) { +- return f.getAbsolutePath(); +- } ++ String path = java.security.AccessController.doPrivileged( ++ new java.security.PrivilegedAction<String>() { ++ public String run() { ++ for (int p=0; p<pathDirs.length; p++) { ++ File f = new File(pathDirs[p] +File.separator+ s); ++ if (f.exists()) { ++ return f.getAbsolutePath(); ++ } ++ } ++ return null; ++ } ++ }); ++ if (path != null) { ++ return path; + } + } + return s; // shouldn't happen, but harmless +diff -r 40ec164889bd -r eaeaacda1c56 test/java/awt/FontClass/FontAccess.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/awt/FontClass/FontAccess.java Tue Jan 06 13:52:03 2009 -0800 +@@ -0,0 +1,48 @@ ++/* ++ * Copyright (c) 2009 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 6785424 ++ * @summary Test no SecurityException searching for a font. ++ * @run main FontAccess ++ * ++ * This can only test the specific bug if run on something like ++ * Windows Citrix Server where SystemDirectory and WindowsDirectory ++ * are different locations. ++ */ ++ ++import java.awt.*; ++import java.awt.image.*; ++ ++public class FontAccess { ++ ++ public static void main(String[] args) { ++ System.setSecurityManager(new SecurityManager()); ++ Font f = new Font("Verdana", Font.PLAIN, 12); ++ BufferedImage bi = new BufferedImage(1,1,1); ++ Graphics2D g = bi.createGraphics(); ++ g.setFont(f); ++ System.out.println(g.getFontMetrics()); ++ } ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6796786-invalid_FP_identity_transform.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,105 @@ +# HG changeset patch +# User never +# Date 1304449914 25200 +# Node ID f1d6640088a1d3ffc30910e93f1bd782ae74eca9 +# Parent 2e038ad0c1d09407fe8a1627269a5b1c4d163985 +6796786: invalid FP identity transform - (a - b) -> b - a +Reviewed-by: iveresov, twisti + +diff -r 2e038ad0c1d0 -r f1d6640088a1 src/share/vm/opto/subnode.cpp +--- openjdk.orig/hotspot/src/share/vm/opto/subnode.cpp Mon May 02 18:53:37 2011 -0700 ++++ openjdk/hotspot/src/share/vm/opto/subnode.cpp Tue May 03 12:11:54 2011 -0700 +@@ -1223,21 +1223,6 @@ + } + + //============================================================================= +-//------------------------------NegNode---------------------------------------- +-Node *NegFNode::Ideal(PhaseGVN *phase, bool can_reshape) { +- if( in(1)->Opcode() == Op_SubF ) +- return new (phase->C, 3) SubFNode( in(1)->in(2), in(1)->in(1) ); +- return NULL; +-} +- +-Node *NegDNode::Ideal(PhaseGVN *phase, bool can_reshape) { +- if( in(1)->Opcode() == Op_SubD ) +- return new (phase->C, 3) SubDNode( in(1)->in(2), in(1)->in(1) ); +- return NULL; +-} +- +- +-//============================================================================= + //------------------------------Value------------------------------------------ + // Compute sqrt + const Type *SqrtDNode::Value( PhaseTransform *phase ) const { +diff -r 2e038ad0c1d0 -r f1d6640088a1 src/share/vm/opto/subnode.hpp +--- openjdk.orig/hotspot/src/share/vm/opto/subnode.hpp Mon May 02 18:53:37 2011 -0700 ++++ openjdk/hotspot/src/share/vm/opto/subnode.hpp Tue May 03 12:11:54 2011 -0700 +@@ -377,7 +377,6 @@ + public: + NegFNode( Node *in1 ) : NegNode(in1) {} + virtual int Opcode() const; +- virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + const Type *bottom_type() const { return Type::FLOAT; } + virtual uint ideal_reg() const { return Op_RegF; } + }; +@@ -391,7 +390,6 @@ + public: + NegDNode( Node *in1 ) : NegNode(in1) {} + virtual int Opcode() const; +- virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + const Type *bottom_type() const { return Type::DOUBLE; } + virtual uint ideal_reg() const { return Op_RegD; } + }; +diff -r 2e038ad0c1d0 -r f1d6640088a1 test/compiler/6796786/Test6796786.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/hotspot/test/compiler/6796786/Test6796786.java Tue May 03 12:11:54 2011 -0700 +@@ -0,0 +1,49 @@ ++/* ++ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++/** ++ * @test ++ * @bug 6796786 ++ * @summary invalid FP identity transform - (a - b) -> b - a ++ * ++ * @run main Test6796786 ++ */ ++ ++public class Test6796786 { ++ static volatile float d1; ++ static volatile float d2; ++ static float zero; ++ ++ public static void main(String[] args) { ++ int total = 0; ++ for (int i = 0; i < 100000; i++) { ++ if (Float.floatToRawIntBits(- (d1 - d1)) == Float.floatToRawIntBits(0.0f)) { ++ total++; ++ } ++ } ++ if (total != 100000) { ++ throw new InternalError(); ++ } ++ } ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6818312-com.sun.awt.SecurityWarning.getSize.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,405 @@ +# HG changeset patch +# User anthony +# Date 1238598347 -14400 +# Node ID 1cb2e3e0631fb815c31f0123a6a207d78b219e21 +# Parent 3a9ae1117c12b6fa13a692609de28600d707e25c +6818312: com.sun.awt.SecurityWarning.getSize() always reports (0, 0) on X11 +Summary: The fix got pushed with 6693253. However the test was omitted. Here it comes. +Reviewed-by: dcherepanov, art + +diff -r 3a9ae1117c12 -r 1cb2e3e0631f test/com/sun/awt/SecurityWarning/GetSizeShouldNotReturnZero.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/com/sun/awt/SecurityWarning/GetSizeShouldNotReturnZero.java Wed Apr 01 19:05:47 2009 +0400 +@@ -0,0 +1,392 @@ ++/* ++ * Copyright 2009 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 %W% %E% ++ @bug 6818312 ++ @summary The size returned by SecurityWarning.getSize() should not be zero ++ @author anthony.petrov@sun.com: area=awt.toplevel ++ @library ../../../../java/awt/regtesthelpers ++ @build Util ++ @run main GetSizeShouldNotReturnZero ++*/ ++ ++/** ++ * GetSizeShouldNotReturnZero.java ++ * ++ * summary: The size returned by SecurityWarning.getSize() should not be zero ++ */ ++ ++import java.awt.*; ++import java.awt.event.*; ++import java.security.Permission; ++import test.java.awt.regtesthelpers.Util; ++import com.sun.awt.SecurityWarning; ++ ++public class GetSizeShouldNotReturnZero ++{ ++ private static void init() ++ { ++ String[] instructions = ++ { ++ "This is an AUTOMATIC test, simply wait until it is done.", ++ "The result (passed or failed) will be shown in the", ++ "message window below." ++ }; ++ Sysout.createDialog( ); ++ Sysout.printInstructions( instructions ); ++ ++ ++ // Install the security manager so that all subsequently created ++ // windows display the security warning. ++ System.setSecurityManager(new SecurityManager() { ++ ++ @Override ++ public void checkPermission(Permission perm) { ++ } ++ ++ @Override ++ public boolean checkTopLevelWindow(Object window) { ++ return false; ++ } ++ }); ++ ++ Frame f = new Frame(); ++ f.setSize(100, 100); ++ f.setVisible(true); ++ ++ Robot robot = Util.createRobot(); ++ Util.waitForIdle(robot); ++ ++ Dimension size = SecurityWarning.getSize(f); ++ if (size.width == 0 || size.height == 0) { ++ fail("Reported security warning size: " + size); ++ return; ++ } ++ pass(); ++ }//End init() ++ ++ ++ ++ /***************************************************** ++ * Standard Test Machinery Section ++ * DO NOT modify anything in this section -- it's a ++ * standard chunk of code which has all of the ++ * synchronisation necessary for the test harness. ++ * By keeping it the same in all tests, it is easier ++ * to read and understand someone else's test, as ++ * well as insuring that all tests behave correctly ++ * with the test harness. ++ * There is a section following this for test- ++ * classes ++ ******************************************************/ ++ private static boolean theTestPassed = false; ++ private static boolean testGeneratedInterrupt = false; ++ private static String failureMessage = ""; ++ ++ private static Thread mainThread = null; ++ ++ private static int sleepTime = 300000; ++ ++ // Not sure about what happens if multiple of this test are ++ // instantiated in the same VM. Being static (and using ++ // static vars), it aint gonna work. Not worrying about ++ // it for now. ++ public static void main( String args[] ) throws InterruptedException ++ { ++ mainThread = Thread.currentThread(); ++ try ++ { ++ init(); ++ } ++ catch( TestPassedException e ) ++ { ++ //The test passed, so just return from main and harness will ++ // interepret this return as a pass ++ return; ++ } ++ //At this point, neither test pass nor test fail has been ++ // called -- either would have thrown an exception and ended the ++ // test, so we know we have multiple threads. ++ ++ //Test involves other threads, so sleep and wait for them to ++ // called pass() or fail() ++ try ++ { ++ Thread.sleep( sleepTime ); ++ //Timed out, so fail the test ++ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); ++ } ++ catch (InterruptedException e) ++ { ++ //The test harness may have interrupted the test. If so, rethrow the exception ++ // so that the harness gets it and deals with it. ++ if( ! testGeneratedInterrupt ) throw e; ++ ++ //reset flag in case hit this code more than once for some reason (just safety) ++ testGeneratedInterrupt = false; ++ ++ if ( theTestPassed == false ) ++ { ++ throw new RuntimeException( failureMessage ); ++ } ++ } ++ ++ }//main ++ ++ public static synchronized void setTimeoutTo( int seconds ) ++ { ++ sleepTime = seconds * 1000; ++ } ++ ++ public static synchronized void pass() ++ { ++ Sysout.println( "The test passed." ); ++ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); ++ //first check if this is executing in main thread ++ if ( mainThread == Thread.currentThread() ) ++ { ++ //Still in the main thread, so set the flag just for kicks, ++ // and throw a test passed exception which will be caught ++ // and end the test. ++ theTestPassed = true; ++ throw new TestPassedException(); ++ } ++ theTestPassed = true; ++ testGeneratedInterrupt = true; ++ mainThread.interrupt(); ++ }//pass() ++ ++ public static synchronized void fail() ++ { ++ //test writer didn't specify why test failed, so give generic ++ fail( "it just plain failed! :-)" ); ++ } ++ ++ public static synchronized void fail( String whyFailed ) ++ { ++ Sysout.println( "The test failed: " + whyFailed ); ++ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); ++ //check if this called from main thread ++ if ( mainThread == Thread.currentThread() ) ++ { ++ //If main thread, fail now 'cause not sleeping ++ throw new RuntimeException( whyFailed ); ++ } ++ theTestPassed = false; ++ testGeneratedInterrupt = true; ++ failureMessage = whyFailed; ++ mainThread.interrupt(); ++ }//fail() ++ ++}// class GetSizeShouldNotReturnZero ++ ++//This exception is used to exit from any level of call nesting ++// when it's determined that the test has passed, and immediately ++// end the test. ++class TestPassedException extends RuntimeException ++{ ++} ++ ++//*********** End Standard Test Machinery Section ********** ++ ++ ++//************ Begin classes defined for the test **************** ++ ++// if want to make listeners, here is the recommended place for them, then instantiate ++// them in init() ++ ++/* Example of a class which may be written as part of a test ++class NewClass implements anInterface ++ { ++ static int newVar = 0; ++ ++ public void eventDispatched(AWTEvent e) ++ { ++ //Counting events to see if we get enough ++ eventCount++; ++ ++ if( eventCount == 20 ) ++ { ++ //got enough events, so pass ++ ++ GetSizeShouldNotReturnZero.pass(); ++ } ++ else if( tries == 20 ) ++ { ++ //tried too many times without getting enough events so fail ++ ++ GetSizeShouldNotReturnZero.fail(); ++ } ++ ++ }// eventDispatched() ++ ++ }// NewClass class ++ ++*/ ++ ++ ++//************** End classes defined for the test ******************* ++ ++ ++ ++ ++/**************************************************** ++ Standard Test Machinery ++ DO NOT modify anything below -- it's a standard ++ chunk of code whose purpose is to make user ++ interaction uniform, and thereby make it simpler ++ to read and understand someone else's test. ++ ****************************************************/ ++ ++/** ++ This is part of the standard test machinery. ++ It creates a dialog (with the instructions), and is the interface ++ for sending text messages to the user. ++ To print the instructions, send an array of strings to Sysout.createDialog ++ WithInstructions method. Put one line of instructions per array entry. ++ To display a message for the tester to see, simply call Sysout.println ++ with the string to be displayed. ++ This mimics System.out.println but works within the test harness as well ++ as standalone. ++ */ ++ ++class Sysout ++{ ++ private static TestDialog dialog; ++ ++ public static void createDialogWithInstructions( String[] instructions ) ++ { ++ dialog = new TestDialog( new Frame(), "Instructions" ); ++ dialog.printInstructions( instructions ); ++ dialog.setVisible(true); ++ println( "Any messages for the tester will display here." ); ++ } ++ ++ public static void createDialog( ) ++ { ++ dialog = new TestDialog( new Frame(), "Instructions" ); ++ String[] defInstr = { "Instructions will appear here. ", "" } ; ++ dialog.printInstructions( defInstr ); ++ dialog.setVisible(true); ++ println( "Any messages for the tester will display here." ); ++ } ++ ++ ++ public static void printInstructions( String[] instructions ) ++ { ++ dialog.printInstructions( instructions ); ++ } ++ ++ ++ public static void println( String messageIn ) ++ { ++ dialog.displayMessage( messageIn ); ++ System.out.println(messageIn); ++ } ++ ++}// Sysout class ++ ++/** ++ This is part of the standard test machinery. It provides a place for the ++ test instructions to be displayed, and a place for interactive messages ++ to the user to be displayed. ++ To have the test instructions displayed, see Sysout. ++ To have a message to the user be displayed, see Sysout. ++ Do not call anything in this dialog directly. ++ */ ++class TestDialog extends Dialog ++{ ++ ++ TextArea instructionsText; ++ TextArea messageText; ++ int maxStringLength = 80; ++ ++ //DO NOT call this directly, go through Sysout ++ public TestDialog( Frame frame, String name ) ++ { ++ super( frame, name ); ++ int scrollBoth = TextArea.SCROLLBARS_BOTH; ++ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); ++ add( "North", instructionsText ); ++ ++ messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); ++ add("Center", messageText); ++ ++ pack(); ++ ++ setVisible(true); ++ }// TestDialog() ++ ++ //DO NOT call this directly, go through Sysout ++ public void printInstructions( String[] instructions ) ++ { ++ //Clear out any current instructions ++ instructionsText.setText( "" ); ++ ++ //Go down array of instruction strings ++ ++ String printStr, remainingStr; ++ for( int i=0; i < instructions.length; i++ ) ++ { ++ //chop up each into pieces maxSringLength long ++ remainingStr = instructions[ i ]; ++ while( remainingStr.length() > 0 ) ++ { ++ //if longer than max then chop off first max chars to print ++ if( remainingStr.length() >= maxStringLength ) ++ { ++ //Try to chop on a word boundary ++ int posOfSpace = remainingStr. ++ lastIndexOf( ' ', maxStringLength - 1 ); ++ ++ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; ++ ++ printStr = remainingStr.substring( 0, posOfSpace + 1 ); ++ remainingStr = remainingStr.substring( posOfSpace + 1 ); ++ } ++ //else just print ++ else ++ { ++ printStr = remainingStr; ++ remainingStr = ""; ++ } ++ ++ instructionsText.append( printStr + "\n" ); ++ ++ }// while ++ ++ }// for ++ ++ }//printInstructions() ++ ++ //DO NOT call this directly, go through Sysout ++ public void displayMessage( String messageIn ) ++ { ++ messageText.append( messageIn + "\n" ); ++ System.out.println(messageIn); ++ } ++ ++}// TestDialog class ++ ++
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6918065-Crash_in_Java2D_blit_loop.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,58 @@ +# HG changeset patch +# User minqi +# Date 1268076930 28800 +# Node ID 1d7db2d5c4c5eeea61b23a6f6ca4d304dec8df10 +# Parent 840601ac5ab7cf49421e9de10c9c36c8f958d9cf +6918065: Crash in Java2D blit loop (IntArgbToIntArgbPreSrcOverMaskBlit) in 64bit mode +Reviewed-by: igor, bae + +diff -r 840601ac5ab7 -r 1d7db2d5c4c5 src/share/classes/java/awt/AlphaComposite.java +--- openjdk.orig/jdk/src/share/classes/java/awt/AlphaComposite.java Wed Mar 03 15:50:33 2010 +0100 ++++ openjdk/jdk/src/share/classes/java/awt/AlphaComposite.java Mon Mar 08 11:35:30 2010 -0800 +@@ -614,14 +614,15 @@ + } + + private AlphaComposite(int rule, float alpha) { +- if (alpha < 0.0f || alpha > 1.0f) { +- throw new IllegalArgumentException("alpha value out of range"); +- } + if (rule < MIN_RULE || rule > MAX_RULE) { + throw new IllegalArgumentException("unknown composite rule"); + } +- this.rule = rule; +- this.extraAlpha = alpha; ++ if (alpha >= 0.0f && alpha <= 1.0f) { ++ this.rule = rule; ++ this.extraAlpha = alpha; ++ } else { ++ throw new IllegalArgumentException("alpha value out of range"); ++ } + } + + /** +diff -r 840601ac5ab7 -r 1d7db2d5c4c5 test/java/awt/AlphaComposite/TestAlphaCompositeForNaN.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/awt/AlphaComposite/TestAlphaCompositeForNaN.java Mon Mar 08 11:35:30 2010 -0800 +@@ -0,0 +1,22 @@ ++/* ++ * @test ++ * @bug 6918065 ++ * @summary Test for passing NaN as alpha ++ * should throw IllegalArgumentException ++ */ ++ ++import java.awt.*; ++ ++public class TestAlphaCompositeForNaN { ++ public static void main(String[] args) { ++ try { ++ AlphaComposite a = AlphaComposite.getInstance(AlphaComposite.DST, Float.NaN); ++ System.out.println("Failed"); ++ throw new RuntimeException(a + " failed to throw IllegalArgumentException for alpha = " + Float.NaN); ++ } ++ catch (IllegalArgumentException ie) { ++ System.out.println("Passed"); ++ System.out.println("Caught " + ie); ++ } ++ } ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6956668-misbehavior_of_XOR_operator_with_int.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,93 @@ +# HG changeset patch +# User kvn +# Date 1306861536 25200 +# Node ID f88fb2fa90cf92088890d601c13046546df61cb0 +# Parent 7c907a50c1bb7c5722924bdcf44952909dd8b55b +6956668: misbehavior of XOR operator (^) with int +Summary: optimize cmp_ne(xor(X,1),0) to cmp_eq(X,0) only for boolean values X. +Reviewed-by: never + +diff -r 7c907a50c1bb -r f88fb2fa90cf src/share/vm/opto/subnode.cpp +--- openjdk.orig/hotspot/src/share/vm/opto/subnode.cpp Wed Jun 01 14:46:14 2011 -0700 ++++ openjdk/hotspot/src/share/vm/opto/subnode.cpp Tue May 31 10:05:36 2011 -0700 +@@ -1101,6 +1101,7 @@ + if( cmp2_type == TypeInt::ZERO && + cmp1_op == Op_XorI && + j_xor->in(1) != j_xor && // An xor of itself is dead ++ phase->type( j_xor->in(1) ) == TypeInt::BOOL && + phase->type( j_xor->in(2) ) == TypeInt::ONE && + (_test._test == BoolTest::eq || + _test._test == BoolTest::ne) ) { +diff -r 7c907a50c1bb -r f88fb2fa90cf test/compiler/6956668/Test6956668.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/hotspot/test/compiler/6956668/Test6956668.java Tue May 31 10:05:36 2011 -0700 +@@ -0,0 +1,69 @@ ++/* ++ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++/** ++ * @test ++ * @bug 6956668 ++ * @summary misbehavior of XOR operator (^) with int ++ * ++ * @run main/othervm -Xbatch Test6956668 ++ */ ++ ++ ++public class Test6956668 { ++ ++ public static int bitTest() { ++ int result = 0; ++ ++ int testValue = 73; ++ int bitCount = Integer.bitCount(testValue); ++ ++ if (testValue != 0) { ++ int gap = Long.numberOfTrailingZeros(testValue); ++ testValue >>>= gap; ++ ++ while (testValue != 0) { ++ result++; ++ ++ if ((testValue ^= 0x1) != 0) { ++ gap = Long.numberOfTrailingZeros(testValue); ++ testValue >>>= gap; ++ } ++ } ++ } ++ ++ if (bitCount != result) { ++ System.out.println("ERROR: " + bitCount + " != " + result); ++ System.exit(97); ++ } ++ ++ return (result); ++ } ++ ++ public static void main(String[] args) { ++ for (int i = 0; i < 100000; i++) { ++ int ct = bitTest(); ++ } ++ } ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/7008106-WindowOpacity.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,19 @@ +# HG changeset patch +# User dav +# Date 1293624780 -10800 +# Node ID 8b05f9b91765b7b9da4d2033693e10c1a174a2a5 +# Parent 39e9d5613145dbdd3973a1ecaa481c679dcfbf8f +7008106: com/sun/awt/Translucency/WindowOpacity.java test fails just against jdk7 b122 +Reviewed-by: dcherepanov + +diff -r 39e9d5613145 -r 8b05f9b91765 test/com/sun/awt/Translucency/WindowOpacity.java +--- openjdk.orig/jdk/test/com/sun/awt/Translucency/WindowOpacity.java Tue Dec 28 17:13:13 2010 +0300 ++++ openjdk/jdk/test/com/sun/awt/Translucency/WindowOpacity.java Wed Dec 29 15:13:00 2010 +0300 +@@ -64,6 +64,7 @@ + boolean passed; + + Frame f = new Frame("Opacity test"); ++ f.setUndecorated(true); + + passed = false; + try {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/7029152-String_intrinsics_miss_optimization.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,383 @@ +# HG changeset patch +# User kvn +# Date 1301512129 25200 +# Node ID f9424955eb1894f874b73cb7596f19ee53a79149 +# Parent 63997f575155c27cbc193a345f814e5b59db5054 +7029152: Ideal nodes for String intrinsics miss memory edge optimization +Summary: In Ideal() method of String intrinsics nodes look for TypeAryPtr::CHARS memory slice if memory is MergeMem. Do not unroll a loop with String intrinsics code. +Reviewed-by: never + +diff -r 63997f575155 -r f9424955eb18 src/share/vm/opto/loopTransform.cpp +--- openjdk.orig/hotspot/src/share/vm/opto/loopTransform.cpp Wed Mar 30 07:47:19 2011 -0700 ++++ openjdk/hotspot/src/share/vm/opto/loopTransform.cpp Wed Mar 30 12:08:49 2011 -0700 +@@ -396,16 +396,16 @@ + // Return exact loop trip count, or 0 if not maximally unrolling + bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const { + CountedLoopNode *cl = _head->as_CountedLoop(); +- assert( cl->is_normal_loop(), "" ); ++ assert(cl->is_normal_loop(), ""); + + Node *init_n = cl->init_trip(); + Node *limit_n = cl->limit(); + + // Non-constant bounds +- if( init_n == NULL || !init_n->is_Con() || ++ if (init_n == NULL || !init_n->is_Con() || + limit_n == NULL || !limit_n->is_Con() || + // protect against stride not being a constant +- !cl->stride_is_con() ) { ++ !cl->stride_is_con()) { + return false; + } + int init = init_n->get_int(); +@@ -428,7 +428,25 @@ + uint unroll_limit = (uint)LoopUnrollLimit * 4; + assert( (intx)unroll_limit == LoopUnrollLimit * 4, "LoopUnrollLimit must fit in 32bits"); + cl->set_trip_count(trip_count); +- if( trip_count <= unroll_limit && body_size <= unroll_limit ) { ++ if (trip_count > unroll_limit || body_size > unroll_limit) { ++ return false; ++ } ++ ++ // Do not unroll a loop with String intrinsics code. ++ // String intrinsics are large and have loops. ++ for (uint k = 0; k < _body.size(); k++) { ++ Node* n = _body.at(k); ++ switch (n->Opcode()) { ++ case Op_StrComp: ++ case Op_StrEquals: ++ case Op_StrIndexOf: ++ case Op_AryEq: { ++ return false; ++ } ++ } // switch ++ } ++ ++ if (body_size <= unroll_limit) { + uint new_body_size = body_size * trip_count; + if (new_body_size <= unroll_limit && + body_size == new_body_size / trip_count && +@@ -448,13 +466,13 @@ + bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const { + + CountedLoopNode *cl = _head->as_CountedLoop(); +- assert( cl->is_normal_loop() || cl->is_main_loop(), "" ); ++ assert(cl->is_normal_loop() || cl->is_main_loop(), ""); + + // protect against stride not being a constant +- if( !cl->stride_is_con() ) return false; ++ if (!cl->stride_is_con()) return false; + + // protect against over-unrolling +- if( cl->trip_count() <= 1 ) return false; ++ if (cl->trip_count() <= 1) return false; + + int future_unroll_ct = cl->unrolled_count() * 2; + +@@ -485,21 +503,21 @@ + // Non-constant bounds. + // Protect against over-unrolling when init or/and limit are not constant + // (so that trip_count's init value is maxint) but iv range is known. +- if( init_n == NULL || !init_n->is_Con() || +- limit_n == NULL || !limit_n->is_Con() ) { ++ if (init_n == NULL || !init_n->is_Con() || ++ limit_n == NULL || !limit_n->is_Con()) { + Node* phi = cl->phi(); +- if( phi != NULL ) { ++ if (phi != NULL) { + assert(phi->is_Phi() && phi->in(0) == _head, "Counted loop should have iv phi."); + const TypeInt* iv_type = phase->_igvn.type(phi)->is_int(); + int next_stride = cl->stride_con() * 2; // stride after this unroll +- if( next_stride > 0 ) { +- if( iv_type->_lo + next_stride <= iv_type->_lo || // overflow +- iv_type->_lo + next_stride > iv_type->_hi ) { ++ if (next_stride > 0) { ++ if (iv_type->_lo + next_stride <= iv_type->_lo || // overflow ++ iv_type->_lo + next_stride > iv_type->_hi) { + return false; // over-unrolling + } +- } else if( next_stride < 0 ) { +- if( iv_type->_hi + next_stride >= iv_type->_hi || // overflow +- iv_type->_hi + next_stride < iv_type->_lo ) { ++ } else if (next_stride < 0) { ++ if (iv_type->_hi + next_stride >= iv_type->_hi || // overflow ++ iv_type->_hi + next_stride < iv_type->_lo) { + return false; // over-unrolling + } + } +@@ -511,24 +529,33 @@ + // Key test to unroll CaffeineMark's Logic test + int xors_in_loop = 0; + // Also count ModL, DivL and MulL which expand mightly +- for( uint k = 0; k < _body.size(); k++ ) { +- switch( _body.at(k)->Opcode() ) { +- case Op_XorI: xors_in_loop++; break; // CaffeineMark's Logic test +- case Op_ModL: body_size += 30; break; +- case Op_DivL: body_size += 30; break; +- case Op_MulL: body_size += 10; break; +- } ++ for (uint k = 0; k < _body.size(); k++) { ++ Node* n = _body.at(k); ++ switch (n->Opcode()) { ++ case Op_XorI: xors_in_loop++; break; // CaffeineMark's Logic test ++ case Op_ModL: body_size += 30; break; ++ case Op_DivL: body_size += 30; break; ++ case Op_MulL: body_size += 10; break; ++ case Op_StrComp: ++ case Op_StrEquals: ++ case Op_StrIndexOf: ++ case Op_AryEq: { ++ // Do not unroll a loop with String intrinsics code. ++ // String intrinsics are large and have loops. ++ return false; ++ } ++ } // switch + } + + // Check for being too big +- if( body_size > (uint)LoopUnrollLimit ) { +- if( xors_in_loop >= 4 && body_size < (uint)LoopUnrollLimit*4) return true; ++ if (body_size > (uint)LoopUnrollLimit) { ++ if (xors_in_loop >= 4 && body_size < (uint)LoopUnrollLimit*4) return true; + // Normal case: loop too big + return false; + } + + // Check for stride being a small enough constant +- if( abs(cl->stride_con()) > (1<<3) ) return false; ++ if (abs(cl->stride_con()) > (1<<3)) return false; + + // Unroll once! (Each trip will soon do double iterations) + return true; +diff -r 63997f575155 -r f9424955eb18 src/share/vm/opto/memnode.cpp +--- openjdk.orig/hotspot/src/share/vm/opto/memnode.cpp Wed Mar 30 07:47:19 2011 -0700 ++++ openjdk/hotspot/src/share/vm/opto/memnode.cpp Wed Mar 30 12:08:49 2011 -0700 +@@ -2617,54 +2617,24 @@ + } + + //============================================================================= +-// Do we match on this edge? No memory edges +-uint StrCompNode::match_edge(uint idx) const { +- return idx == 2 || idx == 3; // StrComp (Binary str1 cnt1) (Binary str2 cnt2) ++// Do not match memory edge. ++uint StrIntrinsicNode::match_edge(uint idx) const { ++ return idx == 2 || idx == 3; + } + + //------------------------------Ideal------------------------------------------ + // Return a node which is more "ideal" than the current node. Strip out + // control copies +-Node *StrCompNode::Ideal(PhaseGVN *phase, bool can_reshape){ +- return remove_dead_region(phase, can_reshape) ? this : NULL; +-} +- +-//============================================================================= +-// Do we match on this edge? No memory edges +-uint StrEqualsNode::match_edge(uint idx) const { +- return idx == 2 || idx == 3; // StrEquals (Binary str1 str2) cnt +-} +- +-//------------------------------Ideal------------------------------------------ +-// Return a node which is more "ideal" than the current node. Strip out +-// control copies +-Node *StrEqualsNode::Ideal(PhaseGVN *phase, bool can_reshape){ +- return remove_dead_region(phase, can_reshape) ? this : NULL; +-} +- +-//============================================================================= +-// Do we match on this edge? No memory edges +-uint StrIndexOfNode::match_edge(uint idx) const { +- return idx == 2 || idx == 3; // StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2) +-} +- +-//------------------------------Ideal------------------------------------------ +-// Return a node which is more "ideal" than the current node. Strip out +-// control copies +-Node *StrIndexOfNode::Ideal(PhaseGVN *phase, bool can_reshape){ +- return remove_dead_region(phase, can_reshape) ? this : NULL; +-} +- +-//============================================================================= +-// Do we match on this edge? No memory edges +-uint AryEqNode::match_edge(uint idx) const { +- return idx == 2 || idx == 3; // StrEquals ary1 ary2 +-} +-//------------------------------Ideal------------------------------------------ +-// Return a node which is more "ideal" than the current node. Strip out +-// control copies +-Node *AryEqNode::Ideal(PhaseGVN *phase, bool can_reshape){ +- return remove_dead_region(phase, can_reshape) ? this : NULL; ++Node *StrIntrinsicNode::Ideal(PhaseGVN *phase, bool can_reshape) { ++ if (remove_dead_region(phase, can_reshape)) return this; ++ ++ Node* mem = phase->transform(in(MemNode::Memory)); ++ // If transformed to a MergeMem, get the desired slice ++ uint alias_idx = phase->C->get_alias_index(adr_type()); ++ mem = mem->is_MergeMem() ? mem->as_MergeMem()->memory_at(alias_idx) : mem; ++ if (mem != in(MemNode::Memory)) ++ set_req(MemNode::Memory, mem); ++ return NULL; + } + + //============================================================================= +diff -r 63997f575155 -r f9424955eb18 src/share/vm/opto/memnode.hpp +--- openjdk.orig/hotspot/src/share/vm/opto/memnode.hpp Wed Mar 30 07:47:19 2011 -0700 ++++ openjdk/hotspot/src/share/vm/opto/memnode.hpp Wed Mar 30 12:08:49 2011 -0700 +@@ -776,67 +776,69 @@ + static bool step_through(Node** np, uint instance_id, PhaseTransform* phase); + }; + +-//------------------------------StrComp------------------------------------- +-class StrCompNode: public Node { ++//------------------------------StrIntrinsic------------------------------- ++// Base class for Ideal nodes used in String instrinsic code. ++class StrIntrinsicNode: public Node { + public: +- StrCompNode(Node* control, Node* char_array_mem, +- Node* s1, Node* c1, +- Node* s2, Node* c2): Node(control, char_array_mem, +- s1, c1, +- s2, c2) {}; +- virtual int Opcode() const; ++ StrIntrinsicNode(Node* control, Node* char_array_mem, ++ Node* s1, Node* c1, Node* s2, Node* c2): ++ Node(control, char_array_mem, s1, c1, s2, c2) { ++ } ++ ++ StrIntrinsicNode(Node* control, Node* char_array_mem, ++ Node* s1, Node* s2, Node* c): ++ Node(control, char_array_mem, s1, s2, c) { ++ } ++ ++ StrIntrinsicNode(Node* control, Node* char_array_mem, ++ Node* s1, Node* s2): ++ Node(control, char_array_mem, s1, s2) { ++ } ++ + virtual bool depends_only_on_test() const { return false; } +- virtual const Type* bottom_type() const { return TypeInt::INT; } + virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; } + virtual uint match_edge(uint idx) const; + virtual uint ideal_reg() const { return Op_RegI; } + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + }; + ++//------------------------------StrComp------------------------------------- ++class StrCompNode: public StrIntrinsicNode { ++public: ++ StrCompNode(Node* control, Node* char_array_mem, ++ Node* s1, Node* c1, Node* s2, Node* c2): ++ StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2) {}; ++ virtual int Opcode() const; ++ virtual const Type* bottom_type() const { return TypeInt::INT; } ++}; ++ + //------------------------------StrEquals------------------------------------- +-class StrEqualsNode: public Node { ++class StrEqualsNode: public StrIntrinsicNode { + public: + StrEqualsNode(Node* control, Node* char_array_mem, +- Node* s1, Node* s2, Node* c): Node(control, char_array_mem, +- s1, s2, c) {}; ++ Node* s1, Node* s2, Node* c): ++ StrIntrinsicNode(control, char_array_mem, s1, s2, c) {}; + virtual int Opcode() const; +- virtual bool depends_only_on_test() const { return false; } + virtual const Type* bottom_type() const { return TypeInt::BOOL; } +- virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; } +- virtual uint match_edge(uint idx) const; +- virtual uint ideal_reg() const { return Op_RegI; } +- virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + }; + + //------------------------------StrIndexOf------------------------------------- +-class StrIndexOfNode: public Node { ++class StrIndexOfNode: public StrIntrinsicNode { + public: + StrIndexOfNode(Node* control, Node* char_array_mem, +- Node* s1, Node* c1, +- Node* s2, Node* c2): Node(control, char_array_mem, +- s1, c1, +- s2, c2) {}; ++ Node* s1, Node* c1, Node* s2, Node* c2): ++ StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2) {}; + virtual int Opcode() const; +- virtual bool depends_only_on_test() const { return false; } + virtual const Type* bottom_type() const { return TypeInt::INT; } +- virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; } +- virtual uint match_edge(uint idx) const; +- virtual uint ideal_reg() const { return Op_RegI; } +- virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + }; + + //------------------------------AryEq--------------------------------------- +-class AryEqNode: public Node { ++class AryEqNode: public StrIntrinsicNode { + public: +- AryEqNode(Node* control, Node* char_array_mem, +- Node* s1, Node* s2): Node(control, char_array_mem, s1, s2) {}; ++ AryEqNode(Node* control, Node* char_array_mem, Node* s1, Node* s2): ++ StrIntrinsicNode(control, char_array_mem, s1, s2) {}; + virtual int Opcode() const; +- virtual bool depends_only_on_test() const { return false; } + virtual const Type* bottom_type() const { return TypeInt::BOOL; } +- virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; } +- virtual uint match_edge(uint idx) const; +- virtual uint ideal_reg() const { return Op_RegI; } +- virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + }; + + //------------------------------MemBar----------------------------------------- +diff -r 63997f575155 -r f9424955eb18 test/compiler/7029152/Test.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/hotspot/test/compiler/7029152/Test.java Wed Mar 30 12:08:49 2011 -0700 +@@ -0,0 +1,49 @@ ++/* ++ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++/** ++ * @test ++ * @bug 7029152 ++ * @summary Ideal nodes for String intrinsics miss memory edge optimization ++ * ++ * @run main/othervm -Xbatch Test ++ */ ++ ++public class Test { ++ ++ static final String str = "11111xx11111xx1x"; ++ static int idx = 0; ++ ++ static int IndexOfTest(String str) { ++ return str.indexOf("11111xx1x"); ++ } ++ ++ public static void main(String args[]) { ++ final int ITERS=2000000; ++ ++ for (int i=0; i<ITERS; i++) { ++ idx = IndexOfTest(str); ++ } ++ System.out.println("IndexOf = " + idx); ++ } ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/7036148-npe-null-jmenu-name.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,85 @@ +# HG changeset patch +# User alexp +# Date 1302889010 -14400 +# Node ID d353dcff4f14a1c7efcfb34a436e9ab3795ffcf9 +# Parent 71e769dc8cf689aad94c21a3b4b6f400a9f8f13c +7036148: NullPointerException with null JMenu name +Reviewed-by: rupashka + +diff -r 71e769dc8cf6 -r d353dcff4f14 src/share/classes/sun/swing/SwingUtilities2.java +--- openjdk.orig/jdk/src/share/classes/sun/swing/SwingUtilities2.java Fri Apr 15 21:26:09 2011 +0400 ++++ openjdk/jdk/src/share/classes/sun/swing/SwingUtilities2.java Fri Apr 15 21:36:50 2011 +0400 +@@ -270,11 +270,10 @@ + */ + public static int getLeftSideBearing(JComponent c, FontMetrics fm, + String string) { +- int res = 0; +- if (!string.isEmpty()) { +- res = getLeftSideBearing(c, fm, string.charAt(0)); ++ if ((string == null) || (string.length() == 0)) { ++ return 0; + } +- return res; ++ return getLeftSideBearing(c, fm, string.charAt(0)); + } + + /** +diff -r 71e769dc8cf6 -r d353dcff4f14 test/javax/swing/JMenuItem/7036148/bug7036148.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/javax/swing/JMenuItem/7036148/bug7036148.java Fri Apr 15 21:36:50 2011 +0400 +@@ -0,0 +1,53 @@ ++/* ++ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++ /* ++ * @test ++ * @bug 7036148 ++ * @summary NullPointerException with null JMenu name ++ * @author Alexander Potochkin ++ * @run main bug7036148 ++ */ ++ ++ ++import javax.swing.*; ++import java.awt.event.ActionEvent; ++ ++public class bug7036148 extends JFrame { ++ public bug7036148() { ++ JMenuBar bar = new JMenuBar(); ++ Action menuAction = new AbstractAction(null, null){ ++ public void actionPerformed(ActionEvent e) { ++ } ++ }; ++ JMenu menu = new JMenu(menuAction); ++ menu.add(new JMenuItem("test")); ++ bar.add(menu); ++ setJMenuBar(bar); ++ pack(); ++ } ++ ++ public static void main(String[] args) { ++ new bug7036148(); ++ } ++} +exporting patch: +<fdopen>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/7042070-Typo_in_Test6796786.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,33 @@ +# HG changeset patch +# User kvn +# Date 1304574077 25200 +# Node ID 37e4df3c8952604ca0b65d4bbd43aeb2e4b2e68f +# Parent dcfb3dede00994a52cf5cdc4ac078cee0a1e1b32 +7042070: Typo in Test6796786.java +Summary: The test should compare with -0.0f. +Reviewed-by: never, iveresov + +diff -r dcfb3dede009 -r 37e4df3c8952 test/compiler/6796786/Test6796786.java +--- openjdk.orig/hotspot/test/compiler/6796786/Test6796786.java Wed May 04 22:31:18 2011 -0700 ++++ openjdk/hotspot/test/compiler/6796786/Test6796786.java Wed May 04 22:41:17 2011 -0700 +@@ -27,18 +27,17 @@ + * @bug 6796786 + * @summary invalid FP identity transform - (a - b) -> b - a + * +- * @run main Test6796786 ++ * @run main/othervm -Xbatch Test6796786 + */ + + public class Test6796786 { + static volatile float d1; + static volatile float d2; +- static float zero; + + public static void main(String[] args) { + int total = 0; + for (int i = 0; i < 100000; i++) { +- if (Float.floatToRawIntBits(- (d1 - d1)) == Float.floatToRawIntBits(0.0f)) { ++ if (Float.floatToRawIntBits(- (d1 - d2)) == Float.floatToRawIntBits(-0.0f)) { + total++; + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/7047069-Array_can_dynamically_change_size.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,239 @@ +# HG changeset patch +# User kvn +# Date 1306525668 25200 +# Node ID ea0da5474c23f6d810cd9de8769e58e6e5ebbef5 +# Parent 9340a27154cb431ee287bfc8c1204f5cb483b66c +7047069: Array can dynamically change size when assigned to an object field +Summary: Fix initialization of a newly-allocated array with arraycopy +Reviewed-by: never + +diff -r 9340a27154cb -r ea0da5474c23 src/share/vm/opto/library_call.cpp +--- openjdk.orig/hotspot/src/share/vm/opto/library_call.cpp Wed May 25 21:17:07 2011 -0700 ++++ openjdk/hotspot/src/share/vm/opto/library_call.cpp Fri May 27 12:47:48 2011 -0700 +@@ -5225,15 +5225,16 @@ + + // Look at the alignment of the starting offsets. + int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type); +- const intptr_t BIG_NEG = -128; +- assert(BIG_NEG + 2*abase < 0, "neg enough"); +- +- intptr_t src_off = abase + ((intptr_t) find_int_con(src_offset, -1) << scale); +- intptr_t dest_off = abase + ((intptr_t) find_int_con(dest_offset, -1) << scale); +- if (src_off < 0 || dest_off < 0) ++ ++ intptr_t src_off_con = (intptr_t) find_int_con(src_offset, -1); ++ intptr_t dest_off_con = (intptr_t) find_int_con(dest_offset, -1); ++ if (src_off_con < 0 || dest_off_con < 0) + // At present, we can only understand constants. + return false; + ++ intptr_t src_off = abase + (src_off_con << scale); ++ intptr_t dest_off = abase + (dest_off_con << scale); ++ + if (((src_off | dest_off) & (BytesPerLong-1)) != 0) { + // Non-aligned; too bad. + // One more chance: Pick off an initial 32-bit word. +diff -r 9340a27154cb -r ea0da5474c23 test/compiler/7047069/Test7047069.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/hotspot/test/compiler/7047069/Test7047069.java Fri May 27 12:47:48 2011 -0700 +@@ -0,0 +1,200 @@ ++/* ++ * Copyright (c) 2011, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++/** ++ * @test ++ * @bug 7047069 ++ * @summary Array can dynamically change size when assigned to an object field ++ * ++ * @run main/othervm -Xbatch Test7047069 ++ */ ++ ++import java.util.*; ++import java.awt.geom.*; ++ ++public class Test7047069 { ++ static boolean verbose; ++ ++ static final int GROW_SIZE = 24; // Multiple of cubic & quad curve size ++ ++ float squareflat; // Square of the flatness parameter ++ // for testing against squared lengths ++ ++ int limit; // Maximum number of recursion levels ++ ++ float hold[] = new float[14]; // The cache of interpolated coords ++ // Note that this must be long enough ++ // to store a full cubic segment and ++ // a relative cubic segment to avoid ++ // aliasing when copying the coords ++ // of a curve to the end of the array. ++ // This is also serendipitously equal ++ // to the size of a full quad segment ++ // and 2 relative quad segments. ++ ++ int holdEnd; // The index of the last curve segment ++ // being held for interpolation ++ ++ int holdIndex; // The index of the curve segment ++ // that was last interpolated. This ++ // is the curve segment ready to be ++ // returned in the next call to ++ // currentSegment(). ++ ++ int levels[]; // The recursion level at which ++ // each curve being held in storage ++ // was generated. ++ ++ int levelIndex; // The index of the entry in the ++ // levels array of the curve segment ++ // at the holdIndex ++ ++ public static void subdivide(float src[], int srcoff, ++ float left[], int leftoff, ++ float right[], int rightoff) ++ { ++ float x1 = src[srcoff + 0]; ++ float y1 = src[srcoff + 1]; ++ float ctrlx = src[srcoff + 2]; ++ float ctrly = src[srcoff + 3]; ++ float x2 = src[srcoff + 4]; ++ float y2 = src[srcoff + 5]; ++ if (left != null) { ++ left[leftoff + 0] = x1; ++ left[leftoff + 1] = y1; ++ } ++ if (right != null) { ++ right[rightoff + 4] = x2; ++ right[rightoff + 5] = y2; ++ } ++ x1 = (x1 + ctrlx) / 2f; ++ y1 = (y1 + ctrly) / 2f; ++ x2 = (x2 + ctrlx) / 2f; ++ y2 = (y2 + ctrly) / 2f; ++ ctrlx = (x1 + x2) / 2f; ++ ctrly = (y1 + y2) / 2f; ++ if (left != null) { ++ left[leftoff + 2] = x1; ++ left[leftoff + 3] = y1; ++ left[leftoff + 4] = ctrlx; ++ left[leftoff + 5] = ctrly; ++ } ++ if (right != null) { ++ right[rightoff + 0] = ctrlx; ++ right[rightoff + 1] = ctrly; ++ right[rightoff + 2] = x2; ++ right[rightoff + 3] = y2; ++ } ++ } ++ ++ public static double getFlatnessSq(float coords[], int offset) { ++ return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1], ++ coords[offset + 4], coords[offset + 5], ++ coords[offset + 2], coords[offset + 3]); ++ } ++ ++ public Test7047069() { ++ this.squareflat = .0001f * .0001f; ++ holdIndex = hold.length - 6; ++ holdEnd = hold.length - 2; ++ hold[holdIndex + 0] = (float) (Math.random() * 100); ++ hold[holdIndex + 1] = (float) (Math.random() * 100); ++ hold[holdIndex + 2] = (float) (Math.random() * 100); ++ hold[holdIndex + 3] = (float) (Math.random() * 100); ++ hold[holdIndex + 4] = (float) (Math.random() * 100); ++ hold[holdIndex + 5] = (float) (Math.random() * 100); ++ levelIndex = 0; ++ this.limit = 10; ++ this.levels = new int[limit + 1]; ++ } ++ ++ /* ++ * Ensures that the hold array can hold up to (want) more values. ++ * It is currently holding (hold.length - holdIndex) values. ++ */ ++ void ensureHoldCapacity(int want) { ++ if (holdIndex - want < 0) { ++ int have = hold.length - holdIndex; ++ int newsize = hold.length + GROW_SIZE; ++ float newhold[] = new float[newsize]; ++ System.arraycopy(hold, holdIndex, ++ newhold, holdIndex + GROW_SIZE, ++ have); ++ if (verbose) System.err.println("old hold = "+hold+"["+hold.length+"]"); ++ if (verbose) System.err.println("replacement hold = "+newhold+"["+newhold.length+"]"); ++ hold = newhold; ++ if (verbose) System.err.println("new hold = "+hold+"["+hold.length+"]"); ++ if (verbose) System.err.println("replacement hold still = "+newhold+"["+newhold.length+"]"); ++ holdIndex += GROW_SIZE; ++ holdEnd += GROW_SIZE; ++ } ++ } ++ ++ private boolean next() { ++ if (holdIndex >= holdEnd) { ++ return false; ++ } ++ ++ int level = levels[levelIndex]; ++ while (level < limit) { ++ if (getFlatnessSq(hold, holdIndex) < squareflat) { ++ break; ++ } ++ ++ ensureHoldCapacity(4); ++ subdivide(hold, holdIndex, ++ hold, holdIndex - 4, ++ hold, holdIndex); ++ holdIndex -= 4; ++ ++ // Now that we have subdivided, we have constructed ++ // two curves of one depth lower than the original ++ // curve. One of those curves is in the place of ++ // the former curve and one of them is in the next ++ // set of held coordinate slots. We now set both ++ // curves level values to the next higher level. ++ level++; ++ levels[levelIndex] = level; ++ levelIndex++; ++ levels[levelIndex] = level; ++ } ++ ++ // This curve segment is flat enough, or it is too deep ++ // in recursion levels to try to flatten any more. The ++ // two coordinates at holdIndex+4 and holdIndex+5 now ++ // contain the endpoint of the curve which can be the ++ // endpoint of an approximating line segment. ++ holdIndex += 4; ++ levelIndex--; ++ return true; ++ } ++ ++ public static void main(String argv[]) { ++ verbose = (argv.length > 0); ++ for (int i = 0; i < 100000; i++) { ++ Test7047069 st = new Test7047069(); ++ while (st.next()) {} ++ } ++ } ++}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20110607/6213702.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,107 @@ +# HG changeset patch +# User asaha +# Date 1300988627 25200 +# Node ID bfc1a4516e20e13c84b6597d7bfcbd2fbc3e0c4d +# Parent 16fbb8d0b834c3e0a95a4d51e22ec77b81192bb3 +6213702: (so) non-blocking sockets with TCP urgent disabled get still selected for read ops (win) +Reviewed-by: alanb + +diff --git a/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java b/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java +--- openjdk/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java ++++ openjdk/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. 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 +@@ -308,14 +308,17 @@ final class WindowsSelectorImpl extends + private int processSelectedKeys(long updateCount) { + int numKeysUpdated = 0; + numKeysUpdated += processFDSet(updateCount, readFds, +- PollArrayWrapper.POLLIN); ++ PollArrayWrapper.POLLIN, ++ false); + numKeysUpdated += processFDSet(updateCount, writeFds, + PollArrayWrapper.POLLCONN | +- PollArrayWrapper.POLLOUT); ++ PollArrayWrapper.POLLOUT, ++ false); + numKeysUpdated += processFDSet(updateCount, exceptFds, + PollArrayWrapper.POLLIN | + PollArrayWrapper.POLLCONN | +- PollArrayWrapper.POLLOUT); ++ PollArrayWrapper.POLLOUT, ++ true); + return numKeysUpdated; + } + +@@ -327,7 +330,8 @@ final class WindowsSelectorImpl extends + * + * me.updateCount <= me.clearedCount <= updateCount + */ +- private int processFDSet(long updateCount, int[] fds, int rOps) { ++ private int processFDSet(long updateCount, int[] fds, int rOps, ++ boolean isExceptFds) { + int numKeysUpdated = 0; + for (int i = 1; i <= fds[0]; i++) { + int desc = fds[i]; +@@ -343,6 +347,17 @@ final class WindowsSelectorImpl extends + if (me == null) + continue; + SelectionKeyImpl sk = me.ski; ++ ++ // The descriptor may be in the exceptfds set because there is ++ // OOB data queued to the socket. If there is OOB data then it ++ // is discarded and the key is not added to the selected set. ++ if (isExceptFds && ++ (sk.channel() instanceof SocketChannelImpl) && ++ discardUrgentData(desc)) ++ { ++ continue; ++ } ++ + if (selectedKeys.contains(sk)) { // Key in selected set + if (me.clearedCount != updateCount) { + if (sk.channel.translateAndSetReadyOps(rOps, sk) && +@@ -448,6 +463,8 @@ final class WindowsSelectorImpl extends + } + + private native void resetWakeupSocket0(int wakeupSourceFd); ++ ++ private native boolean discardUrgentData(int fd); + + // We increment this counter on each call to updateSelectedKeys() + // each entry in SubSelector.fdsMap has a memorized value of +diff --git a/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c b/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c +--- openjdk/jdk/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c ++++ openjdk/jdk/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. 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 +@@ -211,3 +211,20 @@ Java_sun_nio_ch_WindowsSelectorImpl_rese + recv(scinFd, bytes, WAKEUP_SOCKET_BUF_SIZE, 0); + } + } ++ ++JNIEXPORT jboolean JNICALL ++Java_sun_nio_ch_WindowsSelectorImpl_discardUrgentData(JNIEnv* env, jobject this, ++ jint s) ++{ ++ char data[8]; ++ jboolean discarded = JNI_FALSE; ++ int n; ++ do { ++ n = recv(s, data, sizeof(data), MSG_OOB); ++ if (n > 0) { ++ discarded = JNI_TRUE; ++ } ++ } while (n > 0); ++ return discarded; ++} ++
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20110607/6618658.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,25 @@ +--- openjdk/jdk/src/share/classes/java/security/SignedObject.java 2011-02-09 16:33:11.000000000 +0800 ++++ openjdk/jdk/src/share/classes/java/security/SignedObject.java 2011-02-09 16:33:10.000000000 +0800 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. 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 +@@ -249,10 +249,10 @@ + * a stream. + */ + private void readObject(java.io.ObjectInputStream s) +- throws java.io.IOException, ClassNotFoundException +- { +- s.defaultReadObject(); +- content = content.clone(); +- signature = signature.clone(); ++ throws java.io.IOException, ClassNotFoundException { ++ java.io.ObjectInputStream.GetField fields = s.readFields(); ++ content = ((byte[])fields.get("content", null)).clone(); ++ signature = ((byte[])fields.get("signature", null)).clone(); ++ thealgorithm = (String)fields.get("thealgorithm", null); + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20110607/7012520.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,25 @@ +# HG changeset patch +# User dcherepanov +# Date 1301921550 -14400 +# Node ID 049b0098d27c509fd57843ab4ea7aa5fa5fc84bd +# Parent dc0eabbd9955ebe6a40aa931d6f3333e1f50a1b2 +7012520: Heap overflow vulnerability in FileDialog.show() +Reviewed-by: art, anthony + +diff --git a/src/windows/native/sun/windows/awt_FileDialog.cpp b/src/windows/native/sun/windows/awt_FileDialog.cpp +--- openjdk/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp ++++ openjdk/jdk/src/windows/native/sun/windows/awt_FileDialog.cpp +@@ -231,11 +231,12 @@ AwtFileDialog::Show(void *p) + JavaStringBuffer directoryBuffer(env, directory); + + fileBuffer = new TCHAR[MAX_PATH+1]; ++ memset(fileBuffer, 0, (MAX_PATH+1) * sizeof(TCHAR)); + + file = (jstring)env->GetObjectField(target, AwtFileDialog::fileID); + if (file != NULL) { + LPCTSTR tmp = JNU_GetStringPlatformChars(env, file, NULL); +- _tcscpy(fileBuffer, tmp); ++ _tcsncpy(fileBuffer, tmp, MAX_PATH-1); // the fileBuffer is double null terminated string + JNU_ReleaseStringPlatformChars(env, file, tmp); + } else { + fileBuffer[0] = _T('\0');
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20110607/7013519.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,50 @@ +# HG changeset patch +# User bae +# Date 1301414029 -14400 +# Node ID dc0eabbd9955ebe6a40aa931d6f3333e1f50a1b2 +# Parent bfc1a4516e20e13c84b6597d7bfcbd2fbc3e0c4d +7013519: [parfait] Integer overflows in 2D code +Reviewed-by: prr + +diff --git a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c +--- openjdk/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c ++++ openjdk/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c +@@ -40,6 +40,7 @@ + #include <setjmp.h> + #include <assert.h> + #include <string.h> ++#include <limits.h> + + + /* java native interface headers */ +@@ -1921,6 +1922,14 @@ Java_com_sun_imageio_plugins_jpeg_JPEGIm + } + + // Allocate a 1-scanline buffer ++ if (cinfo->num_components <= 0 || ++ cinfo->image_width > (UINT_MAX / (unsigned int)cinfo->num_components)) ++ { ++ RELEASE_ARRAYS(env, data, src->next_input_byte); ++ JNU_ThrowByName(env, "javax/imageio/IIOException", ++ "Invalid number of color components"); ++ return data->abortFlag; ++ } + scanLinePtr = (JSAMPROW)malloc(cinfo->image_width*cinfo->num_components); + if (scanLinePtr == NULL) { + RELEASE_ARRAYS(env, data, src->next_input_byte); +diff --git a/src/share/native/sun/font/layout/SunLayoutEngine.cpp b/src/share/native/sun/font/layout/SunLayoutEngine.cpp +--- openjdk/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp ++++ openjdk/jdk/src/share/native/sun/font/layout/SunLayoutEngine.cpp +@@ -186,7 +186,11 @@ JNIEXPORT void JNICALL Java_sun_font_Sun + jchar buffer[256]; + jchar* chars = buffer; + if (len > 256) { +- chars = (jchar*)malloc(len * sizeof(jchar)); ++ size_t size = len * sizeof(jchar); ++ if (size / sizeof(jchar) != len) { ++ return; ++ } ++ chars = (jchar*)malloc(size); + if (chars == 0) { + return; + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20110607/7013969.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,26 @@ +# HG changeset patch +# User chegar +# Date 1298025619 0 +# Node ID 4c569f18b5a1f4eeb7e13fafba7375e39a5b9161 +# Parent 05a59c28ae9fcb8f7c3362a4e1eeeaa1818edbdc +7013969: NetworkInterface.toString can reveal bindings +Reviewed-by: alanb, michaelm, hawtin + +diff --git a/src/share/classes/java/net/NetworkInterface.java b/src/share/classes/java/net/NetworkInterface.java +--- openjdk/jdk/src/share/classes/java/net/NetworkInterface.java ++++ openjdk/jdk/src/share/classes/java/net/NetworkInterface.java +@@ -527,13 +527,8 @@ public final class NetworkInterface { + if (displayName != null) { + result += " (" + displayName + ")"; + } +- result += " index: "+index+" addresses:\n"; +- for (Enumeration e = getInetAddresses(); e.hasMoreElements(); ) { +- InetAddress addr = (InetAddress)e.nextElement(); +- result += addr+";\n"; +- } + return result; + } ++ + private static native void init(); +- + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20110607/7013971.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,134 @@ +diff -Nru openjdk.orig/jaxws/build.properties openjdk/jaxws/build.properties +--- openjdk.orig/jaxws/build.properties 2011-05-23 22:48:31.989289627 +0100 ++++ openjdk/jaxws/build.properties 2011-05-23 22:49:09.841901697 +0100 +@@ -77,6 +77,9 @@ + # Where patches to drop bundle sources live + patches.dir=patches + ++# Patches to apply ++jaxws_src.patch.list=7013971.patch ++ + # Sanity information + sanity.info= Sanity Settings:${line.separator}\ + ant.home=${ant.home}${line.separator}\ +diff -Nru openjdk.orig/jaxws/patches/jaxws_src/7013971.patch openjdk/jaxws/patches/jaxws_src/7013971.patch +--- openjdk.orig/jaxws/patches/jaxws_src/7013971.patch 1970-01-01 01:00:00.000000000 +0100 ++++ openjdk/jaxws/patches/jaxws_src/7013971.patch 2011-05-23 22:50:07.414832540 +0100 +@@ -0,0 +1,117 @@ ++--- src/com/sun/xml/internal/messaging/saaj/client/p2p/HttpSOAPConnection.java Tue Jul 21 14:54:59 2009 -0700 +++++ src/com/sun/xml/internal/messaging/saaj/client/p2p/HttpSOAPConnection.java Mon Feb 14 09:09:00 2011 +0530 ++@@ -72,16 +72,11 @@ public class HttpSOAPConnection extends ++ Logger.getLogger(LogDomainConstants.HTTP_CONN_DOMAIN, ++ "com.sun.xml.internal.messaging.saaj.client.p2p.LocalStrings"); ++ ++- private static final String defaultProxyHost = null; ++- private static final int defaultProxyPort = -1; ++- ++ MessageFactory messageFactory = null; ++ ++ boolean closed = false; ++ ++ public HttpSOAPConnection() throws SOAPException { ++- proxyHost = defaultProxyHost; ++- proxyPort = defaultProxyPort; ++ ++ try { ++ messageFactory = MessageFactory.newInstance(SOAPConstants.DYNAMIC_SOAP_PROTOCOL); ++@@ -157,11 +152,7 @@ public class HttpSOAPConnection extends ++ ++ if (endPoint instanceof URL) ++ try { ++- PriviledgedPost pp = ++- new PriviledgedPost(this, message, (URL) endPoint); ++- SOAPMessage response = ++- (SOAPMessage) AccessController.doPrivileged(pp); ++- +++ SOAPMessage response = post(message, (URL) endPoint); ++ return response; ++ } catch (Exception ex) { ++ // TBD -- chaining? ++@@ -170,73 +161,6 @@ public class HttpSOAPConnection extends ++ log.severe("SAAJ0007.p2p.bad.endPoint.type"); ++ throw new SOAPExceptionImpl("Bad endPoint type " + endPoint); ++ } ++- } ++- ++- static class PriviledgedPost implements PrivilegedExceptionAction { ++- ++- HttpSOAPConnection c; ++- SOAPMessage message; ++- URL endPoint; ++- ++- PriviledgedPost( ++- HttpSOAPConnection c, ++- SOAPMessage message, ++- URL endPoint) { ++- this.c = c; ++- this.message = message; ++- this.endPoint = endPoint; ++- } ++- ++- public Object run() throws Exception { ++- return c.post(message, endPoint); ++- } ++- } ++- ++- // TBD ++- // Fix this to do things better. ++- ++- private String proxyHost = null; ++- ++- static class PriviledgedSetProxyAction implements PrivilegedExceptionAction { ++- ++- String proxyHost = null; ++- int proxyPort = 0; ++- ++- PriviledgedSetProxyAction(String host, int port) { ++- this.proxyHost = host; ++- this.proxyPort = port; ++- } ++- ++- public Object run() throws Exception { ++- System.setProperty("http.proxyHost", proxyHost); ++- System.setProperty("http.proxyPort", new Integer(proxyPort).toString()); ++- log.log(Level.FINE, "SAAJ0050.p2p.proxy.host", ++- new String[] { proxyHost }); ++- log.log(Level.FINE, "SAAJ0051.p2p.proxy.port", ++- new String[] { new Integer(proxyPort).toString() }); ++- return proxyHost; ++- } ++- } ++- ++- ++- public void setProxy(String host, int port) { ++- try { ++- proxyPort = port; ++- PriviledgedSetProxyAction ps = new PriviledgedSetProxyAction(host, port); ++- proxyHost = (String) AccessController.doPrivileged(ps); ++- } catch (Exception e) { ++- throw new RuntimeException(e); ++- } ++- } ++- ++- public String getProxyHost() { ++- return proxyHost; ++- } ++- ++- private int proxyPort = -1; ++- ++- public int getProxyPort() { ++- return proxyPort; ++ } ++ ++ SOAPMessage post(SOAPMessage message, URL endPoint) throws SOAPException { ++--- src/com/sun/xml/internal/messaging/saaj/client/p2p/HttpSOAPConnection.java Mon Feb 14 09:09:00 2011 +0530 +++++ src/com/sun/xml/internal/messaging/saaj/client/p2p/HttpSOAPConnection.java Wed Feb 16 00:11:00 2011 +0530 ++@@ -201,7 +201,7 @@ public class HttpSOAPConnection extends ++ httpConnection.setDoOutput(true); ++ httpConnection.setDoInput(true); ++ httpConnection.setUseCaches(false); ++- HttpURLConnection.setFollowRedirects(true); +++ httpConnection.setInstanceFollowRedirects(true); ++ ++ if (message.saveRequired()) ++ message.saveChanges();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20110607/7016495.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,424 @@ +# HG changeset patch +# User flar +# Date 1299032055 28800 +# Node ID 50636a6053f85b1355152385560c5856ea14dc3f +# Parent 4c569f18b5a1f4eeb7e13fafba7375e39a5b9161 +7016495: Crash in Java 2D transforming an image with scale close to zero +Reviewed-by: prr, bae + +diff --git a/src/share/classes/sun/java2d/pipe/DrawImage.java b/src/share/classes/sun/java2d/pipe/DrawImage.java +--- openjdk/jdk/src/share/classes/sun/java2d/pipe/DrawImage.java ++++ openjdk/jdk/src/share/classes/sun/java2d/pipe/DrawImage.java +@@ -509,6 +509,9 @@ public class DrawImage implements DrawIm + * edges thus has to be h*2+2 in length + */ + int edges[] = new int[(dy2-dy1)*2+2]; ++ // It is important that edges[0]=edges[1]=0 when we call ++ // Transform in case it must return early and we would ++ // not want to render anything on an error condition. + helper.Transform(tmpmaskblit, srcData, tmpData, + AlphaComposite.Src, null, + itx, interpType, +diff --git a/src/share/native/sun/java2d/loops/TransformHelper.c b/src/share/native/sun/java2d/loops/TransformHelper.c +--- openjdk/jdk/src/share/native/sun/java2d/loops/TransformHelper.c ++++ openjdk/jdk/src/share/native/sun/java2d/loops/TransformHelper.c +@@ -75,6 +75,94 @@ TransformInterpFunc *pBicubicFunc = Bicu + TransformInterpFunc *pBicubicFunc = BicubicInterp; + + /* ++ * The dxydxy parameters of the inverse transform determine how ++ * quickly we step through the source image. For tiny scale ++ * factors (on the order of 1E-16 or so) the stepping distances ++ * are huge. The image has been scaled so small that stepping ++ * a single pixel in device space moves the sampling point by ++ * billions (or more) pixels in the source image space. These ++ * huge stepping values can overflow the whole part of the longs ++ * we use for the fixed point stepping equations and so we need ++ * a more robust solution. We could simply iterate over every ++ * device pixel, use the inverse transform to transform it back ++ * into the source image coordinate system and then test it for ++ * being in range and sample pixel-by-pixel, but that is quite ++ * a bit more expensive. Fortunately, if the scale factors are ++ * so tiny that we overflow our long values then the number of ++ * pixels we are planning to visit should be very tiny. The only ++ * exception to that rule is if the scale factor along one ++ * dimension is tiny (creating the huge stepping values), and ++ * the scale factor along the other dimension is fairly regular ++ * or an up-scale. In that case we have a lot of pixels along ++ * the direction of the larger axis to sample, but few along the ++ * smaller axis. Though, pessimally, with an added shear factor ++ * such a linearly tiny image could have bounds that cover a large ++ * number of pixels. Such odd transformations should be very ++ * rare and the absolute limit on calculations would involve a ++ * single reverse transform of every pixel in the output image ++ * which is not fast, but it should not cause an undue stall ++ * of the rendering software. ++ * ++ * The specific test we will use is to calculate the inverse ++ * transformed values of every corner of the destination bounds ++ * (in order to be user-clip independent) and if we can ++ * perform a fixed-point-long inverse transform of all of ++ * those points without overflowing we will use the fast ++ * fixed point algorithm. Otherwise we will use the safe ++ * per-pixel transform algorithm. ++ * The 4 corners are 0,0, 0,dsth, dstw,0, dstw,dsth ++ * Transformed they are: ++ * tx, ty ++ * tx +dxdy*H, ty +dydy*H ++ * tx+dxdx*W, ty+dydx*W ++ * tx+dxdx*W+dxdy*H, ty+dydx*W+dydy*H ++ */ ++/* We reject coordinates not less than 1<<30 so that the distance between */ ++/* any 2 of them is less than 1<<31 which would overflow into the sign */ ++/* bit of a signed long value used to represent fixed point coordinates. */ ++#define TX_FIXED_UNSAFE(v) (fabs(v) >= (1<<30)) ++static jboolean ++checkOverflow(jint dxoff, jint dyoff, ++ SurfaceDataBounds *pBounds, ++ TransformInfo *pItxInfo, ++ jdouble *retx, jdouble *rety) ++{ ++ jdouble x, y; ++ ++ x = dxoff+pBounds->x1+0.5; /* Center of pixel x1 */ ++ y = dyoff+pBounds->y1+0.5; /* Center of pixel y1 */ ++ Transform_transform(pItxInfo, &x, &y); ++ *retx = x; ++ *rety = y; ++ if (TX_FIXED_UNSAFE(x) || TX_FIXED_UNSAFE(y)) { ++ return JNI_TRUE; ++ } ++ ++ x = dxoff+pBounds->x2-0.5; /* Center of pixel x2-1 */ ++ y = dyoff+pBounds->y1+0.5; /* Center of pixel y1 */ ++ Transform_transform(pItxInfo, &x, &y); ++ if (TX_FIXED_UNSAFE(x) || TX_FIXED_UNSAFE(y)) { ++ return JNI_TRUE; ++ } ++ ++ x = dxoff+pBounds->x1+0.5; /* Center of pixel x1 */ ++ y = dyoff+pBounds->y2-0.5; /* Center of pixel y2-1 */ ++ Transform_transform(pItxInfo, &x, &y); ++ if (TX_FIXED_UNSAFE(x) || TX_FIXED_UNSAFE(y)) { ++ return JNI_TRUE; ++ } ++ ++ x = dxoff+pBounds->x2-0.5; /* Center of pixel x2-1 */ ++ y = dyoff+pBounds->y2-0.5; /* Center of pixel y2-1 */ ++ Transform_transform(pItxInfo, &x, &y); ++ if (TX_FIXED_UNSAFE(x) || TX_FIXED_UNSAFE(y)) { ++ return JNI_TRUE; ++ } ++ ++ return JNI_FALSE; ++} ++ ++/* + * Fill the edge buffer with pairs of coordinates representing the maximum + * left and right pixels of the destination surface that should be processed + * on each scanline, clipped to the bounds parameter. +@@ -82,21 +170,19 @@ TransformInterpFunc *pBicubicFunc = Bicu + * Only pixels that map back through the specified (inverse) transform to a + * source coordinate that falls within the (0, 0, sw, sh) bounds of the + * source image should be processed. +- * pEdgeBuf points to an array of jints that holds MAXEDGES*2 values. +- * If more storage is needed, then this function allocates a new buffer. +- * In either case, a pointer to the buffer actually used to store the +- * results is returned. +- * The caller is responsible for freeing the buffer if the return value +- * is not the same as the original pEdgeBuf passed in. ++ * pEdges points to an array of jints that holds 2 + numedges*2 values where ++ * numedges should match (pBounds->y2 - pBounds->y1). ++ * The first two jints in pEdges should be set to y1 and y2 and every pair ++ * of jints after that represent the xmin,xmax of all pixels in range of ++ * the transformed blit for the corresponding scanline. + */ +-static jint * +-calculateEdges(jint *pEdgeBuf, ++static void ++calculateEdges(jint *pEdges, + SurfaceDataBounds *pBounds, + TransformInfo *pItxInfo, + jlong xbase, jlong ybase, + juint sw, juint sh) + { +- jint *pEdges; + jlong dxdxlong, dydxlong; + jlong dxdylong, dydylong; + jlong drowxlong, drowylong; +@@ -111,10 +197,8 @@ calculateEdges(jint *pEdgeBuf, + dy1 = pBounds->y1; + dx2 = pBounds->x2; + dy2 = pBounds->y2; +- if ((dy2-dy1) > MAXEDGES) { +- pEdgeBuf = malloc(2 * (dy2-dy1) * sizeof (*pEdges)); +- } +- pEdges = pEdgeBuf; ++ *pEdges++ = dy1; ++ *pEdges++ = dy2; + + drowxlong = (dx2-dx1-1) * dxdxlong; + drowylong = (dx2-dx1-1) * dydxlong; +@@ -155,9 +239,21 @@ calculateEdges(jint *pEdgeBuf, + ybase += dydylong; + dy1++; + } ++} + +- return pEdgeBuf; +-} ++static void ++Transform_SafeHelper(JNIEnv *env, ++ SurfaceDataOps *srcOps, ++ SurfaceDataOps *dstOps, ++ SurfaceDataRasInfo *pSrcInfo, ++ SurfaceDataRasInfo *pDstInfo, ++ NativePrimitive *pMaskBlitPrim, ++ CompositeInfo *pCompInfo, ++ TransformHelperFunc *pHelperFunc, ++ TransformInterpFunc *pInterpFunc, ++ RegionData *pClipInfo, TransformInfo *pItxInfo, ++ jint *pData, jint *pEdges, ++ jint dxoff, jint dyoff, jint sw, jint sh); + + /* + * Class: sun_java2d_loops_TransformHelper +@@ -187,12 +283,14 @@ Java_sun_java2d_loops_TransformHelper_Tr + jint maxlinepix; + TransformHelperFunc *pHelperFunc; + TransformInterpFunc *pInterpFunc; +- jint edgebuf[MAXEDGES * 2]; ++ jdouble xorig, yorig; ++ jint numedges; + jint *pEdges; +- jdouble x, y; +- jlong xbase, ybase; +- jlong dxdxlong, dydxlong; +- jlong dxdylong, dydylong; ++ jint edgebuf[2 + MAXEDGES * 2]; ++ union { ++ jlong align; ++ jint data[LINE_SIZE]; ++ } rgb; + + #ifdef MAKE_STUBS + static int th_initialized; +@@ -269,39 +367,62 @@ Java_sun_java2d_loops_TransformHelper_Tr + if (srcOps->Lock(env, srcOps, &srcInfo, pHelperPrim->srcflags) + != SD_SUCCESS) + { ++ /* edgeArray should already contain zeros for min/maxy */ + return; + } + if (dstOps->Lock(env, dstOps, &dstInfo, pMaskBlitPrim->dstflags) + != SD_SUCCESS) + { + SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); ++ /* edgeArray should already contain zeros for min/maxy */ + return; + } + Region_IntersectBounds(&clipInfo, &dstInfo.bounds); + ++ numedges = (dstInfo.bounds.y2 - dstInfo.bounds.y1); ++ if (numedges > MAXEDGES) { ++ pEdges = malloc((2 + 2 * numedges) * sizeof (*pEdges)); ++ if (pEdges == NULL) { ++ SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); ++ SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); ++ /* edgeArray should already contain zeros for min/maxy */ ++ return; ++ } ++ } else { ++ pEdges = edgebuf; ++ } ++ + Transform_GetInfo(env, itxform, &itxInfo); +- dxdxlong = DblToLong(itxInfo.dxdx); +- dydxlong = DblToLong(itxInfo.dydx); +- dxdylong = DblToLong(itxInfo.dxdy); +- dydylong = DblToLong(itxInfo.dydy); +- x = dxoff+dstInfo.bounds.x1+0.5; /* Center of pixel x1 */ +- y = dyoff+dstInfo.bounds.y1+0.5; /* Center of pixel y1 */ +- Transform_transform(&itxInfo, &x, &y); +- xbase = DblToLong(x); +- ybase = DblToLong(y); +- +- pEdges = calculateEdges(edgebuf, &dstInfo.bounds, &itxInfo, +- xbase, ybase, sx2-sx1, sy2-sy1); + + if (!Region_IsEmpty(&clipInfo)) { + srcOps->GetRasInfo(env, srcOps, &srcInfo); + dstOps->GetRasInfo(env, dstOps, &dstInfo); +- if (srcInfo.rasBase && dstInfo.rasBase) { +- union { +- jlong align; +- jint data[LINE_SIZE]; +- } rgb; ++ if (srcInfo.rasBase == NULL || dstInfo.rasBase == NULL) { ++ pEdges[0] = pEdges[1] = 0; ++ } else if (checkOverflow(dxoff, dyoff, &dstInfo.bounds, ++ &itxInfo, &xorig, &yorig)) ++ { ++ Transform_SafeHelper(env, srcOps, dstOps, ++ &srcInfo, &dstInfo, ++ pMaskBlitPrim, &compInfo, ++ pHelperFunc, pInterpFunc, ++ &clipInfo, &itxInfo, rgb.data, pEdges, ++ dxoff, dyoff, sx2-sx1, sy2-sy1); ++ } else { + SurfaceDataBounds span; ++ jlong dxdxlong, dydxlong; ++ jlong dxdylong, dydylong; ++ jlong xbase, ybase; ++ ++ dxdxlong = DblToLong(itxInfo.dxdx); ++ dydxlong = DblToLong(itxInfo.dydx); ++ dxdylong = DblToLong(itxInfo.dxdy); ++ dydylong = DblToLong(itxInfo.dydy); ++ xbase = DblToLong(xorig); ++ ybase = DblToLong(yorig); ++ ++ calculateEdges(pEdges, &dstInfo.bounds, &itxInfo, ++ xbase, ybase, sx2-sx1, sy2-sy1); + + Region_StartIteration(env, &clipInfo); + while (Region_NextIteration(&clipInfo, &span)) { +@@ -318,8 +439,8 @@ Java_sun_java2d_loops_TransformHelper_Tr + + /* Note - process at most one scanline at a time. */ + +- dx1 = pEdges[(dy1 - dstInfo.bounds.y1) * 2]; +- dx2 = pEdges[(dy1 - dstInfo.bounds.y1) * 2 + 1]; ++ dx1 = pEdges[(dy1 - dstInfo.bounds.y1) * 2 + 2]; ++ dx2 = pEdges[(dy1 - dstInfo.bounds.y1) * 2 + 3]; + if (dx1 < span.x1) dx1 = span.x1; + if (dx2 > span.x2) dx2 = span.x2; + +@@ -376,19 +497,122 @@ Java_sun_java2d_loops_TransformHelper_Tr + } + SurfaceData_InvokeRelease(env, dstOps, &dstInfo); + SurfaceData_InvokeRelease(env, srcOps, &srcInfo); ++ } else { ++ pEdges[0] = pEdges[1] = 0; + } + SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); + SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); + if (!JNU_IsNull(env, edgeArray)) { +- (*env)->SetIntArrayRegion(env, edgeArray, 0, 1, &dstInfo.bounds.y1); +- (*env)->SetIntArrayRegion(env, edgeArray, 1, 1, &dstInfo.bounds.y2); +- (*env)->SetIntArrayRegion(env, edgeArray, +- 2, (dstInfo.bounds.y2 - dstInfo.bounds.y1)*2, +- pEdges); ++ (*env)->SetIntArrayRegion(env, edgeArray, 0, 2+numedges*2, pEdges); + } + if (pEdges != edgebuf) { + free(pEdges); + } ++} ++ ++static void ++Transform_SafeHelper(JNIEnv *env, ++ SurfaceDataOps *srcOps, ++ SurfaceDataOps *dstOps, ++ SurfaceDataRasInfo *pSrcInfo, ++ SurfaceDataRasInfo *pDstInfo, ++ NativePrimitive *pMaskBlitPrim, ++ CompositeInfo *pCompInfo, ++ TransformHelperFunc *pHelperFunc, ++ TransformInterpFunc *pInterpFunc, ++ RegionData *pClipInfo, TransformInfo *pItxInfo, ++ jint *pData, jint *pEdges, ++ jint dxoff, jint dyoff, jint sw, jint sh) ++{ ++ SurfaceDataBounds span; ++ jint dx1, dx2; ++ jint dy1, dy2; ++ jint i, iy; ++ ++ dy1 = pDstInfo->bounds.y1; ++ dy2 = pDstInfo->bounds.y2; ++ dx1 = pDstInfo->bounds.x1; ++ dx2 = pDstInfo->bounds.x2; ++ pEdges[0] = dy1; ++ pEdges[1] = dy2; ++ for (iy = dy1; iy < dy2; iy++) { ++ jint i = (iy - dy1) * 2; ++ /* row spans are set to max,min until we find a pixel in range below */ ++ pEdges[i + 2] = dx2; ++ pEdges[i + 3] = dx1; ++ } ++ ++ Region_StartIteration(env, pClipInfo); ++ while (Region_NextIteration(pClipInfo, &span)) { ++ dy1 = span.y1; ++ dy2 = span.y2; ++ while (dy1 < dy2) { ++ dx1 = span.x1; ++ dx2 = span.x2; ++ i = (dy1 - pDstInfo->bounds.y1) * 2; ++ while (dx1 < dx2) { ++ jdouble x, y; ++ jlong xlong, ylong; ++ ++ x = dxoff + dx1 + 0.5; ++ y = dyoff + dy1 + 0.5; ++ Transform_transform(pItxInfo, &x, &y); ++ xlong = DblToLong(x); ++ ylong = DblToLong(y); ++ ++ /* Process only pixels with centers in bounds ++ * Test double values to avoid overflow in conversion ++ * to long values and then also test the long values ++ * in case they rounded up and out of bounds during ++ * the conversion. ++ */ ++ if (x >= 0 && y >= 0 && x < sw && y < sh && ++ WholeOfLong(xlong) < sw && ++ WholeOfLong(ylong) < sh) ++ { ++ void *pDst; ++ ++ if (pEdges[i + 2] > dx1) { ++ pEdges[i + 2] = dx1; ++ } ++ if (pEdges[i + 3] <= dx1) { ++ pEdges[i + 3] = dx1 + 1; ++ } ++ ++ /* Get IntArgbPre pixel data from source */ ++ (*pHelperFunc)(pSrcInfo, ++ pData, 1, ++ xlong, 0, ++ ylong, 0); ++ ++ /* Interpolate result pixels if needed */ ++ if (pInterpFunc) { ++ (*pInterpFunc)(pData, 1, ++ FractOfLong(xlong-LongOneHalf), 0, ++ FractOfLong(ylong-LongOneHalf), 0); ++ } ++ ++ /* Store/Composite interpolated pixels into dest */ ++ pDst = PtrCoord(pDstInfo->rasBase, ++ dx1, pDstInfo->pixelStride, ++ dy1, pDstInfo->scanStride); ++ (*pMaskBlitPrim->funcs.maskblit)(pDst, pData, ++ 0, 0, 0, ++ 1, 1, ++ pDstInfo, pSrcInfo, ++ pMaskBlitPrim, ++ pCompInfo); ++ } ++ ++ /* Increment to next input pixel */ ++ dx1++; ++ } ++ ++ /* Increment to next scanline */ ++ dy1++; ++ } ++ } ++ Region_EndIteration(env, pClipInfo); + } + + #define BL_INTERP_V1_to_V2_by_F(v1, v2, f) \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20110607/7020198.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,139 @@ +# HG changeset patch +# User alexp +# Date 1305650123 -14400 +# Node ID 055d6c57c43057e076396142aae7b53272e8a5fa +# Parent bf0758eb099e803a6353e96dd02f085e970900d0 +7020198: ImageIcon creates Component with null acc +Reviewed-by: rupashka + +diff --git a/src/share/classes/javax/swing/ImageIcon.java b/src/share/classes/javax/swing/ImageIcon.java +--- openjdk/jdk/src/share/classes/javax/swing/ImageIcon.java ++++ openjdk/jdk/src/share/classes/javax/swing/ImageIcon.java +@@ -36,6 +36,9 @@ import java.util.Locale; + import java.util.Locale; + import javax.accessibility.*; + ++import sun.awt.AppContext; ++import java.lang.reflect.Field; ++import java.security.*; + + /** + * An implementation of the Icon interface that paints Icons +@@ -75,13 +78,59 @@ public class ImageIcon implements Icon, + ImageObserver imageObserver; + String description = null; + +- protected final static Component component = new Component() {}; +- protected final static MediaTracker tracker = new MediaTracker(component); ++ // Fields for twisted backward compatibility only. DO NOT USE. ++ protected final static Component component; ++ protected final static MediaTracker tracker; ++ ++ static { ++ component = AccessController.doPrivileged(new PrivilegedAction<Component>() { ++ public Component run() { ++ ++ try { ++ final Component component = createNoPermsComponent(); ++ ++ // 6482575 - clear the appContext field so as not to leak it ++ Field appContextField = ++ ++ Component.class.getDeclaredField("appContext"); ++ appContextField.setAccessible(true); ++ appContextField.set(component, null); ++ ++ return component; ++ } catch (Throwable e) { ++ // We don't care about component. ++ // So don't prevent class initialisation. ++ e.printStackTrace(); ++ ++ return null; ++ } ++ } ++ }); ++ tracker = new MediaTracker(component); ++ } ++ ++ private static Component createNoPermsComponent() { ++ // 7020198 - set acc field to no permissions and no subject ++ // Note, will have appContext set. ++ return AccessController.doPrivileged( ++ new PrivilegedAction<Component>() { ++ public Component run() { ++ return new Component() { ++ }; ++ } ++ }, ++ new AccessControlContext(new ProtectionDomain[]{ ++ new ProtectionDomain(null, null) ++ }) ++ ); ++ } + + /** + * Id used in loading images from MediaTracker. + */ + private static int mediaTrackerID; ++ ++ private final static Object TRACKER_KEY = new StringBuilder("TRACKER_KEY"); + + int width = -1; + int height = -1; +@@ -243,17 +292,18 @@ public class ImageIcon implements Icon, + * @param image the image + */ + protected void loadImage(Image image) { +- synchronized(tracker) { ++ MediaTracker mTracker = getTracker(); ++ synchronized(mTracker) { + int id = getNextID(); + +- tracker.addImage(image, id); ++ mTracker.addImage(image, id); + try { +- tracker.waitForID(id, 0); ++ mTracker.waitForID(id, 0); + } catch (InterruptedException e) { + System.out.println("INTERRUPTED while loading Image"); + } +- loadStatus = tracker.statusID(id, false); +- tracker.removeImage(image, id); ++ loadStatus = mTracker.statusID(id, false); ++ mTracker.removeImage(image, id); + + width = image.getWidth(imageObserver); + height = image.getHeight(imageObserver); +@@ -264,9 +314,30 @@ public class ImageIcon implements Icon, + * Returns an ID to use with the MediaTracker in loading an image. + */ + private int getNextID() { +- synchronized(tracker) { ++ synchronized(getTracker()) { + return ++mediaTrackerID; + } ++ } ++ ++ /** ++ * Returns the MediaTracker for the current AppContext, creating a new ++ * MediaTracker if necessary. ++ */ ++ private MediaTracker getTracker() { ++ Object trackerObj; ++ AppContext ac = AppContext.getAppContext(); ++ // Opt: Only synchronize if trackerObj comes back null? ++ // If null, synchronize, re-check for null, and put new tracker ++ synchronized (ac) { ++ trackerObj = ac.get(TRACKER_KEY); ++ if (trackerObj == null) { ++ Component comp = new Component() { ++ }; ++ trackerObj = new MediaTracker(comp); ++ ac.put(TRACKER_KEY, trackerObj); ++ } ++ } ++ return (MediaTracker) trackerObj; + } + + /**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20110607/7020373.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,38 @@ +# HG changeset patch +# User kamg +# Date 1300992148 14400 +# Node ID f6b8cfca1b530e9f7fd9a0c95eeb239afdb53177 +# Parent 4863fa64ae5f5c96c36c68c5c2bb765e23a5d697 +7020373: JSR rewriting can overflow memory address size variables +Summary: Abort if incoming classfile's parameters would cause overflows +Reviewed-by: coleenp, dcubed, never + +diff --git a/src/share/vm/oops/generateOopMap.cpp b/src/share/vm/oops/generateOopMap.cpp +--- openjdk/hotspot/src/share/vm/oops/generateOopMap.cpp ++++ openjdk/hotspot/src/share/vm/oops/generateOopMap.cpp +@@ -956,10 +956,21 @@ void GenerateOopMap::init_basic_blocks() + // initialize the CellTypeState-related information. + init_state(); + +- // We allocate space for all state-vectors for all basicblocks in one huge chuck. +- // Then in the next part of the code, we set a pointer in each _basic_block that +- // points to each piece. +- CellTypeState *basicBlockState = NEW_RESOURCE_ARRAY(CellTypeState, bbNo * _state_len); ++ // We allocate space for all state-vectors for all basicblocks in one huge ++ // chunk. Then in the next part of the code, we set a pointer in each ++ // _basic_block that points to each piece. ++ ++ // The product of bbNo and _state_len can get large if there are lots of ++ // basic blocks and stack/locals/monitors. Need to check to make sure ++ // we don't overflow the capacity of a pointer. ++ if ((unsigned)bbNo > UINTPTR_MAX / sizeof(CellTypeState) / _state_len) { ++ report_error("The amount of memory required to analyze this method " ++ "exceeds addressable range"); ++ return; ++ } ++ ++ CellTypeState *basicBlockState = ++ NEW_RESOURCE_ARRAY(CellTypeState, bbNo * _state_len); + memset(basicBlockState, 0, bbNo * _state_len * sizeof(CellTypeState)); + + // Make a pass over the basicblocks and assign their state vectors.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/support_linux_3.patch Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,19 @@ +# HG changeset patch +# User andrew +# Date 1309217125 -3600 +# Node ID f7e8b10f51c6a622520b55df0c644fb09ec78542 +# Parent b8227c320dec384a94026fcaa650b0ebd4eef13b +Allow building HotSpot with any Linux 3 version. + +diff -r b8227c320dec -r f7e8b10f51c6 make/linux/Makefile +--- openjdk/hotspot/make/linux/Makefile Wed Jun 15 18:56:52 2011 +0100 ++++ openjdk/hotspot/make/linux/Makefile Tue Jun 28 00:25:25 2011 +0100 +@@ -230,7 +230,7 @@ + # Solaris 2.5.1, 2.6). + # Disable this check by setting DISABLE_HOTSPOT_OS_VERSION_CHECK=ok. + +-SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 2.7% ++SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 3% + OS_VERSION := $(shell uname -r) + EMPTY_IF_NOT_SUPPORTED = $(filter $(SUPPORTED_OS_VERSION),$(OS_VERSION)) +
--- a/patches/xjc.patch Wed Jun 01 02:35:43 2011 +0100 +++ b/patches/xjc.patch Wed Jul 06 17:11:34 2011 +0100 @@ -1,19 +1,18 @@ diff -Nru openjdk.orig/jaxws/build.properties openjdk/jaxws/build.properties ---- openjdk.orig/jaxws/build.properties 2009-12-04 16:41:02.000000000 +0000 -+++ openjdk/jaxws/build.properties 2009-12-04 16:41:47.000000000 +0000 -@@ -73,6 +73,9 @@ - # Where patches to drop bundle sources live +--- openjdk.orig/jaxws/build.properties 2011-05-23 23:27:25.858844463 +0100 ++++ openjdk/jaxws/build.properties 2011-05-23 23:28:12.143588051 +0100 +@@ -78,7 +78,7 @@ patches.dir=patches -+# Patches to apply -+jaxws_src.patch.list=xjc.patch -+ + # Patches to apply +-jaxws_src.patch.list=7013971.patch ++jaxws_src.patch.list=7013971.patch xjc.patch + # Sanity information sanity.info= Sanity Settings:${line.separator}\ - ant.home=${ant.home}${line.separator}\ diff -Nru openjdk.orig/jaxws/patches/jaxws_src/xjc.patch openjdk/jaxws/patches/jaxws_src/xjc.patch --- openjdk.orig/jaxws/patches/jaxws_src/xjc.patch 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/jaxws/patches/jaxws_src/xjc.patch 2009-12-04 16:40:10.000000000 +0000 ++++ openjdk/jaxws/patches/jaxws_src/xjc.patch 2011-05-23 23:28:02.719436649 +0100 @@ -0,0 +1,17 @@ +--- src/com/sun/tools/internal/xjc/reader/xmlschema/parser/SchemaConstraintChecker.java.prev 2008-10-21 15:50:20.000000000 +0100 ++++ src/com/sun/tools/internal/xjc/reader/xmlschema/parser/SchemaConstraintChecker.java 2008-10-21 15:57:37.000000000 +0100
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/ContextEvent.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/ContextEvent.java Wed Jul 06 17:11:34 2011 +0100 @@ -37,32 +37,68 @@ package org.classpath.icedtea.pulseaudio; +import java.util.Arrays; + /** * This class encapsulates a change in the PulseAudio's connection context. * * When this event is fired, something has happened to the connection of this * program to the PulseAudio server. - * */ +class ContextEvent { + // There are certain enumerations from pulse audio that we need to use in + // the java side. For all of these, we declare static longs in the proper + // java classes and we use static native methods to initialize them to + // the values used by pulse audio. This makes us immune to changes in + // the integer values of the enum symbols in pulse audio. + /** + * Basically, what is the new state of the context + * These will be initialized to the proper values in the JNI. + */ + static long UNCONNECTED = -1, + CONNECTING = -1, + AUTHORIZING = -1, + SETTING_NAME = -1, + READY = -1, + FAILED = -1, + TERMINATED = -1; -class ContextEvent { + private static native void init_constants(); + + static { + SecurityWrapper.loadNativeLibrary(); + init_constants(); + } - /** - * Basically, what is the new state of the context - * - */ - public static enum Type { - UNCONNECTED, CONNECTING, AUTHORIZING, SETTING_NAME, READY, FAILED, TERMINATED - } - - private Type type; + /** + * Throws an IllegalStateException if value is not one of the above + * context events. We do this for all pulse audio enumerations that + * we need to use in the java side. If pulse audio decides to add + * new events/states, we need to add them to the classes. The exception + * will let us know. + * return the input if there is no error + * + * @param value is the context event to be checked against one of the known + * events. + * @return value if it is a known event. Otherwise throw an exception. + */ + public static long checkNativeEnumReturn(long value) { + if (!Arrays.asList( + UNCONNECTED, CONNECTING, AUTHORIZING, SETTING_NAME, + READY, FAILED, TERMINATED + ).contains(value)) { + throw new IllegalStateException("Illegal constant for ContextEvent: " + value); + } + return value; + } - public ContextEvent(Type type) { - this.type = type; - } + private long type; - public Type getType() { - return type; - } + public ContextEvent(long type) { + this.type = checkNativeEnumReturn(type); + } + public long getType() { + return type; + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/ContextListener.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/ContextListener.java Wed Jul 06 17:11:34 2011 +0100 @@ -45,6 +45,6 @@ interface ContextListener { - void update(ContextEvent e); + void update(ContextEvent e); }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Debug.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Debug.java Wed Jul 06 17:11:34 2011 +0100 @@ -49,66 +49,66 @@ class Debug { - enum DebugLevel { - Verbose, Debug, Info, Warning, Error, None - } + enum DebugLevel { + Verbose, Debug, Info, Warning, Error, None + } - private static DebugLevel currentDebugLevel = DebugLevel.None; + private static DebugLevel currentDebugLevel = DebugLevel.None; - static { - // System.out.println("PulseAudio: initializing Debug"); + static { + // System.out.println("PulseAudio: initializing Debug"); - String systemSetting; - try { - systemSetting = System.getProperty("pulseaudio.debugLevel"); - } catch (SecurityException e) { - // sigh, we cant read that property - systemSetting = null; - } + String systemSetting; + try { + systemSetting = System.getProperty("pulseaudio.debugLevel"); + } catch (SecurityException e) { + // sigh, we cant read that property + systemSetting = null; + } - DebugLevel wantedLevel; - try { - wantedLevel = DebugLevel.valueOf(systemSetting); + DebugLevel wantedLevel; + try { + wantedLevel = DebugLevel.valueOf(systemSetting); - } catch (IllegalArgumentException e) { - wantedLevel = DebugLevel.Info; - } catch (NullPointerException e) { - wantedLevel = DebugLevel.None; - } + } catch (IllegalArgumentException e) { + wantedLevel = DebugLevel.Info; + } catch (NullPointerException e) { + wantedLevel = DebugLevel.None; + } - currentDebugLevel = wantedLevel; - println(DebugLevel.Info, "Using debug level: " + currentDebugLevel); - } + currentDebugLevel = wantedLevel; + println(DebugLevel.Info, "Using debug level: " + currentDebugLevel); + } - static void println(String string) { - println(DebugLevel.Info, string); - } + static void println(String string) { + println(DebugLevel.Info, string); + } - static void print(DebugLevel level, String string) { - int result = level.compareTo(currentDebugLevel); - if (result >= 0) { - if (level.compareTo(DebugLevel.Error) >= 0) { - System.err.print(string); - } else { - System.out.print(string); - } - } else { - // do nothing - } - } + static void print(DebugLevel level, String string) { + int result = level.compareTo(currentDebugLevel); + if (result >= 0) { + if (level.compareTo(DebugLevel.Error) >= 0) { + System.err.print(string); + } else { + System.out.print(string); + } + } else { + // do nothing + } + } - static void println(DebugLevel level, String string) { + static void println(DebugLevel level, String string) { - int result = level.compareTo(currentDebugLevel); - if (result >= 0) { - if (level.compareTo(DebugLevel.Error) >= 0) { - System.err.println("DEBUG: pulse-java: " + string); - } else { - System.out.println("DEBUG: pulse-java: " + string); - } - } else { - // do nothing - } - } + int result = level.compareTo(currentDebugLevel); + if (result >= 0) { + if (level.compareTo(DebugLevel.Error) >= 0) { + System.err.println("DEBUG: pulse-java: " + string); + } else { + System.out.println("DEBUG: pulse-java: " + string); + } + } else { + // do nothing + } + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/EventLoop.java Wed Jul 06 17:11:34 2011 +0100 @@ -40,243 +40,207 @@ import java.util.ArrayList; import java.util.List; -import org.classpath.icedtea.pulseaudio.ContextEvent.Type; +import org.classpath.icedtea.pulseaudio.ContextEvent; import org.classpath.icedtea.pulseaudio.Debug.DebugLevel; /** * This class wraps pulseaudio's event loop. It also holds the lock used in the * rest of pulse-java - * - * */ final class EventLoop implements Runnable { - /* - * any methods that can obstruct the behaviour of pa_mainloop should run - * synchronized - */ - - /* - * the threadLock object is the object used for synchronizing the - * non-thread-safe operations of pulseaudio's c api - */ - final Object threadLock = new Object(); + /* + * any methods that can obstruct the behaviour of pa_mainloop should run + * synchronized + */ - private static EventLoop instance = null; + /* + * the threadLock object is the object used for synchronizing the + * non-thread-safe operations of pulseaudio's c api + */ + final Object threadLock = new Object(); + + private static EventLoop instance = null; - private List<ContextListener> contextListeners; - // private List<SourceDataLine> lines; - private String appName; - private String serverString; + private List<ContextListener> contextListeners; + // private List<SourceDataLine> lines; + private String appName; + private String serverString; - private int status; - // private boolean eventLoopIsRunning = false; - - private List<String> targetPortNameList = new ArrayList<String>(); - private List<String> sourcePortNameList = new ArrayList<String>(); + private long status; + // private boolean eventLoopIsRunning = false; - /* - * JNI stuff - * - * Do not synchronize the individual functions, synchronize - * block/method/lines around the call - */ + private List<String> targetPortNameList = new ArrayList<String>(); + private List<String> sourcePortNameList = new ArrayList<String>(); - private native void native_setup(String appName, String server); + /* + * JNI stuff + * + * Do not synchronize the individual functions, synchronize + * block/method/lines around the call + */ - private native int native_iterate(int timeout); - - private native void native_shutdown(); + private native void native_setup(String appName, String server); - private native void native_set_sink_volume(byte[] streamPointer, int volume); + private native int native_iterate(int timeout); - /* - * These fields hold pointers - */ - private byte[] contextPointer; - private byte[] mainloopPointer; + private native void native_shutdown(); - /* - * - */ + /* + * These fields hold pointers + */ + private byte[] contextPointer; + private byte[] mainloopPointer; - static { - SecurityWrapper.loadNativeLibrary(); - } + static { + SecurityWrapper.loadNativeLibrary(); + } - private EventLoop() { - contextListeners = new ArrayList<ContextListener>(); - } + private EventLoop() { + contextListeners = new ArrayList<ContextListener>(); + } - synchronized static EventLoop getEventLoop() { - if (instance == null) { - instance = new EventLoop(); - } - return instance; - } + synchronized static EventLoop getEventLoop() { + if (instance == null) { + instance = new EventLoop(); + } + return instance; + } - void setAppName(String appName) { - this.appName = appName; - } + void setAppName(String appName) { + this.appName = appName; + } - void setServer(String serverString) { - this.serverString = serverString; - } + void setServer(String serverString) { + this.serverString = serverString; + } - @Override - public void run() { - native_setup(this.appName, this.serverString); - - Debug.println(DebugLevel.Info, "Eventloop.run(): eventloop starting"); + @Override + public void run() { + native_setup(this.appName, this.serverString); - /* - * Perhaps this loop should be written in C doing a Java to C call on - * every iteration of the loop might be slow - */ - while (true) { - synchronized (threadLock) { - // timeout is in milliseconds - // timout = 0 means dont block - native_iterate(100); + Debug.println(DebugLevel.Info, "Eventloop.run(): eventloop starting"); - if (Thread.interrupted()) { - native_shutdown(); + /* + * Perhaps this loop should be written in C doing a Java to C call on + * every iteration of the loop might be slow + */ + while (true) { + synchronized (threadLock) { + // timeout is in milliseconds + // timout = 0 means dont block + native_iterate(100); - // clean up the listeners - synchronized (contextListeners) { - contextListeners.clear(); - } - - Debug.println(DebugLevel.Info, - "EventLoop.run(): event loop terminated"); - - return; + if (Thread.interrupted()) { + native_shutdown(); - } - } - } - - } + // clean up the listeners + synchronized (contextListeners) { + contextListeners.clear(); + } - void addContextListener(ContextListener contextListener) { - synchronized (contextListeners) { - contextListeners.add(contextListener); - } - } + Debug.println(DebugLevel.Info, + "EventLoop.run(): event loop terminated"); + + return; - void removeContextListener(ContextListener contextListener) { - synchronized (contextListeners) { - contextListeners.remove(contextListener); - } - } + } + } + } + + } - int getStatus() { - return this.status; - } + void addContextListener(ContextListener contextListener) { + synchronized (contextListeners) { + contextListeners.add(contextListener); + } + } + + void removeContextListener(ContextListener contextListener) { + synchronized (contextListeners) { + contextListeners.remove(contextListener); + } + } + + long getStatus() { + return this.status; + } - void update(int status) { - synchronized (threadLock) { - // System.out.println(this.getClass().getName() - // + ".update() called! status = " + status); - this.status = status; - switch (status) { - case 0: - fireEvent(new ContextEvent(Type.UNCONNECTED)); - break; - case 1: - fireEvent(new ContextEvent(Type.CONNECTING)); - break; - case 2: - // no op - break; - case 3: - // no op - break; - case 4: - fireEvent(new ContextEvent(Type.READY)); - break; - case 5: - fireEvent(new ContextEvent(Type.FAILED)); - Debug.println(DebugLevel.Warning, - "EventLoop.update(): Context failed"); - break; - case 6: - fireEvent(new ContextEvent(Type.TERMINATED)); - break; - default: + void update(long status) { + synchronized (threadLock) { + // System.out.println(this.getClass().getName() + // + ".update() called! status = " + status); + this.status = status; + fireEvent(new ContextEvent(status)); + } - } - } - } - - private void fireEvent(final ContextEvent e) { - // System.out.println(this.getClass().getName() + "firing event: " - // + e.getType().toString()); + if (status == ContextEvent.FAILED) { + Debug.println(DebugLevel.Warning, + "EventLoop.update(): Context failed"); + } + } - synchronized (contextListeners) { - // System.out.println(contextListeners.size()); - for (ContextListener listener : contextListeners) { - listener.update(e); - } - } + private void fireEvent(final ContextEvent e) { + // System.out.println(this.getClass().getName() + "firing event: " + // + e.getType().toString()); - } + synchronized (contextListeners) { + // System.out.println(contextListeners.size()); + for (ContextListener listener : contextListeners) { + listener.update(e); + } + } + + } - void setVolume(byte[] streamPointer, int volume) { - synchronized (threadLock) { - native_set_sink_volume(streamPointer, volume); - } - } + byte[] getContextPointer() { + return contextPointer; + } - byte[] getContextPointer() { - return contextPointer; - } + byte[] getMainLoopPointer() { + return mainloopPointer; + } - byte[] getMainLoopPointer() { - return mainloopPointer; - } + private native byte[] nativeUpdateTargetPortNameList(); - private native byte[] nativeUpdateTargetPortNameList(); - - private native byte[] nativeUpdateSourcePortNameList(); + private native byte[] nativeUpdateSourcePortNameList(); - synchronized List<String> updateTargetPortNameList() { - targetPortNameList = new ArrayList<String>(); - Operation op; - synchronized (this.threadLock) { - op = new Operation(nativeUpdateTargetPortNameList()); - } + synchronized List<String> updateTargetPortNameList() { + targetPortNameList = new ArrayList<String>(); + Operation op; + synchronized (this.threadLock) { + op = new Operation(nativeUpdateTargetPortNameList()); + } - op.waitForCompletion(); + op.waitForCompletion(); - assert (op.getState() == Operation.State.Done); + assert (op.getState() == Operation.DONE); - op.releaseReference(); - return targetPortNameList; - } + op.releaseReference(); + return targetPortNameList; + } - protected synchronized List<String> updateSourcePortNameList() { - sourcePortNameList = new ArrayList<String>(); - Operation op; - synchronized (this.threadLock) { - op = new Operation(nativeUpdateSourcePortNameList()); - } + protected synchronized List<String> updateSourcePortNameList() { + sourcePortNameList = new ArrayList<String>(); + Operation op; + synchronized (this.threadLock) { + op = new Operation(nativeUpdateSourcePortNameList()); + } - op.waitForCompletion(); + op.waitForCompletion(); - assert (op.getState() == Operation.State.Done); + assert (op.getState() == Operation.DONE); - op.releaseReference(); - return sourcePortNameList; - } + op.releaseReference(); + return sourcePortNameList; + } - public void source_callback(String name) { - sourcePortNameList.add(name); - } + public void source_callback(String name) { + sourcePortNameList.add(name); + } - public void sink_callback(String name) { - targetPortNameList.add(name); - } - + public void sink_callback(String name) { + targetPortNameList.add(name); + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Operation.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Operation.java Wed Jul 06 17:11:34 2011 +0100 @@ -37,6 +37,8 @@ package org.classpath.icedtea.pulseaudio; +import java.util.Arrays; + /** * Encapsulates a pa_operation object * @@ -54,109 +56,111 @@ class Operation { - private byte[] operationPointer; - private EventLoop eventLoop; + private byte[] operationPointer; + private EventLoop eventLoop; - public enum State { - Running, Done, Cancelled, - } + // These should never be written to in java. They will be initialized + // properly in native code. + public static long RUNNING = -1, + DONE = -1, + CANCELLED = -1; - static { - SecurityWrapper.loadNativeLibrary(); - } + private static native void init_constants(); - private native void native_ref(); - - private native void native_unref(); - - private native int native_get_state(); + static { + SecurityWrapper.loadNativeLibrary(); + init_constants(); + } - Operation(byte[] operationPointer) { - assert (operationPointer != null); - this.operationPointer = operationPointer; - this.eventLoop = EventLoop.getEventLoop(); - } + // If value is not one of RUNNING, DONE, CANCELLED, throw an + // IllegalStateException. Otherwise return the input. + private static long checkNativeOperationState(long value) { + if (!Arrays.asList(RUNNING, DONE, CANCELLED).contains(value)) { + throw new IllegalStateException("Unknown operation state: " + value); + } + return value; + } + + private native void native_ref(); - @Override - protected void finalize() throws Throwable { - // might catch operations which havent been released - assert (operationPointer == null); - super.finalize(); - } + private native void native_unref(); + + private native long native_get_state(); + + Operation(byte[] operationPointer) { + assert (operationPointer != null); + this.operationPointer = operationPointer; + this.eventLoop = EventLoop.getEventLoop(); + } - /** - * Increase reference count by 1 - */ - void addReference() { - assert (operationPointer != null); - synchronized (eventLoop.threadLock) { - native_ref(); - } - } + @Override + protected void finalize() throws Throwable { + // might catch operations which havent been released + assert (operationPointer == null); + super.finalize(); + } - /** - * Decrease reference count by 1. If the count reaches 0, object will be freed - */ - void releaseReference() { - assert (operationPointer != null); - synchronized (eventLoop.threadLock) { - native_unref(); - } - operationPointer = null; - } + /** + * Increase reference count by 1 + */ + void addReference() { + assert (operationPointer != null); + synchronized (eventLoop.threadLock) { + native_ref(); + } + } - // FIXME broken function - boolean isNull() { - if (operationPointer == null) { - return true; - } - return false; - } + /** + * Decrease reference count by 1. If the count reaches 0, object will be freed + */ + void releaseReference() { + assert (operationPointer != null); + synchronized (eventLoop.threadLock) { + native_unref(); + } + operationPointer = null; + } - State getState() { - assert (operationPointer != null); - int state; - synchronized (eventLoop.threadLock) { - state = native_get_state(); - } - switch (state) { - case 0: - return State.Running; - case 1: - return State.Done; - case 2: - return State.Cancelled; - default: - throw new IllegalStateException("Invalid operation State"); - } + // FIXME broken function + boolean isNull() { + if (operationPointer == null) { + return true; + } + return false; + } - } + long getState() { + assert (operationPointer != null); + synchronized (eventLoop.threadLock) { + return checkNativeOperationState(native_get_state()); + } + } - /** - * Block until the operation has completed - * - */ - void waitForCompletion() { - assert (operationPointer != null); + /** + * Block until the operation has completed + * + */ + void waitForCompletion() { + assert (operationPointer != null); - boolean interrupted = false; - do { - synchronized (eventLoop.threadLock) { - if (getState() == Operation.State.Done) { - return; - } - try { - eventLoop.threadLock.wait(); - } catch (InterruptedException e) { - // ingore the interrupt for now - interrupted = true; - } - } - } while (getState() != State.Done); + boolean interrupted = false; + do { + synchronized (eventLoop.threadLock) { + if (getState() == DONE) { + return; + } + try { + eventLoop.threadLock.wait(); + } catch (InterruptedException e) { + // ingore the interrupt for now + interrupted = true; + } + } + } while (getState() != DONE); - // let the caller know about the interrupt - if (interrupted) { - Thread.currentThread().interrupt(); - } - } + // let the caller know about the interrupt + if (interrupted) { + Thread.currentThread().interrupt(); + } + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java Wed Jul 06 17:11:34 2011 +0100 @@ -51,524 +51,524 @@ import org.classpath.icedtea.pulseaudio.Stream.WriteListener; public final class PulseAudioClip extends PulseAudioDataLine implements Clip, - PulseAudioPlaybackLine { + PulseAudioPlaybackLine { - private byte[] data = null; + private byte[] data = null; - // these are frame indices. so counted from 0 - // the current frame index - private int currentFrame = 0; + // these are frame indices. so counted from 0 + // the current frame index + private int currentFrame = 0; - // total number of frames in this clip - private int frameCount = 0; + // total number of frames in this clip + private int frameCount = 0; - // the starting frame of the loop - private int startFrame = 0; - // the ending frame of the loop - private int endFrame = 0; + // the starting frame of the loop + private int startFrame = 0; + // the ending frame of the loop + private int endFrame = 0; - public static final String DEFAULT_CLIP_NAME = "Audio Clip"; + public static final String DEFAULT_CLIP_NAME = "Audio Clip"; - private Object clipLock = new Object(); - private int loopsLeft = 0; + private Object clipLock = new Object(); + private int loopsLeft = 0; - // private Semaphore clipSemaphore = new Semaphore(1); + // private Semaphore clipSemaphore = new Semaphore(1); - /** - * This thread runs - * - */ - private final class ClipThread extends Thread { - @Override - public void run() { + /** + * This thread runs + * + */ + private final class ClipThread extends Thread { + @Override + public void run() { - /* - * The while loop below only works with LOOP_CONTINUOUSLY because we - * abuse the fact that loopsLeft's initial value is -1 - * (=LOOP_CONTINUOUSLY) and it keeps on going lower without hitting - * 0. So do a sanity check - */ - if (Clip.LOOP_CONTINUOUSLY != -1) { - throw new UnsupportedOperationException( - "LOOP_CONTINUOUSLY has changed; things are going to break"); - } + /* + * The while loop below only works with LOOP_CONTINUOUSLY because we + * abuse the fact that loopsLeft's initial value is -1 + * (=LOOP_CONTINUOUSLY) and it keeps on going lower without hitting + * 0. So do a sanity check + */ + if (Clip.LOOP_CONTINUOUSLY != -1) { + throw new UnsupportedOperationException( + "LOOP_CONTINUOUSLY has changed; things are going to break"); + } - while (true) { - writeFrames(currentFrame, endFrame + 1); - if (Thread.interrupted()) { - // Thread.currentThread().interrupt(); - // System.out.println("returned from interrupted - // writeFrames"); - break; - } + while (true) { + writeFrames(currentFrame, endFrame + 1); + if (Thread.interrupted()) { + // Thread.currentThread().interrupt(); + // System.out.println("returned from interrupted + // writeFrames"); + break; + } - // if loop(0) has been called from the mainThread, - // wait until loopsLeft has been set - if (loopsLeft == 0) { - // System.out.println("Reading to the end of the file"); - // System.out.println("endFrame: " + endFrame); - writeFrames(endFrame, getFrameLength()); - break; - } else { - synchronized (clipLock) { - currentFrame = startFrame; - if (loopsLeft != Integer.MIN_VALUE) { - loopsLeft--; - } - } - } + // if loop(0) has been called from the mainThread, + // wait until loopsLeft has been set + if (loopsLeft == 0) { + // System.out.println("Reading to the end of the file"); + // System.out.println("endFrame: " + endFrame); + writeFrames(endFrame, getFrameLength()); + break; + } else { + synchronized (clipLock) { + currentFrame = startFrame; + if (loopsLeft != Integer.MIN_VALUE) { + loopsLeft--; + } + } + } - } + } - // drain - Operation operation; + // drain + Operation operation; - synchronized (eventLoop.threadLock) { - operation = stream.drain(); - } + synchronized (eventLoop.threadLock) { + operation = stream.drain(); + } - operation.waitForCompletion(); - operation.releaseReference(); + operation.waitForCompletion(); + operation.releaseReference(); - } - } + } + } - private ClipThread clipThread; + private ClipThread clipThread; - private void writeFrames(int startingFrame, int lastFrame) { + private void writeFrames(int startingFrame, int lastFrame) { - WriteListener writeListener = new WriteListener() { - @Override - public void update() { - synchronized (eventLoop.threadLock) { - eventLoop.threadLock.notifyAll(); - } - } - }; + WriteListener writeListener = new WriteListener() { + @Override + public void update() { + synchronized (eventLoop.threadLock) { + eventLoop.threadLock.notifyAll(); + } + } + }; - stream.addWriteListener(writeListener); + stream.addWriteListener(writeListener); - Debug.println(DebugLevel.Verbose, - "PulseAudioClip$ClipThread.writeFrames(): Writing"); + Debug.println(DebugLevel.Verbose, + "PulseAudioClip$ClipThread.writeFrames(): Writing"); - int remainingFrames = lastFrame - startingFrame - 1; - while (remainingFrames > 0) { - synchronized (eventLoop.threadLock) { - int availableSize; + int remainingFrames = lastFrame - startingFrame - 1; + while (remainingFrames > 0) { + synchronized (eventLoop.threadLock) { + int availableSize; - do { - availableSize = stream.getWritableSize(); - if (availableSize < 0) { - Thread.currentThread().interrupt(); - stream.removeWriteListener(writeListener); - return; - } - if (availableSize == 0) { - try { - eventLoop.threadLock.wait(); - } catch (InterruptedException e) { - // System.out - // .println("interrupted while waiting for - // getWritableSize"); - // clean up and return - Thread.currentThread().interrupt(); - stream.removeWriteListener(writeListener); - return; - } - } + do { + availableSize = stream.getWritableSize(); + if (availableSize < 0) { + Thread.currentThread().interrupt(); + stream.removeWriteListener(writeListener); + return; + } + if (availableSize == 0) { + try { + eventLoop.threadLock.wait(); + } catch (InterruptedException e) { + // System.out + // .println("interrupted while waiting for + // getWritableSize"); + // clean up and return + Thread.currentThread().interrupt(); + stream.removeWriteListener(writeListener); + return; + } + } - } while (availableSize == 0); + } while (availableSize == 0); - int framesToWrite = Math.min(remainingFrames, availableSize - / getFormat().getFrameSize()); - stream.write(data, currentFrame * getFormat().getFrameSize(), - framesToWrite * getFormat().getFrameSize()); - remainingFrames -= framesToWrite; - currentFrame += framesToWrite; - framesSinceOpen += framesToWrite; - if (Thread.interrupted()) { - Thread.currentThread().interrupt(); - break; - } - // System.out.println("remaining frames" + remainingFrames); - // System.out.println("currentFrame: " + currentFrame); - // System.out.println("framesSinceOpen: " + framesSinceOpen); - } - } + int framesToWrite = Math.min(remainingFrames, availableSize + / getFormat().getFrameSize()); + stream.write(data, currentFrame * getFormat().getFrameSize(), + framesToWrite * getFormat().getFrameSize()); + remainingFrames -= framesToWrite; + currentFrame += framesToWrite; + framesSinceOpen += framesToWrite; + if (Thread.interrupted()) { + Thread.currentThread().interrupt(); + break; + } + // System.out.println("remaining frames" + remainingFrames); + // System.out.println("currentFrame: " + currentFrame); + // System.out.println("framesSinceOpen: " + framesSinceOpen); + } + } - stream.removeWriteListener(writeListener); - } + stream.removeWriteListener(writeListener); + } - PulseAudioClip(AudioFormat[] formats, AudioFormat defaultFormat) { - this.supportedFormats = formats; - this.defaultFormat = defaultFormat; - this.currentFormat = defaultFormat; - this.streamName = DEFAULT_CLIP_NAME; + PulseAudioClip(AudioFormat[] formats, AudioFormat defaultFormat) { + this.supportedFormats = formats; + this.defaultFormat = defaultFormat; + this.currentFormat = defaultFormat; + this.streamName = DEFAULT_CLIP_NAME; - clipThread = new ClipThread(); + clipThread = new ClipThread(); - } + } - @Override - protected void connectLine(int bufferSize, Stream masterStream) - throws LineUnavailableException { - StreamBufferAttributes bufferAttributes = new StreamBufferAttributes( - bufferSize, bufferSize / 4, bufferSize / 8, - ((bufferSize / 10) > 100 ? bufferSize / 10 : 100), 0); + @Override + protected void connectLine(int bufferSize, Stream masterStream) + throws LineUnavailableException { + StreamBufferAttributes bufferAttributes = new StreamBufferAttributes( + bufferSize, bufferSize / 4, bufferSize / 8, + ((bufferSize / 10) > 100 ? bufferSize / 10 : 100), 0); - if (masterStream != null) { - synchronized (eventLoop.threadLock) { - stream.connectForPlayback(Stream.DEFAULT_DEVICE, - bufferAttributes, masterStream.getStreamPointer()); - } - } else { - synchronized (eventLoop.threadLock) { - stream.connectForPlayback(Stream.DEFAULT_DEVICE, - bufferAttributes, null); - } - } - } + if (masterStream != null) { + synchronized (eventLoop.threadLock) { + stream.connectForPlayback(Stream.DEFAULT_DEVICE, + bufferAttributes, masterStream.getStreamPointer()); + } + } else { + synchronized (eventLoop.threadLock) { + stream.connectForPlayback(Stream.DEFAULT_DEVICE, + bufferAttributes, null); + } + } + } - @Override - public int available() { - return 0; // a clip always returns 0 - } + @Override + public int available() { + return 0; // a clip always returns 0 + } - @Override - public void close() { + @Override + public void close() { - if (!isOpen) { - throw new IllegalStateException("line already closed"); - } + if (!isOpen) { + throw new IllegalStateException("line already closed"); + } - clipThread.interrupt(); + clipThread.interrupt(); - try { - clipThread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + try { + clipThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } - currentFrame = 0; - framesSinceOpen = 0; + currentFrame = 0; + framesSinceOpen = 0; - PulseAudioMixer mixer = PulseAudioMixer.getInstance(); - mixer.removeSourceLine(this); + PulseAudioMixer mixer = PulseAudioMixer.getInstance(); + mixer.removeSourceLine(this); - super.close(); + super.close(); - Debug.println(DebugLevel.Verbose, "PulseAudioClip.close(): " - + "Clip closed"); + Debug.println(DebugLevel.Verbose, "PulseAudioClip.close(): " + + "Clip closed"); - } + } - /* - * - * drain() on a Clip should block until the entire clip has finished playing - * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4732218 - */ - @Override - public void drain() { - if (!isOpen) { - throw new IllegalStateException("line not open"); - } + /* + * + * drain() on a Clip should block until the entire clip has finished playing + * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4732218 + */ + @Override + public void drain() { + if (!isOpen) { + throw new IllegalStateException("line not open"); + } - while (clipThread != null && clipThread.isAlive()) { - try { - clipThread.join(); - } catch (InterruptedException e) { - // ignore - } - } + while (clipThread != null && clipThread.isAlive()) { + try { + clipThread.join(); + } catch (InterruptedException e) { + // ignore + } + } - Operation operation; + Operation operation; - synchronized (eventLoop.threadLock) { - operation = stream.drain(); - } + synchronized (eventLoop.threadLock) { + operation = stream.drain(); + } - operation.waitForCompletion(); - operation.releaseReference(); + operation.waitForCompletion(); + operation.releaseReference(); - } + } - @Override - public void flush() { - if (!isOpen) { - throw new IllegalStateException("line not open"); - } + @Override + public void flush() { + if (!isOpen) { + throw new IllegalStateException("line not open"); + } - Operation operation; - synchronized (eventLoop.threadLock) { - operation = stream.flush(); - operation.waitForCompletion(); - } - operation.releaseReference(); + Operation operation; + synchronized (eventLoop.threadLock) { + operation = stream.flush(); + operation.waitForCompletion(); + } + operation.releaseReference(); - } + } - @Override - public int getFrameLength() { - if (!isOpen) { - return AudioSystem.NOT_SPECIFIED; - } + @Override + public int getFrameLength() { + if (!isOpen) { + return AudioSystem.NOT_SPECIFIED; + } - return frameCount; - } + return frameCount; + } - @Override - public int getFramePosition() { - if (!isOpen) { - throw new IllegalStateException("Line not open"); - } - synchronized (clipLock) { - return (int) framesSinceOpen; - } - } + @Override + public int getFramePosition() { + if (!isOpen) { + throw new IllegalStateException("Line not open"); + } + synchronized (clipLock) { + return (int) framesSinceOpen; + } + } - @Override - public long getLongFramePosition() { - if (!isOpen) { - throw new IllegalStateException("Line not open"); - } + @Override + public long getLongFramePosition() { + if (!isOpen) { + throw new IllegalStateException("Line not open"); + } - synchronized (clipLock) { - return framesSinceOpen; - } - } + synchronized (clipLock) { + return framesSinceOpen; + } + } - @Override - public long getMicrosecondLength() { - if (!isOpen) { - return AudioSystem.NOT_SPECIFIED; - } - synchronized (clipLock) { - return (long) (frameCount / currentFormat.getFrameRate() * 1000); - } - } + @Override + public long getMicrosecondLength() { + if (!isOpen) { + return AudioSystem.NOT_SPECIFIED; + } + synchronized (clipLock) { + return (long) (frameCount / currentFormat.getFrameRate() * 1000); + } + } - @Override - public long getMicrosecondPosition() { - if (!isOpen) { - throw new IllegalStateException("Line not open"); - } + @Override + public long getMicrosecondPosition() { + if (!isOpen) { + throw new IllegalStateException("Line not open"); + } - synchronized (clipLock) { - return (long) (framesSinceOpen / currentFormat.getFrameRate() * 1000); - } - } + synchronized (clipLock) { + return (long) (framesSinceOpen / currentFormat.getFrameRate() * 1000); + } + } - @Override - public void loop(int count) { - if (!isOpen) { - throw new IllegalStateException("Line not open"); - } + @Override + public void loop(int count) { + if (!isOpen) { + throw new IllegalStateException("Line not open"); + } - if (count < 0 && count != LOOP_CONTINUOUSLY) { - throw new IllegalArgumentException("invalid value for count:" - + count); - } + if (count < 0 && count != LOOP_CONTINUOUSLY) { + throw new IllegalArgumentException("invalid value for count:" + + count); + } - if (clipThread.isAlive() && count != 0) { - // Do nothing; behavior not specified by the Java API - return; - } + if (clipThread.isAlive() && count != 0) { + // Do nothing; behavior not specified by the Java API + return; + } - super.start(); + super.start(); - synchronized (clipLock) { - if (currentFrame > endFrame) { - loopsLeft = 0; - } else { - loopsLeft = count; - } - } - if (!clipThread.isAlive()) { - clipThread = new ClipThread(); - clipThread.start(); - } + synchronized (clipLock) { + if (currentFrame > endFrame) { + loopsLeft = 0; + } else { + loopsLeft = count; + } + } + if (!clipThread.isAlive()) { + clipThread = new ClipThread(); + clipThread.start(); + } - } + } - @Override - public void open() throws LineUnavailableException { - throw new IllegalArgumentException("open() on a Clip is not allowed"); - } + @Override + public void open() throws LineUnavailableException { + throw new IllegalArgumentException("open() on a Clip is not allowed"); + } - @Override - public void open(AudioFormat format, byte[] data, int offset, int bufferSize) - throws LineUnavailableException { + @Override + public void open(AudioFormat format, byte[] data, int offset, int bufferSize) + throws LineUnavailableException { - super.open(format); - this.data = new byte[bufferSize]; - System.arraycopy(data, offset, this.data, 0, bufferSize); + super.open(format); + this.data = new byte[bufferSize]; + System.arraycopy(data, offset, this.data, 0, bufferSize); - frameCount = bufferSize / format.getFrameSize(); - currentFrame = 0; - framesSinceOpen = 0; - startFrame = 0; - endFrame = frameCount - 1; - loopsLeft = 0; + frameCount = bufferSize / format.getFrameSize(); + currentFrame = 0; + framesSinceOpen = 0; + startFrame = 0; + endFrame = frameCount - 1; + loopsLeft = 0; - PulseAudioVolumeControl volumeControl = new PulseAudioVolumeControl( - this, eventLoop); - controls.add(volumeControl); + PulseAudioVolumeControl volumeControl = new PulseAudioVolumeControl( + this, eventLoop); + controls.add(volumeControl); - PulseAudioMixer mixer = PulseAudioMixer.getInstance(); - mixer.addSourceLine(this); + PulseAudioMixer mixer = PulseAudioMixer.getInstance(); + mixer.addSourceLine(this); - isOpen = true; - Debug.println(DebugLevel.Verbose, "PulseAudioClip.open(): Clip opened"); + isOpen = true; + Debug.println(DebugLevel.Verbose, "PulseAudioClip.open(): Clip opened"); - } + } - // FIXME - @Override - public byte[] native_set_volume(float value) { - return stream.native_set_volume(value); - } + // FIXME + @Override + public byte[] native_set_volume(float value) { + return stream.native_set_volume(value); + } - public byte[] native_update_volume() { - return stream.native_update_volume(); - } + public byte[] native_update_volume() { + return stream.native_update_volume(); + } - @Override - public float getCachedVolume() { - return stream.getCachedVolume(); - } + @Override + public float getCachedVolume() { + return stream.getCachedVolume(); + } - @Override - public void setCachedVolume(float value) { - stream.setCachedVolume(value); + @Override + public void setCachedVolume(float value) { + stream.setCachedVolume(value); - } + } - @Override - public void open(AudioInputStream stream) throws LineUnavailableException, - IOException { - byte[] buffer = new byte[(int) (stream.getFrameLength() * stream - .getFormat().getFrameSize())]; - stream.read(buffer, 0, buffer.length); + @Override + public void open(AudioInputStream stream) throws LineUnavailableException, + IOException { + byte[] buffer = new byte[(int) (stream.getFrameLength() * stream + .getFormat().getFrameSize())]; + stream.read(buffer, 0, buffer.length); - open(stream.getFormat(), buffer, 0, buffer.length); + open(stream.getFormat(), buffer, 0, buffer.length); - } + } - @Override - public void setFramePosition(int frames) { - if (!isOpen) { - throw new IllegalStateException("Line not open"); - } + @Override + public void setFramePosition(int frames) { + if (!isOpen) { + throw new IllegalStateException("Line not open"); + } - if (frames < 0 || frames > frameCount) { - throw new IllegalArgumentException("incorreft frame value"); - } + if (frames < 0 || frames > frameCount) { + throw new IllegalArgumentException("incorreft frame value"); + } - synchronized (clipLock) { - currentFrame = frames; - } + synchronized (clipLock) { + currentFrame = frames; + } - } + } - @Override - public void setLoopPoints(int start, int end) { - if (!isOpen) { - throw new IllegalStateException("Line not open"); - } + @Override + public void setLoopPoints(int start, int end) { + if (!isOpen) { + throw new IllegalStateException("Line not open"); + } - if (end == -1) { - end = frameCount - 1; - } + if (end == -1) { + end = frameCount - 1; + } - if (end < start) { - throw new IllegalArgumentException( - "ending point must be greater than or equal to the starting point"); - } + if (end < start) { + throw new IllegalArgumentException( + "ending point must be greater than or equal to the starting point"); + } - if (start < 0) { - throw new IllegalArgumentException( - "starting point must be greater than or equal to 0"); - } + if (start < 0) { + throw new IllegalArgumentException( + "starting point must be greater than or equal to 0"); + } - synchronized (clipLock) { - startFrame = start; - endFrame = end; - } + synchronized (clipLock) { + startFrame = start; + endFrame = end; + } - } + } - @Override - public void setMicrosecondPosition(long microseconds) { - if (!isOpen) { - throw new IllegalStateException("Line not open"); - } + @Override + public void setMicrosecondPosition(long microseconds) { + if (!isOpen) { + throw new IllegalStateException("Line not open"); + } - float frameIndex = microseconds * currentFormat.getFrameRate() / 1000; + float frameIndex = microseconds * currentFormat.getFrameRate() / 1000; - /* make frameIndex positive */ - while (frameIndex < 0) { - frameIndex += frameCount; - } + /* make frameIndex positive */ + while (frameIndex < 0) { + frameIndex += frameCount; + } - /* frameIndex is in the range [0, frameCount-1], inclusive */ - frameIndex = frameIndex % frameCount; + /* frameIndex is in the range [0, frameCount-1], inclusive */ + frameIndex = frameIndex % frameCount; - synchronized (clipLock) { - currentFrame = (int) frameIndex; - } + synchronized (clipLock) { + currentFrame = (int) frameIndex; + } - } + } - @Override - public void start() { - if (isStarted) { - return; - } + @Override + public void start() { + if (isStarted) { + return; + } - super.start(); + super.start(); - if (!clipThread.isAlive()) { - synchronized (clipLock) { - loopsLeft = 0; - } - clipThread = new ClipThread(); - clipThread.start(); - } + if (!clipThread.isAlive()) { + synchronized (clipLock) { + loopsLeft = 0; + } + clipThread = new ClipThread(); + clipThread.start(); + } - } + } - @Override - public void stop() { - if (!isOpen) { - throw new IllegalStateException("Line not open"); - } + @Override + public void stop() { + if (!isOpen) { + throw new IllegalStateException("Line not open"); + } - /* do what start does and ignore if called at the wrong time */ - if (!isStarted) { - return; - } + /* do what start does and ignore if called at the wrong time */ + if (!isStarted) { + return; + } - if (clipThread.isAlive()) { - clipThread.interrupt(); - } - try { - clipThread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - synchronized (clipLock) { - loopsLeft = 0; - } + if (clipThread.isAlive()) { + clipThread.interrupt(); + } + try { + clipThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + synchronized (clipLock) { + loopsLeft = 0; + } - super.stop(); + super.stop(); - } + } - @Override - public Line.Info getLineInfo() { - return new DataLine.Info(Clip.class, supportedFormats, - StreamBufferAttributes.MIN_VALUE, - StreamBufferAttributes.MAX_VALUE); - } + @Override + public Line.Info getLineInfo() { + return new DataLine.Info(Clip.class, supportedFormats, + StreamBufferAttributes.MIN_VALUE, + StreamBufferAttributes.MAX_VALUE); + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java Wed Jul 06 17:11:34 2011 +0100 @@ -55,450 +55,444 @@ */ abstract class PulseAudioDataLine extends PulseAudioLine implements DataLine { - protected static final int DEFAULT_BUFFER_SIZE = StreamBufferAttributes.SANE_DEFAULT; + protected static final int DEFAULT_BUFFER_SIZE = StreamBufferAttributes.SANE_DEFAULT; - // override this to set the stream name - protected String streamName; + // override this to set the stream name + protected String streamName; - // true between start() and stop() - protected boolean isStarted = false; + // true between start() and stop() + protected boolean isStarted = false; - // true between a started and an underflow callback - protected boolean dataWritten = false; + // true between a started and an underflow callback + protected boolean dataWritten = false; - // true if a stream has been paused - // protected boolean isPaused = false; + // true if a stream has been paused + // protected boolean isPaused = false; - protected AudioFormat[] supportedFormats = null; - protected AudioFormat currentFormat = null; - protected AudioFormat defaultFormat = null; - protected boolean sendEvents = true; + protected AudioFormat[] supportedFormats = null; + protected AudioFormat currentFormat = null; + protected AudioFormat defaultFormat = null; + protected boolean sendEvents = true; - protected int bufferSize = 0; - // the total number of frames played since this line was opened - protected long framesSinceOpen = 0; + // the total number of frames played since this line was opened + protected long framesSinceOpen = 0; - protected EventLoop eventLoop = null; - protected Semaphore semaphore = new Semaphore(0); - protected Stream stream; - boolean writeInterrupted = false; + protected EventLoop eventLoop = null; + protected Semaphore semaphore = new Semaphore(0); + protected Stream stream; + boolean writeInterrupted = false; - protected void open(AudioFormat format, int bufferSize) - throws LineUnavailableException { + protected void open(AudioFormat format, int bufferSize) + throws LineUnavailableException { - if (isOpen()) { - throw new IllegalStateException("Line is already open"); - } + if (isOpen()) { + throw new IllegalStateException("Line is already open"); + } - PulseAudioMixer mixer = PulseAudioMixer.getInstance(); - if (!mixer.isOpen()) { - mixer.open(); - } + PulseAudioMixer mixer = PulseAudioMixer.getInstance(); + if (!mixer.isOpen()) { + mixer.open(); + } - eventLoop = EventLoop.getEventLoop(); + eventLoop = EventLoop.getEventLoop(); - createStream(format); - addStreamListeners(); - connect(null, bufferSize); - } + createStream(format); + addStreamListeners(); + connect(null, bufferSize); + } - private void createStream(AudioFormat format) - throws LineUnavailableException { + private void createStream(AudioFormat format) + throws LineUnavailableException { - for (AudioFormat myFormat : supportedFormats) { - if (format.matches(myFormat)) { - /* - * A few issues with format: - * - * To match: SAME encoding: safe because its a java enum. SAME - * number of channels: safe because myFormat has specific - * values. SAME bits per sample (aka sampleSize) and bytes per - * frame (aka frameSize): safe because myFormat has specific - * values. SAME sample rate: _not_ safe because myFormat uses - * AudioSystem.NOT_SPECIFIED. SAME frame rate: safe because we - * _ignore_ it completely ;) - */ + for (AudioFormat myFormat : supportedFormats) { + if (format.matches(myFormat)) { + /* + * A few issues with format: + * + * To match: SAME encoding: safe because its a java enum. SAME + * number of channels: safe because myFormat has specific + * values. SAME bits per sample (aka sampleSize) and bytes per + * frame (aka frameSize): safe because myFormat has specific + * values. SAME sample rate: _not_ safe because myFormat uses + * AudioSystem.NOT_SPECIFIED. SAME frame rate: safe because we + * _ignore_ it completely ;) + */ - float sampleRate = format.getSampleRate(); - if (sampleRate == (float) AudioSystem.NOT_SPECIFIED) { - /* pick a random sample rate */ - sampleRate = 44100.0f; - } + float sampleRate = format.getSampleRate(); + if (sampleRate == (float) AudioSystem.NOT_SPECIFIED) { + /* pick a random sample rate */ + sampleRate = 44100.0f; + } - String formatString = (String) myFormat - .getProperty(PulseAudioMixer.PULSEAUDIO_FORMAT_KEY); - synchronized (eventLoop.threadLock) { + String formatString = (String) myFormat + .getProperty(PulseAudioMixer.PULSEAUDIO_FORMAT_KEY); + synchronized (eventLoop.threadLock) { - stream = new Stream(eventLoop.getContextPointer(), - streamName, Stream.Format.valueOf(formatString), - (int) sampleRate, myFormat.getChannels()); + stream = new Stream(eventLoop.getContextPointer(), + streamName, Stream.Format.valueOf(formatString), + (int) sampleRate, myFormat.getChannels()); - } - currentFormat = format; - isOpen = true; - } - } + } + currentFormat = format; + isOpen = true; + } + } - if (!isOpen()) { - throw new IllegalArgumentException("Invalid format"); - } + if (!isOpen()) { + throw new IllegalArgumentException("Invalid format"); + } - // System.out.println("Stream " + stream + " created"); + // System.out.println("Stream " + stream + " created"); - } + } - /** - * This method adds the listeners used to find out when the stream has - * connected/disconnected etc to the actual stream. - */ - private void addStreamListeners() { - Stream.StateListener openCloseListener = new Stream.StateListener() { + /** + * This method adds the listeners used to find out when the stream has + * connected/disconnected etc to the actual stream. + */ + private void addStreamListeners() { + Stream.StateListener openCloseListener = new Stream.StateListener() { - @Override - public void update() { - synchronized (eventLoop.threadLock) { + @Override + public void update() { + synchronized (eventLoop.threadLock) { - /* - * Note the order: first we notify all the listeners, and - * then return. this means no race conditions when the - * listeners are removed before they get called by close - * - * eg: - * - * line.close(); line.removeLineListener(listener) - * - * the listener is guaranteed to have run - */ + /* + * Note the order: first we notify all the listeners, and + * then return. this means no race conditions when the + * listeners are removed before they get called by close + * + * eg: + * + * line.close(); line.removeLineListener(listener) + * + * the listener is guaranteed to have run + */ - if (stream.getState() == Stream.State.READY) { - if (sendEvents) { - fireLineEvent(new LineEvent( - PulseAudioDataLine.this, - LineEvent.Type.OPEN, framesSinceOpen)); - } - semaphore.release(); + if (stream.getState() == Stream.STATE_READY) { + if (sendEvents) { + fireLineEvent(new LineEvent( + PulseAudioDataLine.this, + LineEvent.Type.OPEN, framesSinceOpen)); + } + semaphore.release(); - } else if (stream.getState() == Stream.State.TERMINATED - || stream.getState() == Stream.State.FAILED) { - if (sendEvents) { - fireLineEvent((new LineEvent( - PulseAudioDataLine.this, - LineEvent.Type.CLOSE, framesSinceOpen))); - } - synchronized (this) { - this.notifyAll(); - } - semaphore.release(); + } else if (stream.getState() == Stream.STATE_TERMINATED + || stream.getState() == Stream.STATE_FAILED) { + if (sendEvents) { + fireLineEvent((new LineEvent( + PulseAudioDataLine.this, + LineEvent.Type.CLOSE, framesSinceOpen))); + } + semaphore.release(); + } + } + } + }; - } - } - } - }; + stream.addStateListener(openCloseListener); - stream.addStateListener(openCloseListener); + Stream.UnderflowListener stoppedListener = new Stream.UnderflowListener() { + @Override + public void update() { + dataWritten = false; - Stream.UnderflowListener stoppedListener = new Stream.UnderflowListener() { - @Override - public void update() { - dataWritten = false; - - // always send a STOP event on an underflow (assumption: - // an underflow can't happen while the stream is corked) - fireLineEvent(new LineEvent(PulseAudioDataLine.this, - LineEvent.Type.STOP, framesSinceOpen)); - } - }; - stream.addUnderflowListener(stoppedListener); + // always send a STOP event on an underflow (assumption: + // an underflow can't happen while the stream is corked) + fireLineEvent(new LineEvent(PulseAudioDataLine.this, + LineEvent.Type.STOP, framesSinceOpen)); + } + }; + stream.addUnderflowListener(stoppedListener); - Stream.PlaybackStartedListener startedListener = new Stream.PlaybackStartedListener() { - @Override - public void update() { - if (!dataWritten) { - fireLineEvent(new LineEvent(PulseAudioDataLine.this, - LineEvent.Type.START, framesSinceOpen)); - synchronized (this) { - this.notifyAll(); - } - } - dataWritten = true; + Stream.PlaybackStartedListener startedListener = new Stream.PlaybackStartedListener() { + @Override + public void update() { + if (!dataWritten) { + fireLineEvent(new LineEvent(PulseAudioDataLine.this, + LineEvent.Type.START, framesSinceOpen)); + synchronized (this) { + PulseAudioDataLine.this.notifyAll(); + } + } + dataWritten = true; - } - }; + } + }; - stream.addPlaybackStartedListener(startedListener); + stream.addPlaybackStartedListener(startedListener); - WriteListener writeNotifier = new WriteListener() { + WriteListener writeNotifier = new WriteListener() { - @Override - public void update() { - synchronized (eventLoop.threadLock) { - eventLoop.threadLock.notifyAll(); - } - } + @Override + public void update() { + synchronized (eventLoop.threadLock) { + eventLoop.threadLock.notifyAll(); + } + } - }; - stream.addWriteListener(writeNotifier); + }; + stream.addWriteListener(writeNotifier); - Stream.CorkListener corkListener = new Stream.CorkListener() { + Stream.CorkListener corkListener = new Stream.CorkListener() { - @Override - public void update() { - synchronized (eventLoop.threadLock) { - eventLoop.threadLock.notifyAll(); - } - } + @Override + public void update() { + synchronized (eventLoop.threadLock) { + eventLoop.threadLock.notifyAll(); + } + } - }; - stream.addCorkListener(corkListener); - } + }; + stream.addCorkListener(corkListener); + } - private void connect(Stream masterStream, int bufferSize) - throws LineUnavailableException { + private void connect(Stream masterStream, int bufferSize) + throws LineUnavailableException { - try { - synchronized (eventLoop.threadLock) { - connectLine(bufferSize, masterStream); - } - } catch (LineUnavailableException e) { - // error connecting to the server! - // stream.removePlaybackStartedListener(startedListener); - // stream.removeUnderflowListener(stoppedListener); - // stream.removeStateListener(openCloseListener); - stream.free(); - stream = null; - throw e; + try { + synchronized (eventLoop.threadLock) { + connectLine(bufferSize, masterStream); + } + } catch (LineUnavailableException e) { + // error connecting to the server! + // stream.removePlaybackStartedListener(startedListener); + // stream.removeUnderflowListener(stoppedListener); + // stream.removeStateListener(openCloseListener); + stream.free(); + stream = null; + throw e; - } - this.bufferSize = bufferSize; - try { - semaphore.acquire(); - synchronized (eventLoop.threadLock) { - if (stream.getState() != Stream.State.READY) { - stream.disconnect(); - stream.free(); - throw new LineUnavailableException( - "unable to obtain a line"); - } - } - } catch (InterruptedException e) { - throw new LineUnavailableException("unable to prepare stream"); - } - } + } + try { + semaphore.acquire(); + synchronized (eventLoop.threadLock) { + if (stream.getState() != Stream.STATE_READY) { + stream.disconnect(); + stream.free(); + throw new LineUnavailableException( + "unable to obtain a line"); + } + } + } catch (InterruptedException e) { + throw new LineUnavailableException("unable to prepare stream"); + } + } - protected void open(AudioFormat format) throws LineUnavailableException { - open(format, DEFAULT_BUFFER_SIZE); + protected void open(AudioFormat format) throws LineUnavailableException { + open(format, DEFAULT_BUFFER_SIZE); - } + } - @Override - public void open() throws LineUnavailableException { - assert (defaultFormat != null); - open(defaultFormat, DEFAULT_BUFFER_SIZE); - } + @Override + public void open() throws LineUnavailableException { + assert (defaultFormat != null); + open(defaultFormat, DEFAULT_BUFFER_SIZE); + } - @Override - public void close() { + @Override + public void close() { - if (!isOpen()) { - // For whatever reason, we are being asked to close - // a line that is not even open. - return; - } + if (!isOpen()) { + // For whatever reason, we are being asked to close + // a line that is not even open. + return; + } - synchronized (eventLoop.threadLock) { - stream.disconnect(); - } + synchronized (eventLoop.threadLock) { + stream.disconnect(); + } - try { - semaphore.acquire(); - } catch (InterruptedException e) { - throw new RuntimeException("unable to prepare stream"); - } + try { + semaphore.acquire(); + } catch (InterruptedException e) { + throw new RuntimeException("unable to prepare stream"); + } - synchronized (eventLoop.threadLock) { - stream.free(); - } + synchronized (eventLoop.threadLock) { + stream.free(); + } - super.close(); + super.close(); - isStarted = false; - } + isStarted = false; + } - void reconnectforSynchronization(Stream masterStream) - throws LineUnavailableException { - sendEvents = false; - drain(); + void reconnectforSynchronization(Stream masterStream) + throws LineUnavailableException { + sendEvents = false; + drain(); - synchronized (eventLoop.threadLock) { - stream.disconnect(); - } - try { - semaphore.acquire(); - } catch (InterruptedException e) { - throw new RuntimeException("unable to prepare stream"); - } + synchronized (eventLoop.threadLock) { + stream.disconnect(); + } + try { + semaphore.acquire(); + } catch (InterruptedException e) { + throw new RuntimeException("unable to prepare stream"); + } - createStream(getFormat()); - addStreamListeners(); - connect(masterStream, getBufferSize()); + createStream(getFormat()); + addStreamListeners(); + connect(masterStream, getBufferSize()); - sendEvents = true; - } + sendEvents = true; + } - @Override - public void start() { - if (!isOpen()) { - throw new IllegalStateException( - "Line must be open()ed before it can be start()ed"); - } + @Override + public void start() { + if (!isOpen()) { + throw new IllegalStateException( + "Line must be open()ed before it can be start()ed"); + } - if (isStarted) { - return; + if (isStarted) { + return; - } - if (dataWritten && (!isStarted)) { - fireLineEvent(new LineEvent(PulseAudioDataLine.this, - LineEvent.Type.START, framesSinceOpen)); - } + } + if (dataWritten && (!isStarted)) { + fireLineEvent(new LineEvent(PulseAudioDataLine.this, + LineEvent.Type.START, framesSinceOpen)); + } - Operation op; - synchronized (eventLoop.threadLock) { - op = stream.unCork(); - } + Operation op; + synchronized (eventLoop.threadLock) { + op = stream.unCork(); + } - op.waitForCompletion(); - op.releaseReference(); - synchronized (this) { - this.notifyAll(); - } - isStarted = true; + op.waitForCompletion(); + op.releaseReference(); + synchronized (this) { + this.notifyAll(); + } + isStarted = true; - } + } - @Override - public synchronized void stop() { - if (!isOpen()) { - // For some reason, we are being asked to stop a line - // that isn't even open. - return; - } - writeInterrupted = true; - if (!isStarted) { - return; - } + @Override + public synchronized void stop() { + if (!isOpen()) { + // For some reason, we are being asked to stop a line + // that isn't even open. + return; + } + writeInterrupted = true; + if (!isStarted) { + return; + } - Operation op; - synchronized (eventLoop.threadLock) { - op = stream.cork(); - // if there are no data on the line when stop was called, - // don't send a stop event - if (dataWritten && (isStarted)) { - fireLineEvent(new LineEvent(PulseAudioDataLine.this, - LineEvent.Type.STOP, framesSinceOpen)); - } - } + Operation op; + synchronized (eventLoop.threadLock) { + op = stream.cork(); + // if there are no data on the line when stop was called, + // don't send a stop event + if (dataWritten && (isStarted)) { + fireLineEvent(new LineEvent(PulseAudioDataLine.this, + LineEvent.Type.STOP, framesSinceOpen)); + } + } - op.waitForCompletion(); - op.releaseReference(); + op.waitForCompletion(); + op.releaseReference(); - isStarted = false; - } + isStarted = false; + } - /* - * TODO - * - * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4791152 : - * - * a line is active in between calls to start() and stop(). In that sense, - * active means that the line is ready to take or give data. Running is - * tightly bound to data flow in the line. I.e. when you start a - * SourceDataLine but never write data to it, the line should not be - * running. This also means that a line should become not running on buffer - * underrun/overflow. - * - * - * HOWEVER, the javadocs say the opposite thing! (need help from the jck = - * official spec) - */ - @Override - public boolean isActive() { - return isStarted; - } + /* + * TODO + * + * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4791152 : + * + * a line is active in between calls to start() and stop(). In that sense, + * active means that the line is ready to take or give data. Running is + * tightly bound to data flow in the line. I.e. when you start a + * SourceDataLine but never write data to it, the line should not be + * running. This also means that a line should become not running on buffer + * underrun/overflow. + * + * + * HOWEVER, the javadocs say the opposite thing! (need help from the jck = + * official spec) + */ + @Override + public boolean isActive() { + return isStarted; + } - @Override - public boolean isRunning() { - return isStarted && dataWritten; - } + @Override + public boolean isRunning() { + return isStarted && dataWritten; + } - protected abstract void connectLine(int bufferSize, Stream masterStream) - throws LineUnavailableException; + protected abstract void connectLine(int bufferSize, Stream masterStream) + throws LineUnavailableException; - public Stream getStream() { - if (!isOpen()) { - throw new IllegalStateException("Line must be open"); - } + public Stream getStream() { + if (!isOpen()) { + throw new IllegalStateException("Line must be open"); + } - return stream; - } + return stream; + } - @Override - public int getBufferSize() { - if (!isOpen()) { - return DEFAULT_BUFFER_SIZE; - } - return bufferSize; - } + @Override + public int getBufferSize() { + if (!isOpen()) { + return DEFAULT_BUFFER_SIZE; + } + return stream.getBufferSize(); + } - @Override - public AudioFormat getFormat() { - if (!isOpen()) { - return defaultFormat; - } - return currentFormat; - } + @Override + public AudioFormat getFormat() { + if (!isOpen()) { + return defaultFormat; + } + return currentFormat; + } - @Override - public float getLevel() { - return AudioSystem.NOT_SPECIFIED; - } + @Override + public float getLevel() { + return AudioSystem.NOT_SPECIFIED; + } - /** - * - * @param streamName - * the name of this audio stream - */ - public void setName(String streamName) { - if (isOpen()) { + /** + * + * @param streamName + * the name of this audio stream + */ + public void setName(String streamName) { + if (isOpen()) { - Operation o; - synchronized (eventLoop.threadLock) { - o = stream.setName(streamName); - } - o.waitForCompletion(); - o.releaseReference(); + Operation o; + synchronized (eventLoop.threadLock) { + o = stream.setName(streamName); + } + o.waitForCompletion(); + o.releaseReference(); - } + } - this.streamName = streamName; + this.streamName = streamName; - } + } - /** - * - * @return the name of this audio stream/clip - */ - public String getName() { - return streamName; - } + /** + * + * @return the name of this audio stream/clip + */ + public String getName() { + return streamName; + } - public int getBytesInBuffer() { - Operation o; - synchronized (eventLoop.threadLock) { - o = stream.updateTimingInfo(); - } - o.waitForCompletion(); - o.releaseReference(); - return stream.bytesInBuffer(); - } + public int getBytesInBuffer() { + Operation o; + synchronized (eventLoop.threadLock) { + o = stream.updateTimingInfo(); + } + o.waitForCompletion(); + o.releaseReference(); + return stream.bytesInBuffer(); + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioLine.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioLine.java Wed Jul 06 17:11:34 2011 +0100 @@ -48,77 +48,77 @@ abstract class PulseAudioLine implements Line { - protected List<LineListener> lineListeners = new ArrayList<LineListener>(); - protected List<Control> controls = new ArrayList<Control>(); + protected List<LineListener> lineListeners = new ArrayList<LineListener>(); + protected List<Control> controls = new ArrayList<Control>(); - // true between open() and close(). ie represents when a line has acquire - // resources - protected boolean isOpen = false; + // true between open() and close(). ie represents when a line has acquire + // resources + protected boolean isOpen = false; - @Override - public void addLineListener(LineListener listener) { - this.lineListeners.add(listener); - } + @Override + public void addLineListener(LineListener listener) { + this.lineListeners.add(listener); + } - @Override - public void close() { - if (!isOpen()) { - throw new IllegalStateException("Line is not open"); - } + @Override + public void close() { + if (!isOpen()) { + throw new IllegalStateException("Line is not open"); + } - lineListeners.clear(); + lineListeners.clear(); - isOpen = false; - } + isOpen = false; + } - protected void fireLineEvent(LineEvent e) { - for (LineListener lineListener : lineListeners) { - lineListener.update(e); - } - } + protected void fireLineEvent(LineEvent e) { + for (LineListener lineListener : lineListeners) { + lineListener.update(e); + } + } - @Override - public Control getControl(Type control) { - if (isOpen()) { - for (Control aControl : controls) { - if (aControl.getType() == control) { - return aControl; - } - } - } - throw new IllegalArgumentException(control.toString() - + " not supported"); - } + @Override + public Control getControl(Type control) { + if (isOpen()) { + for (Control aControl : controls) { + if (aControl.getType() == control) { + return aControl; + } + } + } + throw new IllegalArgumentException(control.toString() + + " not supported"); + } - @Override - public Control[] getControls() { - if (!isOpen()) { - return new Control[] {}; - } + @Override + public Control[] getControls() { + if (!isOpen()) { + return new Control[] {}; + } - return (Control[]) controls.toArray(new Control[0]); - } + return (Control[]) controls.toArray(new Control[0]); + } - @Override - public boolean isControlSupported(Type control) { - for (Control myControl : controls) { - //Control.Type's known descendants keep a set of - //static Types. - if (myControl.getType().equals(control)) { - return true; - } - } - return false; - } + @Override + public boolean isControlSupported(Type control) { + for (Control myControl : controls) { + //Control.Type's known descendants keep a set of + //static Types. + if (myControl.getType().equals(control)) { + return true; + } + } + return false; + } - @Override - public boolean isOpen() { - return isOpen; - } + @Override + public boolean isOpen() { + return isOpen; + } - @Override - public void removeLineListener(LineListener listener) { - lineListeners.remove(listener); - } + @Override + public void removeLineListener(LineListener listener) { + lineListeners.remove(listener); + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixer.java Wed Jul 06 17:11:34 2011 +0100 @@ -66,728 +66,727 @@ import org.classpath.icedtea.pulseaudio.Debug.DebugLevel; public final class PulseAudioMixer implements Mixer { - // singleton + // singleton - private Thread eventLoopThread; + private Thread eventLoopThread; - private List<Line.Info> sourceLineInfos = new ArrayList<Line.Info>(); - private List<Line.Info> staticSourceLineInfos = new ArrayList<Line.Info>(); + private List<Line.Info> sourceLineInfos = new ArrayList<Line.Info>(); + private List<Line.Info> staticSourceLineInfos = new ArrayList<Line.Info>(); - private List<Line.Info> targetLineInfos = new ArrayList<Line.Info>(); - private List<Line.Info> staticTargetLineInfos = new ArrayList<Line.Info>(); + private List<Line.Info> targetLineInfos = new ArrayList<Line.Info>(); + private List<Line.Info> staticTargetLineInfos = new ArrayList<Line.Info>(); - private static PulseAudioMixer _instance = null; + private static PulseAudioMixer _instance = null; - private static final String DEFAULT_APP_NAME = "Java"; - static final String PULSEAUDIO_FORMAT_KEY = "PulseAudioFormatKey"; + private static final String DEFAULT_APP_NAME = "Java"; + static final String PULSEAUDIO_FORMAT_KEY = "PulseAudioFormatKey"; - private boolean isOpen = false; + private boolean isOpen = false; - private final List<PulseAudioLine> sourceLines = new ArrayList<PulseAudioLine>(); - private final List<PulseAudioLine> targetLines = new ArrayList<PulseAudioLine>(); + private final List<PulseAudioLine> sourceLines = new ArrayList<PulseAudioLine>(); + private final List<PulseAudioLine> targetLines = new ArrayList<PulseAudioLine>(); - private final List<LineListener> lineListeners = new ArrayList<LineListener>(); + private final List<LineListener> lineListeners = new ArrayList<LineListener>(); - private PulseAudioMixer() { + private PulseAudioMixer() { - Debug.println(DebugLevel.Verbose, "PulseAudioMixer.PulseAudioMixer(): " - + "Contructing PulseAudioMixer..."); + Debug.println(DebugLevel.Verbose, "PulseAudioMixer.PulseAudioMixer(): " + + "Contructing PulseAudioMixer..."); - AudioFormat[] formats = getSupportedFormats(); + AudioFormat[] formats = getSupportedFormats(); - staticSourceLineInfos.add(new DataLine.Info(SourceDataLine.class, - formats, StreamBufferAttributes.MIN_VALUE, - StreamBufferAttributes.MAX_VALUE)); - staticSourceLineInfos.add(new DataLine.Info(Clip.class, formats, - StreamBufferAttributes.MIN_VALUE, - StreamBufferAttributes.MAX_VALUE)); + staticSourceLineInfos.add(new DataLine.Info(SourceDataLine.class, + formats, StreamBufferAttributes.MIN_VALUE, + StreamBufferAttributes.MAX_VALUE)); + staticSourceLineInfos.add(new DataLine.Info(Clip.class, formats, + StreamBufferAttributes.MIN_VALUE, + StreamBufferAttributes.MAX_VALUE)); - staticTargetLineInfos.add(new DataLine.Info(TargetDataLine.class, - formats, StreamBufferAttributes.MIN_VALUE, - StreamBufferAttributes.MAX_VALUE)); + staticTargetLineInfos.add(new DataLine.Info(TargetDataLine.class, + formats, StreamBufferAttributes.MIN_VALUE, + StreamBufferAttributes.MAX_VALUE)); - refreshSourceAndTargetLines(); + refreshSourceAndTargetLines(); - Debug.println(DebugLevel.Verbose, "PulseAudioMixer.PulseAudioMixer(): " - + "Finished constructing PulseAudioMixer"); + Debug.println(DebugLevel.Verbose, "PulseAudioMixer.PulseAudioMixer(): " + + "Finished constructing PulseAudioMixer"); - } + } - synchronized public static PulseAudioMixer getInstance() { - if (_instance == null) { - _instance = new PulseAudioMixer(); - } - return _instance; - } + synchronized public static PulseAudioMixer getInstance() { + if (_instance == null) { + _instance = new PulseAudioMixer(); + } + return _instance; + } - private AudioFormat[] getSupportedFormats() { + private AudioFormat[] getSupportedFormats() { - List<AudioFormat> supportedFormats = new ArrayList<AudioFormat>(); + List<AudioFormat> supportedFormats = new ArrayList<AudioFormat>(); - Map<String, Object> properties; + Map<String, Object> properties; - /* - * frameSize = sample size (in bytes, not bits) x # of channels - * - * From PulseAudio's sources - * http://git.0pointer.de/?p=pulseaudio.git;a=blob - * ;f=src/pulse/sample.c;h=93da2465f4301e27af4976e82737c3a048124a68;hb= - * 82ea8dde8abc51165a781c69bc3b38034d62d969#l63 - */ + /* + * frameSize = sample size (in bytes, not bits) x # of channels + * + * From PulseAudio's sources + * http://git.0pointer.de/?p=pulseaudio.git;a=blob + * ;f=src/pulse/sample.c;h=93da2465f4301e27af4976e82737c3a048124a68;hb= + * 82ea8dde8abc51165a781c69bc3b38034d62d969#l63 + */ - /* - * technically, PulseAudio supports up to 16 channels, but things get - * interesting with channel maps - * - * PA_CHANNEL_MAP_DEFAULT (=PA_CHANNEL_MAP_AIFF) supports 1,2,3,4,5 or 6 - * channels only - */ - int[] channelSizes = new int[] { 1, 2, 3, 4, 5, 6 }; + /* + * technically, PulseAudio supports up to 16 channels, but things get + * interesting with channel maps + * + * PA_CHANNEL_MAP_DEFAULT (=PA_CHANNEL_MAP_AIFF) supports 1,2,3,4,5 or 6 + * channels only + */ + int[] channelSizes = new int[] { 1, 2, 3, 4, 5, 6 }; - for (int channelSize : channelSizes) { - properties = new HashMap<String, Object>(); - properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_ALAW"); + for (int channelSize : channelSizes) { + properties = new HashMap<String, Object>(); + properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_ALAW"); - int sampleSize = 8; - final AudioFormat PA_SAMPLE_ALAW = new AudioFormat(Encoding.ALAW, // encoding - AudioSystem.NOT_SPECIFIED, // sample rate - sampleSize, // sample size - channelSize, // channels - sampleSize / 8 * channelSize, // frame size - AudioSystem.NOT_SPECIFIED, // frame rate - false, // big endian? - properties); + int sampleSize = 8; + final AudioFormat PA_SAMPLE_ALAW = new AudioFormat(Encoding.ALAW, // encoding + AudioSystem.NOT_SPECIFIED, // sample rate + sampleSize, // sample size + channelSize, // channels + sampleSize / 8 * channelSize, // frame size + AudioSystem.NOT_SPECIFIED, // frame rate + false, // big endian? + properties); - supportedFormats.add(PA_SAMPLE_ALAW); - } + supportedFormats.add(PA_SAMPLE_ALAW); + } - for (int channelSize : channelSizes) { - properties = new HashMap<String, Object>(); - properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_ULAW"); + for (int channelSize : channelSizes) { + properties = new HashMap<String, Object>(); + properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_ULAW"); - int sampleSize = 8; - final AudioFormat PA_SAMPLE_ULAW = new AudioFormat(Encoding.ULAW, // encoding - AudioSystem.NOT_SPECIFIED, // sample rate - sampleSize, // sample size - channelSize, // channels - sampleSize / 8 * channelSize, // frame size - AudioSystem.NOT_SPECIFIED, // frame rate - false, // big endian? - properties); - - supportedFormats.add(PA_SAMPLE_ULAW); - } + int sampleSize = 8; + final AudioFormat PA_SAMPLE_ULAW = new AudioFormat(Encoding.ULAW, // encoding + AudioSystem.NOT_SPECIFIED, // sample rate + sampleSize, // sample size + channelSize, // channels + sampleSize / 8 * channelSize, // frame size + AudioSystem.NOT_SPECIFIED, // frame rate + false, // big endian? + properties); - for (int channelSize : channelSizes) { - properties = new HashMap<String, Object>(); - properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S16BE"); + supportedFormats.add(PA_SAMPLE_ULAW); + } - int sampleSize = 16; - final AudioFormat PA_SAMPLE_S16BE = new AudioFormat( - Encoding.PCM_SIGNED, // encoding - AudioSystem.NOT_SPECIFIED, // sample rate - sampleSize, // sample size - channelSize, // channels - sampleSize / 8 * channelSize, // frame size - AudioSystem.NOT_SPECIFIED, // frame rate - true, // big endian? - properties); - - supportedFormats.add(PA_SAMPLE_S16BE); - } + for (int channelSize : channelSizes) { + properties = new HashMap<String, Object>(); + properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S16BE"); - for (int channelSize : channelSizes) { - properties = new HashMap<String, Object>(); - properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S16LE"); + int sampleSize = 16; + final AudioFormat PA_SAMPLE_S16BE = new AudioFormat( + Encoding.PCM_SIGNED, // encoding + AudioSystem.NOT_SPECIFIED, // sample rate + sampleSize, // sample size + channelSize, // channels + sampleSize / 8 * channelSize, // frame size + AudioSystem.NOT_SPECIFIED, // frame rate + true, // big endian? + properties); - int sampleSize = 16; - final AudioFormat A_SAMPLE_S16LE = new AudioFormat( - Encoding.PCM_SIGNED, // encoding - AudioSystem.NOT_SPECIFIED, // sample rate - sampleSize, // sample size - channelSize, // channels - sampleSize / 8 * channelSize, // frame size - AudioSystem.NOT_SPECIFIED, // frame rate - false, // big endian? - properties); + supportedFormats.add(PA_SAMPLE_S16BE); + } - supportedFormats.add(A_SAMPLE_S16LE); - } - - for (int channelSize : channelSizes) { - properties = new HashMap<String, Object>(); - properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S32BE"); + for (int channelSize : channelSizes) { + properties = new HashMap<String, Object>(); + properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S16LE"); - int sampleSize = 32; - final AudioFormat PA_SAMPLE_S32BE = new AudioFormat( - Encoding.PCM_SIGNED, // encoding - AudioSystem.NOT_SPECIFIED, // sample rate - sampleSize, // sample size - channelSize, // channels - sampleSize / 8 * channelSize, // frame size - AudioSystem.NOT_SPECIFIED, // frame rate - true, // big endian? - properties); + int sampleSize = 16; + final AudioFormat A_SAMPLE_S16LE = new AudioFormat( + Encoding.PCM_SIGNED, // encoding + AudioSystem.NOT_SPECIFIED, // sample rate + sampleSize, // sample size + channelSize, // channels + sampleSize / 8 * channelSize, // frame size + AudioSystem.NOT_SPECIFIED, // frame rate + false, // big endian? + properties); - supportedFormats.add(PA_SAMPLE_S32BE); - } + supportedFormats.add(A_SAMPLE_S16LE); + } + + for (int channelSize : channelSizes) { + properties = new HashMap<String, Object>(); + properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S32BE"); - for (int channelSize : channelSizes) { - properties = new HashMap<String, Object>(); - properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S32LE"); + int sampleSize = 32; + final AudioFormat PA_SAMPLE_S32BE = new AudioFormat( + Encoding.PCM_SIGNED, // encoding + AudioSystem.NOT_SPECIFIED, // sample rate + sampleSize, // sample size + channelSize, // channels + sampleSize / 8 * channelSize, // frame size + AudioSystem.NOT_SPECIFIED, // frame rate + true, // big endian? + properties); - int sampleSize = 32; - final AudioFormat PA_SAMPLE_S32LE = new AudioFormat( - Encoding.PCM_SIGNED, // encoding - AudioSystem.NOT_SPECIFIED, // sample rate - sampleSize, // sample size - channelSize, // channels - sampleSize / 8 * channelSize, // frame size - AudioSystem.NOT_SPECIFIED, // frame rate - false, // big endian? - properties); + supportedFormats.add(PA_SAMPLE_S32BE); + } + + for (int channelSize : channelSizes) { + properties = new HashMap<String, Object>(); + properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_S32LE"); - supportedFormats.add(PA_SAMPLE_S32LE); - } - - for (int channelSize : channelSizes) { - properties = new HashMap<String, Object>(); - properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_U8"); + int sampleSize = 32; + final AudioFormat PA_SAMPLE_S32LE = new AudioFormat( + Encoding.PCM_SIGNED, // encoding + AudioSystem.NOT_SPECIFIED, // sample rate + sampleSize, // sample size + channelSize, // channels + sampleSize / 8 * channelSize, // frame size + AudioSystem.NOT_SPECIFIED, // frame rate + false, // big endian? + properties); - int sampleSize = 8; // in bits - AudioFormat PA_SAMPLE_U8 = new AudioFormat(Encoding.PCM_UNSIGNED, // encoding - AudioSystem.NOT_SPECIFIED, // sample rate - sampleSize, // sample size - channelSize, // channels - sampleSize / 8 * channelSize, // frame size in bytes - AudioSystem.NOT_SPECIFIED, // frame rate - false, // big endian? - properties); + supportedFormats.add(PA_SAMPLE_S32LE); + } - supportedFormats.add(PA_SAMPLE_U8); - } + for (int channelSize : channelSizes) { + properties = new HashMap<String, Object>(); + properties.put(PULSEAUDIO_FORMAT_KEY, "PA_SAMPLE_U8"); - return supportedFormats.toArray(new AudioFormat[0]); - } + int sampleSize = 8; // in bits + AudioFormat PA_SAMPLE_U8 = new AudioFormat(Encoding.PCM_UNSIGNED, // encoding + AudioSystem.NOT_SPECIFIED, // sample rate + sampleSize, // sample size + channelSize, // channels + sampleSize / 8 * channelSize, // frame size in bytes + AudioSystem.NOT_SPECIFIED, // frame rate + false, // big endian? + properties); - @Override - public Line getLine(Line.Info info) throws LineUnavailableException { - - if (!isLineSupported(info)) { - throw new IllegalArgumentException("Line unsupported: " + info); - } + supportedFormats.add(PA_SAMPLE_U8); + } - AudioFormat[] formats = null; - AudioFormat defaultFormat = null; + return supportedFormats.toArray(new AudioFormat[0]); + } + + @Override + public Line getLine(Line.Info info) throws LineUnavailableException { - if (DataLine.Info.class.isInstance(info)) { - ArrayList<AudioFormat> formatList = new ArrayList<AudioFormat>(); - AudioFormat[] requestedFormats = ((DataLine.Info) info) - .getFormats(); - for (int i = 0; i < requestedFormats.length; i++) { - AudioFormat f1 = requestedFormats[i]; - for (AudioFormat f2 : getSupportedFormats()) { + if (!isLineSupported(info)) { + throw new IllegalArgumentException("Line unsupported: " + info); + } + + AudioFormat[] formats = null; + AudioFormat defaultFormat = null; - if (f1.matches(f2)) { - formatList.add(f2); - defaultFormat = f1; - } - } - } - formats = formatList.toArray(new AudioFormat[0]); + if (DataLine.Info.class.isInstance(info)) { + ArrayList<AudioFormat> formatList = new ArrayList<AudioFormat>(); + AudioFormat[] requestedFormats = ((DataLine.Info) info) + .getFormats(); + for (int i = 0; i < requestedFormats.length; i++) { + AudioFormat f1 = requestedFormats[i]; + for (AudioFormat f2 : getSupportedFormats()) { - } else { - formats = getSupportedFormats(); - defaultFormat = new AudioFormat(Encoding.PCM_UNSIGNED, 44100, 8, 2, - 2, AudioSystem.NOT_SPECIFIED, false); - } + if (f1.matches(f2)) { + formatList.add(f2); + defaultFormat = f1; + } + } + } + formats = formatList.toArray(new AudioFormat[0]); - if ((info.getLineClass() == SourceDataLine.class)) { - return new PulseAudioSourceDataLine(formats, defaultFormat); - } - - if ((info.getLineClass() == TargetDataLine.class)) { - /* check for permission to record audio */ - AudioPermission perm = new AudioPermission("record", null); - perm.checkGuard(null); + } else { + formats = getSupportedFormats(); + defaultFormat = new AudioFormat(Encoding.PCM_UNSIGNED, 44100, 8, 2, + 2, AudioSystem.NOT_SPECIFIED, false); + } - return new PulseAudioTargetDataLine(formats, defaultFormat); - } + if ((info.getLineClass() == SourceDataLine.class)) { + return new PulseAudioSourceDataLine(formats, defaultFormat); + } - if ((info.getLineClass() == Clip.class)) { - return new PulseAudioClip(formats, defaultFormat); - } + if ((info.getLineClass() == TargetDataLine.class)) { + /* check for permission to record audio */ + AudioPermission perm = new AudioPermission("record", null); + perm.checkGuard(null); - if (Port.Info.class.isInstance(info)) { - Port.Info portInfo = (Port.Info) info; - if (portInfo.isSource()) { - /* check for permission to record audio */ - AudioPermission perm = new AudioPermission("record", null); - perm.checkGuard(null); + return new PulseAudioTargetDataLine(formats, defaultFormat); + } + + if ((info.getLineClass() == Clip.class)) { + return new PulseAudioClip(formats, defaultFormat); + } - return new PulseAudioSourcePort(portInfo.getName()); - } else { - return new PulseAudioTargetPort(portInfo.getName()); - } - } - - Debug.println(DebugLevel.Info, "PulseAudioMixer.getLine(): " - + "No matching line supported by PulseAudio"); - - throw new IllegalArgumentException("No matching lines found"); + if (Port.Info.class.isInstance(info)) { + Port.Info portInfo = (Port.Info) info; + if (portInfo.isSource()) { + /* check for permission to record audio */ + AudioPermission perm = new AudioPermission("record", null); + perm.checkGuard(null); - } + return new PulseAudioSourcePort(portInfo.getName()); + } else { + return new PulseAudioTargetPort(portInfo.getName()); + } + } + + Debug.println(DebugLevel.Info, "PulseAudioMixer.getLine(): " + + "No matching line supported by PulseAudio"); + + throw new IllegalArgumentException("No matching lines found"); - @Override - public int getMaxLines(Line.Info info) { - /* - * PulseAudio supports (theoretically) unlimited number of streams for - * supported formats - */ - if (isLineSupported(info)) { - return AudioSystem.NOT_SPECIFIED; - } + } - return 0; - } - - @Override - public Info getMixerInfo() { - return PulseAudioMixerInfo.getInfo(); - } + @Override + public int getMaxLines(Line.Info info) { + /* + * PulseAudio supports (theoretically) unlimited number of streams for + * supported formats + */ + if (isLineSupported(info)) { + return AudioSystem.NOT_SPECIFIED; + } - public Line.Info[] getSourceLineInfo() { - return sourceLineInfos.toArray(new Line.Info[0]); - } + return 0; + } - @Override - public Line.Info[] getSourceLineInfo(Line.Info info) { - ArrayList<Line.Info> infos = new ArrayList<Line.Info>(); + @Override + public Info getMixerInfo() { + return PulseAudioMixerInfo.getInfo(); + } + + public Line.Info[] getSourceLineInfo() { + return sourceLineInfos.toArray(new Line.Info[0]); + } - for (Line.Info supportedInfo : sourceLineInfos) { - if (info.matches(supportedInfo)) { - infos.add(supportedInfo); - } - } - return infos.toArray(new Line.Info[0]); - } + @Override + public Line.Info[] getSourceLineInfo(Line.Info info) { + ArrayList<Line.Info> infos = new ArrayList<Line.Info>(); - @Override - public Line[] getSourceLines() { - return sourceLines.toArray(new Line[0]); - - } + for (Line.Info supportedInfo : sourceLineInfos) { + if (info.matches(supportedInfo)) { + infos.add(supportedInfo); + } + } + return infos.toArray(new Line.Info[0]); + } - @Override - public Line.Info[] getTargetLineInfo() { - return targetLineInfos.toArray(new Line.Info[0]); - } + @Override + public Line[] getSourceLines() { + return sourceLines.toArray(new Line[0]); - @Override - public Line.Info[] getTargetLineInfo(Line.Info info) { - ArrayList<Line.Info> infos = new ArrayList<Line.Info>(); + } + + @Override + public Line.Info[] getTargetLineInfo() { + return targetLineInfos.toArray(new Line.Info[0]); + } - for (Line.Info supportedInfo : targetLineInfos) { - if (info.matches(supportedInfo)) { - infos.add(supportedInfo); - } - } - return infos.toArray(new Line.Info[0]); - } + @Override + public Line.Info[] getTargetLineInfo(Line.Info info) { + ArrayList<Line.Info> infos = new ArrayList<Line.Info>(); - @Override - public Line[] getTargetLines() { + for (Line.Info supportedInfo : targetLineInfos) { + if (info.matches(supportedInfo)) { + infos.add(supportedInfo); + } + } + return infos.toArray(new Line.Info[0]); + } - /* check for permission to record audio */ - AudioPermission perm = new AudioPermission("record", null); - perm.checkGuard(null); + @Override + public Line[] getTargetLines() { - return (Line[]) targetLines.toArray(new Line[0]); - } + /* check for permission to record audio */ + AudioPermission perm = new AudioPermission("record", null); + perm.checkGuard(null); - @Override - public boolean isLineSupported(Line.Info info) { - if (info != null) { - for (Line.Info myInfo : sourceLineInfos) { - if (info.matches(myInfo)) { - return true; - } - } + return (Line[]) targetLines.toArray(new Line[0]); + } - for (Line.Info myInfo : targetLineInfos) { - if (info.matches(myInfo)) { - return true; - } - } + @Override + public boolean isLineSupported(Line.Info info) { + if (info != null) { + for (Line.Info myInfo : sourceLineInfos) { + if (info.matches(myInfo)) { + return true; + } + } - } - return false; + for (Line.Info myInfo : targetLineInfos) { + if (info.matches(myInfo)) { + return true; + } + } - } + } + return false; - @Override - public boolean isSynchronizationSupported(Line[] lines, boolean maintainSync) { + } - return false; - } + @Override + public boolean isSynchronizationSupported(Line[] lines, boolean maintainSync) { + + return false; + } - @Override - public void synchronize(Line[] lines, boolean maintainSync) { + @Override + public void synchronize(Line[] lines, boolean maintainSync) { - throw new IllegalArgumentException( - "Mixer does not support synchronizing lines"); + throw new IllegalArgumentException( + "Mixer does not support synchronizing lines"); - // Line masterStream = null; - // for (Line line : lines) { - // if (line.isOpen()) { - // masterStream = line; - // break; - // } - // } - // if (masterStream == null) { - // // for now, can't synchronize lines if none of them is open (no - // // stream pointer to pass) - // // will see what to do about this later - // throw new IllegalArgumentException(); - // } - // - // try { - // - // for (Line line : lines) { - // if (line != masterStream) { - // - // ((PulseAudioDataLine) line) - // .reconnectforSynchronization(((PulseAudioDataLine) masterStream) - // .getStream()); - // - // } - // } - // } catch (LineUnavailableException e) { - // // we couldn't reconnect, so tell the user we failed by throwing an - // // exception - // throw new IllegalArgumentException(e); - // } + // Line masterStream = null; + // for (Line line : lines) { + // if (line.isOpen()) { + // masterStream = line; + // break; + // } + // } + // if (masterStream == null) { + // // for now, can't synchronize lines if none of them is open (no + // // stream pointer to pass) + // // will see what to do about this later + // throw new IllegalArgumentException(); + // } + // + // try { + // + // for (Line line : lines) { + // if (line != masterStream) { + // + // ((PulseAudioDataLine) line) + // .reconnectforSynchronization(((PulseAudioDataLine) masterStream) + // .getStream()); + // + // } + // } + // } catch (LineUnavailableException e) { + // // we couldn't reconnect, so tell the user we failed by throwing an + // // exception + // throw new IllegalArgumentException(e); + // } - } + } - @Override - public void unsynchronize(Line[] lines) { - // FIXME should be able to implement this - throw new IllegalArgumentException(); - } + @Override + public void unsynchronize(Line[] lines) { + // FIXME should be able to implement this + throw new IllegalArgumentException(); + } - @Override - public void addLineListener(LineListener listener) { - lineListeners.add(listener); - } + @Override + public void addLineListener(LineListener listener) { + lineListeners.add(listener); + } - @Override - synchronized public void close() { + @Override + synchronized public void close() { - /* - * only allow the mixer to be controlled if either playback or recording - * is allowed - */ + /* + * only allow the mixer to be controlled if either playback or recording + * is allowed + */ - if (!this.isOpen) { - throw new IllegalStateException("Mixer is not open; cant close"); - } + if (!this.isOpen) { + throw new IllegalStateException("Mixer is not open; cant close"); + } - List<Line> linesToClose = new LinkedList<Line>(); - linesToClose.addAll(sourceLines); - if (sourceLines.size() > 0) { + List<Line> linesToClose = new LinkedList<Line>(); + linesToClose.addAll(sourceLines); + if (sourceLines.size() > 0) { - Debug.println(DebugLevel.Warning, "PulseAudioMixer.close(): " - + linesToClose.size() - + " source lines were not closed. closing them now."); + Debug.println(DebugLevel.Warning, "PulseAudioMixer.close(): " + + linesToClose.size() + + " source lines were not closed. closing them now."); - linesToClose.addAll(sourceLines); - for (Line line : linesToClose) { - if (line.isOpen()) { - line.close(); - } - } - } - linesToClose.clear(); + linesToClose.addAll(sourceLines); + for (Line line : linesToClose) { + if (line.isOpen()) { + line.close(); + } + } + } + linesToClose.clear(); - if (targetLines.size() > 0) { - Debug.println(DebugLevel.Warning, "PulseAudioMixer.close(): " - + linesToClose.size() - + " target lines have not been closed"); + if (targetLines.size() > 0) { + Debug.println(DebugLevel.Warning, "PulseAudioMixer.close(): " + + linesToClose.size() + + " target lines have not been closed"); - linesToClose.addAll(targetLines); - for (Line line : linesToClose) { - if (line.isOpen()) { - line.close(); - } - } - } + linesToClose.addAll(targetLines); + for (Line line : linesToClose) { + if (line.isOpen()) { + line.close(); + } + } + } - synchronized (lineListeners) { - lineListeners.clear(); - } + synchronized (lineListeners) { + lineListeners.clear(); + } - eventLoopThread.interrupt(); + eventLoopThread.interrupt(); - try { - eventLoopThread.join(); - } catch (InterruptedException e) { - System.out.println(this.getClass().getName() - + ": interrupted while waiting for eventloop to finish"); - } + try { + eventLoopThread.join(); + } catch (InterruptedException e) { + System.out.println(this.getClass().getName() + + ": interrupted while waiting for eventloop to finish"); + } - isOpen = false; + isOpen = false; - refreshSourceAndTargetLines(); + refreshSourceAndTargetLines(); - Debug.println(DebugLevel.Verbose, "PulseAudioMixer.close(): " - + "Mixer closed"); + Debug.println(DebugLevel.Verbose, "PulseAudioMixer.close(): " + + "Mixer closed"); - } + } - @Override - public Control getControl(Type control) { - // mixer supports no controls - throw new IllegalArgumentException(); - } + @Override + public Control getControl(Type control) { + // mixer supports no controls + throw new IllegalArgumentException(); + } - @Override - public Control[] getControls() { - // mixer supports no controls; return an array of length 0 - return new Control[] {}; - } + @Override + public Control[] getControls() { + // mixer supports no controls; return an array of length 0 + return new Control[] {}; + } - @Override - public javax.sound.sampled.Line.Info getLineInfo() { - // System.out.println("DEBUG: PulseAudioMixer.getLineInfo() called"); - return new Line.Info(PulseAudioMixer.class); - } + @Override + public javax.sound.sampled.Line.Info getLineInfo() { + // System.out.println("DEBUG: PulseAudioMixer.getLineInfo() called"); + return new Line.Info(PulseAudioMixer.class); + } - @Override - public boolean isControlSupported(Type control) { - // mixer supports no controls - return false; - } + @Override + public boolean isControlSupported(Type control) { + // mixer supports no controls + return false; + } - @Override - public boolean isOpen() { - return isOpen; - } + @Override + public boolean isOpen() { + return isOpen; + } - @Override - public void open() throws LineUnavailableException { - openLocal(); + @Override + public void open() throws LineUnavailableException { + openLocal(); - } + } - public void openLocal() throws LineUnavailableException { - openLocal(DEFAULT_APP_NAME); - } + public void openLocal() throws LineUnavailableException { + openLocal(DEFAULT_APP_NAME); + } - public void openLocal(String appName) throws LineUnavailableException { - openImpl(appName, null); - } + public void openLocal(String appName) throws LineUnavailableException { + openImpl(appName, null); + } - public void openRemote(String appName, String host) - throws UnknownHostException, LineUnavailableException { - if (host == null) { - throw new NullPointerException("hostname"); - } - - final int PULSEAUDIO_DEFAULT_PORT = 4713; - - /* - * If trying to connect to a remote machine, check for permissions - */ - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkConnect(host,PULSEAUDIO_DEFAULT_PORT ); - } - - openImpl(appName, host); - } + public void openRemote(String appName, String host) + throws UnknownHostException, LineUnavailableException { + if (host == null) { + throw new NullPointerException("hostname"); + } + + final int PULSEAUDIO_DEFAULT_PORT = 4713; + + /* + * If trying to connect to a remote machine, check for permissions + */ + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkConnect(host,PULSEAUDIO_DEFAULT_PORT ); + } + + openImpl(appName, host); + } - public void openRemote(String appName, String host, int port) - throws UnknownHostException, LineUnavailableException { + public void openRemote(String appName, String host, int port) + throws UnknownHostException, LineUnavailableException { - if ((port < 1) && (port != -1)) { - throw new IllegalArgumentException("Invalid value for port"); - } + if ((port < 1) && (port != -1)) { + throw new IllegalArgumentException("Invalid value for port"); + } - if (host == null) { - throw new NullPointerException("hostname"); - } + if (host == null) { + throw new NullPointerException("hostname"); + } - /* - * If trying to connect to a remote machine, check for permissions - */ - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkConnect(host, port); - } + /* + * If trying to connect to a remote machine, check for permissions + */ + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkConnect(host, port); + } - InetAddress addr = InetAddress.getAllByName(host)[0]; + InetAddress addr = InetAddress.getAllByName(host)[0]; - host = addr.getHostAddress(); - host = host + ":" + String.valueOf(port); + host = addr.getHostAddress(); + host = host + ":" + String.valueOf(port); - openImpl(appName, host); - - } + openImpl(appName, host); + + } - /* - * - * @param appName name of the application - * - * @param hostAndIp a string consisting of the host and ip address of the - * server to connect to. Format: "<host>:<ip>". Set to null to indicate a - * local connection - */ - synchronized private void openImpl(String appName, String hostAndIp) - throws LineUnavailableException { + /* + * + * @param appName name of the application + * + * @param hostAndIp a string consisting of the host and ip address of the + * server to connect to. Format: "<host>:<ip>". Set to null to indicate a + * local connection + */ + synchronized private void openImpl(String appName, String hostAndIp) + throws LineUnavailableException { - if (isOpen) { - throw new IllegalStateException("Mixer is already open"); - } + if (isOpen) { + throw new IllegalStateException("Mixer is already open"); + } - EventLoop eventLoop; - eventLoop = EventLoop.getEventLoop(); - eventLoop.setAppName(appName); - eventLoop.setServer(hostAndIp); + EventLoop eventLoop; + eventLoop = EventLoop.getEventLoop(); + eventLoop.setAppName(appName); + eventLoop.setServer(hostAndIp); - ContextListener generalEventListener = new ContextListener() { - @Override - public void update(ContextEvent e) { - if (e.getType() == ContextEvent.Type.READY) { - fireEvent(new LineEvent(PulseAudioMixer.this, - LineEvent.Type.OPEN, AudioSystem.NOT_SPECIFIED)); - } else if (e.getType() == ContextEvent.Type.FAILED - || e.getType() == ContextEvent.Type.TERMINATED) { - fireEvent(new LineEvent(PulseAudioMixer.this, - LineEvent.Type.CLOSE, AudioSystem.NOT_SPECIFIED)); - } - } - }; + ContextListener generalEventListener = new ContextListener() { + @Override + public void update(ContextEvent e) { + if (e.getType() == ContextEvent.READY) { + fireEvent(new LineEvent(PulseAudioMixer.this, + LineEvent.Type.OPEN, AudioSystem.NOT_SPECIFIED)); + } else if (e.getType() == ContextEvent.FAILED + || e.getType() == ContextEvent.TERMINATED) { + fireEvent(new LineEvent(PulseAudioMixer.this, + LineEvent.Type.CLOSE, AudioSystem.NOT_SPECIFIED)); + } + } + }; - eventLoop.addContextListener(generalEventListener); + eventLoop.addContextListener(generalEventListener); - final Semaphore ready = new Semaphore(0); + final Semaphore ready = new Semaphore(0); - ContextListener initListener = new ContextListener() { + ContextListener initListener = new ContextListener() { - @Override - public void update(ContextEvent e) { - if (e.getType() == ContextEvent.Type.READY - || e.getType() == ContextEvent.Type.FAILED - || e.getType() == ContextEvent.Type.TERMINATED) { - ready.release(); - } - } + @Override + public void update(ContextEvent e) { + if (e.getType() == ContextEvent.READY + || e.getType() == ContextEvent.FAILED + || e.getType() == ContextEvent.TERMINATED) { + ready.release(); + } + } - }; + }; - eventLoop.addContextListener(initListener); + eventLoop.addContextListener(initListener); - eventLoopThread = new Thread(eventLoop, "PulseAudio Eventloop Thread"); + eventLoopThread = new Thread(eventLoop, "PulseAudio Eventloop Thread"); - /* - * Make the thread exit if by some weird error it is the only thread - * running. The application should be able to exit if the main thread - * doesn't or can't (perhaps an assert?) do a mixer.close(). - */ - eventLoopThread.setDaemon(true); - eventLoopThread.start(); + /* + * Make the thread exit if by some weird error it is the only thread + * running. The application should be able to exit if the main thread + * doesn't or can't (perhaps an assert?) do a mixer.close(). + */ + eventLoopThread.setDaemon(true); + eventLoopThread.start(); - try { - // System.out.println("waiting..."); - ready.acquire(); - if (eventLoop.getStatus() != 4) { - /* - * when exiting, wait for the thread to end otherwise we get one - * thread that inits the singleton with new data and the old - * thread then cleans up the singleton asserts fail all over the - * place - */ - eventLoop.removeContextListener(initListener); - eventLoopThread.interrupt(); - eventLoopThread.join(); - throw new LineUnavailableException(); - } - eventLoop.removeContextListener(initListener); - // System.out.println("got signal"); - } catch (InterruptedException e) { - System.out - .println("PulseAudioMixer: got interrupted while waiting for the EventLoop to initialize"); - } + try { + // System.out.println("waiting..."); + ready.acquire(); + if (eventLoop.getStatus() != ContextEvent.READY) { + /* + * when exiting, wait for the thread to end otherwise we get one + * thread that inits the singleton with new data and the old + * thread then cleans up the singleton asserts fail all over the + * place + */ + eventLoop.removeContextListener(initListener); + eventLoopThread.interrupt(); + eventLoopThread.join(); + throw new LineUnavailableException(); + } + eventLoop.removeContextListener(initListener); + // System.out.println("got signal"); + } catch (InterruptedException e) { + System.out.println("PulseAudioMixer: got interrupted while waiting for the EventLoop to initialize"); + } - // System.out.println(this.getClass().getName() + ": ready"); + // System.out.println(this.getClass().getName() + ": ready"); - this.isOpen = true; + this.isOpen = true; - // sourceLineInfo and targetLineInfo need to be updated with - // port infos, which can only be obtained after EventLoop had started + // sourceLineInfo and targetLineInfo need to be updated with + // port infos, which can only be obtained after EventLoop had started - refreshSourceAndTargetLines(); + refreshSourceAndTargetLines(); - for (String portName : eventLoop.updateSourcePortNameList()) { - sourceLineInfos.add(new Port.Info(Port.class, portName, true)); - } + for (String portName : eventLoop.updateSourcePortNameList()) { + sourceLineInfos.add(new Port.Info(Port.class, portName, true)); + } - for (String portName : eventLoop.updateTargetPortNameList()) { - targetLineInfos.add(new Port.Info(Port.class, portName, false)); - } + for (String portName : eventLoop.updateTargetPortNameList()) { + targetLineInfos.add(new Port.Info(Port.class, portName, false)); + } - Debug.println(DebugLevel.Debug, "PulseAudioMixer.open(): " - + "Mixer opened"); + Debug.println(DebugLevel.Debug, "PulseAudioMixer.open(): " + + "Mixer opened"); - } + } - @Override - public void removeLineListener(LineListener listener) { - lineListeners.remove(listener); - } + @Override + public void removeLineListener(LineListener listener) { + lineListeners.remove(listener); + } - /* - * Should this method be synchronized? I had a few reasons, but i forgot - * them Pros: - Thread safety? - * - * Cons: - eventListeners are run from other threads, if those then call - * fireEvent while a method is waiting on a listener, this synchronized - * block wont be entered: deadlock! - */ - private void fireEvent(final LineEvent e) { - synchronized (lineListeners) { - for (LineListener lineListener : lineListeners) { - lineListener.update(e); - } - } - } + /* + * Should this method be synchronized? I had a few reasons, but i forgot + * them Pros: - Thread safety? + * + * Cons: - eventListeners are run from other threads, if those then call + * fireEvent while a method is waiting on a listener, this synchronized + * block wont be entered: deadlock! + */ + private void fireEvent(final LineEvent e) { + synchronized (lineListeners) { + for (LineListener lineListener : lineListeners) { + lineListener.update(e); + } + } + } - void addSourceLine(PulseAudioLine line) { - sourceLines.add(line); - } + void addSourceLine(PulseAudioLine line) { + sourceLines.add(line); + } - void removeSourceLine(PulseAudioLine line) { - sourceLines.remove(line); - } + void removeSourceLine(PulseAudioLine line) { + sourceLines.remove(line); + } - void addTargetLine(PulseAudioLine line) { - targetLines.add(line); - } + void addTargetLine(PulseAudioLine line) { + targetLines.add(line); + } - void removeTargetLine(PulseAudioLine line) { - targetLines.remove(line); - } + void removeTargetLine(PulseAudioLine line) { + targetLines.remove(line); + } - void refreshSourceAndTargetLines() { + void refreshSourceAndTargetLines() { - sourceLineInfos.clear(); - targetLineInfos.clear(); + sourceLineInfos.clear(); + targetLineInfos.clear(); - sourceLineInfos.addAll(staticSourceLineInfos); + sourceLineInfos.addAll(staticSourceLineInfos); - targetLineInfos.addAll(staticTargetLineInfos); + targetLineInfos.addAll(staticTargetLineInfos); - } + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixerInfo.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixerInfo.java Wed Jul 06 17:11:34 2011 +0100 @@ -40,23 +40,23 @@ import javax.sound.sampled.Mixer; public final class PulseAudioMixerInfo extends Mixer.Info { - // singleton + // singleton - private static PulseAudioMixerInfo _instance = null; + private static PulseAudioMixerInfo _instance = null; - protected PulseAudioMixerInfo(String name, String vendor, - String description, String version) { - super(name, vendor, description, version); - } + protected PulseAudioMixerInfo(String name, String vendor, + String description, String version) { + super(name, vendor, description, version); + } - // the "getInstance()" method - synchronized public static PulseAudioMixerInfo getInfo() { - if (_instance == null) { - _instance = new PulseAudioMixerInfo("PulseAudio Mixer", "IcedTea", - "the ear-candy mixer", "0.02"); - } + // the "getInstance()" method + synchronized public static PulseAudioMixerInfo getInfo() { + if (_instance == null) { + _instance = new PulseAudioMixerInfo("PulseAudio Mixer", "IcedTea", + "the ear-candy mixer", "0.02"); + } - return _instance; - } + return _instance; + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixerProvider.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMixerProvider.java Wed Jul 06 17:11:34 2011 +0100 @@ -41,23 +41,23 @@ import javax.sound.sampled.Mixer.Info; public class PulseAudioMixerProvider extends - javax.sound.sampled.spi.MixerProvider { + javax.sound.sampled.spi.MixerProvider { - @Override - public Mixer getMixer(Info info) { - // System.out.println("DEBUG: getMixer called"); - if (info.equals(PulseAudioMixerInfo.getInfo())) { - return PulseAudioMixer.getInstance(); - } else { - throw new IllegalArgumentException("Mixer type not supported"); - } - } + @Override + public Mixer getMixer(Info info) { + // System.out.println("DEBUG: getMixer called"); + if (info.equals(PulseAudioMixerInfo.getInfo())) { + return PulseAudioMixer.getInstance(); + } else { + throw new IllegalArgumentException("Mixer type not supported"); + } + } - @Override - public Info[] getMixerInfo() { - // System.out.println("DEBUG: get mixer info called"); - Mixer.Info[] m = { PulseAudioMixerInfo.getInfo() }; - return m; - } + @Override + public Info[] getMixerInfo() { + // System.out.println("DEBUG: get mixer info called"); + Mixer.Info[] m = { PulseAudioMixerInfo.getInfo() }; + return m; + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPlaybackLine.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPlaybackLine.java Wed Jul 06 17:11:34 2011 +0100 @@ -42,44 +42,44 @@ */ interface PulseAudioPlaybackLine { - /** - * Set the volume of the Line (ie, sink input, source, or sink) - * - * @return an Operation object which can be used to check if the operation - * has completed - */ - byte[] native_set_volume(float value); + /** + * Set the volume of the Line (ie, sink input, source, or sink) + * + * @return an Operation object which can be used to check if the operation + * has completed + */ + byte[] native_set_volume(float value); - /** - * - * Update the volume information of a Line (sink input, source or sink) - * - * @return an Operation object which can be used to check if the operation - * has been completed - */ - byte[] native_update_volume(); - - - /** - * Gets the cached volume. To get the current volume, call - * native_update_volume, and then call this method to get the updated - * volume. - * - * @return the cached volume of the Line - */ - float getCachedVolume(); + /** + * + * Update the volume information of a Line (sink input, source or sink) + * + * @return an Operation object which can be used to check if the operation + * has been completed + */ + byte[] native_update_volume(); + + + /** + * Gets the cached volume. To get the current volume, call + * native_update_volume, and then call this method to get the updated + * volume. + * + * @return the cached volume of the Line + */ + float getCachedVolume(); - /** - * Set the cached value of a line - * - */ - void setCachedVolume(float volume); + /** + * Set the cached value of a line + * + */ + void setCachedVolume(float volume); - /** - * Check if a line is open - * - * @return <code>true</code> if line is open - */ - boolean isOpen(); + /** + * Check if a line is open + * + * @return <code>true</code> if line is open + */ + boolean isOpen(); }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java Wed Jul 06 17:11:34 2011 +0100 @@ -43,119 +43,119 @@ import javax.sound.sampled.Port; abstract class PulseAudioPort extends PulseAudioLine implements Port, - PulseAudioPlaybackLine { + PulseAudioPlaybackLine { - private String name; + private String name; - /* - * Variable used in native code - */ - @SuppressWarnings("unused") - private byte[] contextPointer; - @SuppressWarnings("unused") - private int channels; + /* + * Variable used in native code + */ + @SuppressWarnings("unused") + private byte[] contextPointer; + @SuppressWarnings("unused") + private int channels; - private EventLoop eventLoop; + private EventLoop eventLoop; - private float cachedVolume; + private float cachedVolume; - private PulseAudioVolumeControl volumeControl; + private PulseAudioVolumeControl volumeControl; - static { - SecurityWrapper.loadNativeLibrary(); - } + static { + SecurityWrapper.loadNativeLibrary(); + } - PulseAudioPort(String portName) { - this.name = portName; - this.eventLoop = EventLoop.getEventLoop(); - this.contextPointer = eventLoop.getContextPointer(); + PulseAudioPort(String portName) { + this.name = portName; + this.eventLoop = EventLoop.getEventLoop(); + this.contextPointer = eventLoop.getContextPointer(); - updateVolumeInfo(); + updateVolumeInfo(); - volumeControl = new PulseAudioVolumeControl(this, eventLoop); - controls.add(volumeControl); + volumeControl = new PulseAudioVolumeControl(this, eventLoop); + controls.add(volumeControl); - /* - * unlike other lines, Ports must either be open or close - * - * close = no sound. open = sound - */ - open(); + /* + * unlike other lines, Ports must either be open or close + * + * close = no sound. open = sound + */ + open(); - // System.out.println("Opened Target Port " + name); - } + // System.out.println("Opened Target Port " + name); + } - // FIXME why public - @Override - public abstract byte[] native_set_volume(float newValue); + // FIXME why public + @Override + public abstract byte[] native_set_volume(float newValue); - /** - * - * @see {@link update_channels_and_volume} - */ - // FIXME why public - public abstract byte[] native_update_volume(); + /** + * + * @see {@link update_channels_and_volume} + */ + // FIXME why public + public abstract byte[] native_update_volume(); - @Override - public float getCachedVolume() { - return this.cachedVolume; - } + @Override + public float getCachedVolume() { + return this.cachedVolume; + } - @Override - public void setCachedVolume(float value) { - this.cachedVolume = value; + @Override + public void setCachedVolume(float value) { + this.cachedVolume = value; - } + } - private void updateVolumeInfo() { - Operation op; - synchronized (eventLoop.threadLock) { - op = new Operation(native_update_volume()); - } + private void updateVolumeInfo() { + Operation op; + synchronized (eventLoop.threadLock) { + op = new Operation(native_update_volume()); + } - op.waitForCompletion(); - op.releaseReference(); - } + op.waitForCompletion(); + op.releaseReference(); + } - /** - * Callback used by JNI when native_update_volume completes - * - * @param channels - * the number of channels - * @param cachedVolume - * the new volume - */ - @SuppressWarnings("unused") - void update_channels_and_volume(int channels, float volume) { - this.channels = channels; - this.cachedVolume = volume; - } + /** + * Callback used by JNI when native_update_volume completes + * + * @param channels + * the number of channels + * @param cachedVolume + * the new volume + */ + @SuppressWarnings("unused") + void update_channels_and_volume(int channels, float volume) { + this.channels = channels; + this.cachedVolume = volume; + } - @Override - public void close() { + @Override + public void close() { - native_set_volume((float) 0); - isOpen = false; - fireLineEvent(new LineEvent(this, LineEvent.Type.CLOSE, - AudioSystem.NOT_SPECIFIED)); - } + native_set_volume((float) 0); + isOpen = false; + fireLineEvent(new LineEvent(this, LineEvent.Type.CLOSE, + AudioSystem.NOT_SPECIFIED)); + } - @Override - public abstract Line.Info getLineInfo(); + @Override + public abstract Line.Info getLineInfo(); - @Override - public void open() { - if (isOpen) { - return; - } - native_set_volume(cachedVolume); - isOpen = true; - fireLineEvent(new LineEvent(this, LineEvent.Type.OPEN, - AudioSystem.NOT_SPECIFIED)); - } + @Override + public void open() { + if (isOpen) { + return; + } + native_set_volume(cachedVolume); + isOpen = true; + fireLineEvent(new LineEvent(this, LineEvent.Type.OPEN, + AudioSystem.NOT_SPECIFIED)); + } - public String getName() { - return this.name; - } + public String getName() { + return this.name; + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java Wed Jul 06 17:11:34 2011 +0100 @@ -49,294 +49,297 @@ import org.classpath.icedtea.pulseaudio.Debug.DebugLevel; public final class PulseAudioSourceDataLine extends PulseAudioDataLine - implements SourceDataLine, PulseAudioPlaybackLine { + implements SourceDataLine, PulseAudioPlaybackLine { - private PulseAudioVolumeControl volumeControl; - - public static final String DEFAULT_SOURCEDATALINE_NAME = "Audio Stream"; + private PulseAudioVolumeControl volumeControl; - /* - * Package-private constructor only called by PulseAudioMixer - */ - PulseAudioSourceDataLine(AudioFormat[] formats, AudioFormat defaultFormat) { + public static final String DEFAULT_SOURCEDATALINE_NAME = "Audio Stream"; - this.supportedFormats = formats; - this.lineListeners = new ArrayList<LineListener>(); - this.defaultFormat = defaultFormat; - this.currentFormat = defaultFormat; - this.streamName = DEFAULT_SOURCEDATALINE_NAME; + /* + * Package-private constructor only called by PulseAudioMixer + */ + PulseAudioSourceDataLine(AudioFormat[] formats, AudioFormat defaultFormat) { - } + this.supportedFormats = formats; + this.lineListeners = new ArrayList<LineListener>(); + this.defaultFormat = defaultFormat; + this.currentFormat = defaultFormat; + this.streamName = DEFAULT_SOURCEDATALINE_NAME; - @Override - synchronized public void open(AudioFormat format, int bufferSize) - throws LineUnavailableException { - - super.open(format, bufferSize); + } - volumeControl = new PulseAudioVolumeControl(this, eventLoop); - controls.add(volumeControl); + @Override + synchronized public void open(AudioFormat format, int bufferSize) + throws LineUnavailableException { + + super.open(format, bufferSize); - PulseAudioMixer parentMixer = PulseAudioMixer.getInstance(); - parentMixer.addSourceLine(this); + volumeControl = new PulseAudioVolumeControl(this, eventLoop); + controls.add(volumeControl); - Debug.println(DebugLevel.Verbose, "PulseAudioSourceDataLine.open(): " - + "line opened"); - - } + PulseAudioMixer parentMixer = PulseAudioMixer.getInstance(); + parentMixer.addSourceLine(this); - @Override - public void open(AudioFormat format) throws LineUnavailableException { - open(format, DEFAULT_BUFFER_SIZE); - } + Debug.println(DebugLevel.Verbose, "PulseAudioSourceDataLine.open(): " + + "line opened"); + + } - // FIXME - public byte[] native_set_volume(float value) { - synchronized (eventLoop.threadLock) { - return stream.native_set_volume(value); - } - } + @Override + public void open(AudioFormat format) throws LineUnavailableException { + open(format, DEFAULT_BUFFER_SIZE); + } - public byte[] native_update_volume() { - synchronized (eventLoop.threadLock) { - return stream.native_update_volume(); - } - } - - @Override - public float getCachedVolume() { - return stream.getCachedVolume(); - } + // FIXME + public byte[] native_set_volume(float value) { + synchronized (eventLoop.threadLock) { + return stream.native_set_volume(value); + } + } - @Override - synchronized public void setCachedVolume(float value) { - stream.setCachedVolume(value); - } + public byte[] native_update_volume() { + synchronized (eventLoop.threadLock) { + return stream.native_update_volume(); + } + } + + @Override + public float getCachedVolume() { + return stream.getCachedVolume(); + } - @Override - protected void connectLine(int bufferSize, Stream masterStream) - throws LineUnavailableException { - StreamBufferAttributes bufferAttributes = new StreamBufferAttributes( - - bufferSize, bufferSize / 4, bufferSize / 8, - ((bufferSize / 10) > 100 ? bufferSize / 10 : 100), 0); + @Override + synchronized public void setCachedVolume(float value) { + stream.setCachedVolume(value); + } - if (masterStream != null) { - synchronized (eventLoop.threadLock) { - stream.connectForPlayback(Stream.DEFAULT_DEVICE, - bufferAttributes, masterStream.getStreamPointer()); - } - } else { - synchronized (eventLoop.threadLock) { - stream.connectForPlayback(Stream.DEFAULT_DEVICE, - bufferAttributes, null); - } - } - } + @Override + protected void connectLine(int bufferSize, Stream masterStream) + throws LineUnavailableException { + StreamBufferAttributes bufferAttributes = + new StreamBufferAttributes( + bufferSize, + bufferSize / 4, + bufferSize / 8, + Math.max(bufferSize / 10, 100), + 0); - @Override - public int write(byte[] data, int offset, int length) { - // can't call write() without open()ing first, but can call write() - // without start()ing - synchronized (this) { - writeInterrupted = false; - } + if (masterStream != null) { + synchronized (eventLoop.threadLock) { + stream.connectForPlayback(Stream.DEFAULT_DEVICE, + bufferAttributes, masterStream.getStreamPointer()); + } + } else { + synchronized (eventLoop.threadLock) { + stream.connectForPlayback(Stream.DEFAULT_DEVICE, + bufferAttributes, null); + } + } + } - if (!isOpen()) { - // A closed line can write exactly 0 bytes. - return 0; - } + @Override + public int write(byte[] data, int offset, int length) { + // can't call write() without open()ing first, but can call write() + // without start()ing + synchronized (this) { + writeInterrupted = false; + } + + if (!isOpen()) { + // A closed line can write exactly 0 bytes. + return 0; + } - int frameSize = currentFormat.getFrameSize(); - if (length % frameSize != 0) { - throw new IllegalArgumentException( - "amount of data to write does not represent an integral number of frames"); - } - - if (length < 0) { - throw new IllegalArgumentException("length is negative"); - } - - if (length < 0 || offset < 0 || offset > data.length - length) { - throw new ArrayIndexOutOfBoundsException( - "Overflow condition: buffer.length=" + data.length + - " offset= " + offset + " length=" + length ); - } - - int position = offset; - int remainingLength = length; - int availableSize = 0; - - int sizeWritten = 0; + int frameSize = currentFormat.getFrameSize(); + if (length % frameSize != 0) { + throw new IllegalArgumentException( + "amount of data to write does not represent an integral number of frames"); + } + + if (length < 0) { + throw new IllegalArgumentException("length is negative"); + } + + if (length < 0 || offset < 0 || offset > data.length - length) { + throw new ArrayIndexOutOfBoundsException( + "Overflow condition: buffer.length=" + data.length + + " offset= " + offset + " length=" + length ); + } - boolean interrupted = false; - - while (remainingLength != 0) { + int position = offset; + int remainingLength = length; + int availableSize = 0; - synchronized (eventLoop.threadLock) { + int sizeWritten = 0; - do { - if (writeInterrupted) { - return sizeWritten; - } + boolean interrupted = false; + + while (remainingLength != 0) { - if (availableSize == -1) { - return sizeWritten; - } - availableSize = stream.getWritableSize(); + synchronized (eventLoop.threadLock) { - if (availableSize == 0) { - try { - eventLoop.threadLock.wait(100); - } catch (InterruptedException e) { - // ignore for now - interrupted = true; - } + do { + if (writeInterrupted) { + return sizeWritten; + } + + if (availableSize == -1) { + return sizeWritten; + } + availableSize = stream.getWritableSize(); - } - - } while (availableSize == 0); + if (availableSize == 0) { + try { + eventLoop.threadLock.wait(100); + } catch (InterruptedException e) { + // ignore for now + interrupted = true; + } - if (availableSize > remainingLength) { - availableSize = remainingLength; - } + } + + } while (availableSize == 0); - // only write entire frames, so round down avialableSize to - // a multiple of frameSize - availableSize = (availableSize / frameSize) * frameSize; + if (availableSize > remainingLength) { + availableSize = remainingLength; + } - synchronized (this) { - if (writeInterrupted) { - return sizeWritten; - } - /* write a little bit of the buffer */ - stream.write(data, position, availableSize); - } - - sizeWritten += availableSize; - position += availableSize; - remainingLength -= availableSize; + // only write entire frames, so round down avialableSize to + // a multiple of frameSize + availableSize = (availableSize / frameSize) * frameSize; - framesSinceOpen += availableSize / frameSize; - - } - } + synchronized (this) { + if (writeInterrupted) { + return sizeWritten; + } + /* write a little bit of the buffer */ + stream.write(data, position, availableSize); + } - // all the data should have been played by now - assert (sizeWritten == length); + sizeWritten += availableSize; + position += availableSize; + remainingLength -= availableSize; - if (interrupted) { - Thread.currentThread().interrupt(); - } + framesSinceOpen += availableSize / frameSize; + + } + } - return sizeWritten; - } + // all the data should have been played by now + assert (sizeWritten == length); + + if (interrupted) { + Thread.currentThread().interrupt(); + } - @Override - public int available() { - synchronized (eventLoop.threadLock) { - return stream.getWritableSize(); - } - }; + return sizeWritten; + } - @Override - public int getFramePosition() { - return (int) framesSinceOpen; - } + @Override + public int available() { + synchronized (eventLoop.threadLock) { + return stream.getWritableSize(); + } + }; - @Override - public long getLongFramePosition() { - return framesSinceOpen; - } + @Override + public int getFramePosition() { + return (int) framesSinceOpen; + } - @Override - public long getMicrosecondPosition() { + @Override + public long getLongFramePosition() { + return framesSinceOpen; + } - float frameRate = currentFormat.getFrameRate(); - float time = framesSinceOpen / frameRate; // seconds - long microseconds = (long) (time * 1000); - return microseconds; - } + @Override + public long getMicrosecondPosition() { - @Override - public void drain() { + float frameRate = currentFormat.getFrameRate(); + float time = framesSinceOpen / frameRate; // seconds + long microseconds = (long) (time * 1000); + return microseconds; + } - synchronized (this) { - writeInterrupted = true; - } + @Override + public void drain() { - do { - synchronized (this) { - if (!isOpen()) { - return; - } - if (getBytesInBuffer() == 0) { - return; - } - if (isStarted) { - break; - } - try { - this.wait(100); - } catch (InterruptedException e) { - return; - } - } - } while (!isStarted); + synchronized (this) { + writeInterrupted = true; + } - Operation operation; - - synchronized (eventLoop.threadLock) { - operation = stream.drain(); - } + do { + synchronized (this) { + if (!isOpen()) { + return; + } + if (getBytesInBuffer() == 0) { + return; + } + if (isStarted) { + break; + } + try { + this.wait(100); + } catch (InterruptedException e) { + return; + } + } + } while (!isStarted); - operation.waitForCompletion(); - operation.releaseReference(); - - } + Operation operation; - @Override - public void flush() { - synchronized (this) { - writeInterrupted = true; - } + synchronized (eventLoop.threadLock) { + operation = stream.drain(); + } + + operation.waitForCompletion(); + operation.releaseReference(); + + } - if (isOpen()) { - Operation operation; - synchronized (eventLoop.threadLock) { - operation = stream.flush(); - } + @Override + public void flush() { + synchronized (this) { + writeInterrupted = true; + } - operation.waitForCompletion(); - operation.releaseReference(); - } - - } + if (isOpen()) { + Operation operation; + synchronized (eventLoop.threadLock) { + operation = stream.flush(); + } - @Override - synchronized public void close() { + operation.waitForCompletion(); + operation.releaseReference(); + } - if (!isOpen()) { - return; - } + } + + @Override + synchronized public void close() { - writeInterrupted = true; + if (!isOpen()) { + return; + } - PulseAudioMixer parent = PulseAudioMixer.getInstance(); - parent.removeSourceLine(this); + writeInterrupted = true; - super.close(); + PulseAudioMixer parent = PulseAudioMixer.getInstance(); + parent.removeSourceLine(this); + + super.close(); - Debug.println(DebugLevel.Verbose, "PulseAudioSourceDataLine.close():" - + " line closed"); + Debug.println(DebugLevel.Verbose, "PulseAudioSourceDataLine.close():" + + " line closed"); - } + } - @Override - public Line.Info getLineInfo() { - return new DataLine.Info(SourceDataLine.class, supportedFormats, - StreamBufferAttributes.MIN_VALUE, - StreamBufferAttributes.MAX_VALUE); - } + @Override + public Line.Info getLineInfo() { + return new DataLine.Info(SourceDataLine.class, supportedFormats, + StreamBufferAttributes.MIN_VALUE, + StreamBufferAttributes.MAX_VALUE); + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java Wed Jul 06 17:11:34 2011 +0100 @@ -43,53 +43,53 @@ final class PulseAudioSourcePort extends PulseAudioPort { - /* aka mic */ + /* aka mic */ - static { - SecurityWrapper.loadNativeLibrary(); - } + static { + SecurityWrapper.loadNativeLibrary(); + } - PulseAudioSourcePort(String name) { - super(name); - } + PulseAudioSourcePort(String name) { + super(name); + } - public void open() { + public void open() { - /* check for permission to record audio */ - AudioPermission perm = new AudioPermission("record", null); - perm.checkGuard(null); + /* check for permission to record audio */ + AudioPermission perm = new AudioPermission("record", null); + perm.checkGuard(null); - super.open(); + super.open(); - PulseAudioMixer parent = PulseAudioMixer.getInstance(); - parent.addSourceLine(this); - } + PulseAudioMixer parent = PulseAudioMixer.getInstance(); + parent.addSourceLine(this); + } - public void close() { + public void close() { - /* check for permission to record audio */ - AudioPermission perm = new AudioPermission("record", null); - perm.checkGuard(null); + /* check for permission to record audio */ + AudioPermission perm = new AudioPermission("record", null); + perm.checkGuard(null); - if (!isOpen) { - throw new IllegalStateException("Port is not open; so cant close"); - } + if (!isOpen) { + throw new IllegalStateException("Port is not open; so cant close"); + } - PulseAudioMixer parent = PulseAudioMixer.getInstance(); - parent.removeSourceLine(this); + PulseAudioMixer parent = PulseAudioMixer.getInstance(); + parent.removeSourceLine(this); - super.close(); - } + super.close(); + } - // FIXME - public native byte[] native_set_volume(float newValue); + // FIXME + public native byte[] native_set_volume(float newValue); - // FIXME - public native byte[] native_update_volume(); + // FIXME + public native byte[] native_update_volume(); - @Override - public Line.Info getLineInfo() { - return new Port.Info(Port.class, getName(), false); - } + @Override + public Line.Info getLineInfo() { + return new Port.Info(Port.class, getName(), false); + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetDataLine.java Wed Jul 06 17:11:34 2011 +0100 @@ -48,348 +48,374 @@ import org.classpath.icedtea.pulseaudio.Debug.DebugLevel; public final class PulseAudioTargetDataLine extends PulseAudioDataLine - implements TargetDataLine { + implements TargetDataLine { - /* - * This contains the data from the PulseAudio buffer that has since been - * dropped. If 20 bytes of a fragment of size 200 are read, the other 180 - * are dumped in this - */ - private byte[] fragmentBuffer; + /* + * This contains the data from the PulseAudio buffer that has since been + * dropped. If 20 bytes of a fragment of size 200 are read, the other 180 + * are dumped in this + */ + private byte[] fragmentBuffer; - /* - * these are set to true only by the respective functions (flush(), drain()) - * set to false only by read() - */ - private boolean flushed = false; - private boolean drained = false; + /* + * these are set to true only by the respective functions (flush(), drain()) + * set to false only by read() + */ + private boolean flushed = false; + private boolean drained = false; - public static final String DEFAULT_TARGETDATALINE_NAME = "Audio Stream"; + public static final String DEFAULT_TARGETDATALINE_NAME = "Audio Stream"; - PulseAudioTargetDataLine(AudioFormat[] formats, AudioFormat defaultFormat) { - this.supportedFormats = formats; - this.defaultFormat = defaultFormat; - this.currentFormat = defaultFormat; - this.streamName = DEFAULT_TARGETDATALINE_NAME; + PulseAudioTargetDataLine(AudioFormat[] formats, AudioFormat defaultFormat) { + this.supportedFormats = formats; + this.defaultFormat = defaultFormat; + this.currentFormat = defaultFormat; + this.streamName = DEFAULT_TARGETDATALINE_NAME; - } + } - @Override - synchronized public void close() { - if (!isOpen()) { - // Probably due to some programmer error, we are being - // asked to close an already closed line. Oh well. - Debug.println(DebugLevel.Verbose, - "PulseAudioTargetDataLine.close(): " - + "Line closed that wasn't open."); - return; - } + @Override + synchronized public void close() { + if (!isOpen()) { + // Probably due to some programmer error, we are being + // asked to close an already closed line. Oh well. + Debug.println(DebugLevel.Verbose, + "PulseAudioTargetDataLine.close(): " + + "Line closed that wasn't open."); + return; + } - /* check for permission to record audio */ - AudioPermission perm = new AudioPermission("record", null); - perm.checkGuard(null); + /* check for permission to record audio */ + AudioPermission perm = new AudioPermission("record", null); + perm.checkGuard(null); - PulseAudioMixer parentMixer = PulseAudioMixer.getInstance(); - parentMixer.removeTargetLine(this); + PulseAudioMixer parentMixer = PulseAudioMixer.getInstance(); + parentMixer.removeTargetLine(this); - super.close(); + super.close(); - Debug.println(DebugLevel.Verbose, "PulseAudioTargetDataLine.close(): " - + "Line closed"); - } + Debug.println(DebugLevel.Verbose, "PulseAudioTargetDataLine.close(): " + + "Line closed"); + } - @Override - synchronized public void open(AudioFormat format, int bufferSize) - throws LineUnavailableException { - /* check for permission to record audio */ - AudioPermission perm = new AudioPermission("record", null); - perm.checkGuard(null); + @Override + synchronized public void open(AudioFormat format, int bufferSize) + throws LineUnavailableException { + /* check for permission to record audio */ + AudioPermission perm = new AudioPermission("record", null); + perm.checkGuard(null); - if (isOpen()) { - throw new IllegalStateException("already open"); - } - super.open(format, bufferSize); + if (isOpen()) { + throw new IllegalStateException("already open"); + } + super.open(format, bufferSize); - /* initialize all the member variables */ - framesSinceOpen = 0; - fragmentBuffer = null; - flushed = false; - drained = false; + /* initialize all the member variables */ + framesSinceOpen = 0; + fragmentBuffer = null; + flushed = false; + drained = false; - /* add this open line to the mixer */ - PulseAudioMixer parentMixer = PulseAudioMixer.getInstance(); - parentMixer.addTargetLine(this); + /* add this open line to the mixer */ + PulseAudioMixer parentMixer = PulseAudioMixer.getInstance(); + parentMixer.addTargetLine(this); - Debug.println(DebugLevel.Verbose, "PulseAudioTargetDataLine.open(): " - + "Line opened"); - } + Debug.println(DebugLevel.Verbose, "PulseAudioTargetDataLine.open(): " + + "Line opened"); + } - @Override - synchronized public void open(AudioFormat format) - throws LineUnavailableException { - open(format, DEFAULT_BUFFER_SIZE); - } + @Override + synchronized public void open(AudioFormat format) + throws LineUnavailableException { + open(format, DEFAULT_BUFFER_SIZE); + } - @Override - protected void connectLine(int bufferSize, Stream masterStream) - throws LineUnavailableException { - int fragmentSize = bufferSize / 10 > 500 ? bufferSize / 10 : 500; - StreamBufferAttributes bufferAttributes = new StreamBufferAttributes( - bufferSize, 0, 0, 0, fragmentSize); - synchronized (eventLoop.threadLock) { - stream.connectForRecording(Stream.DEFAULT_DEVICE, bufferAttributes); - } - } - - @Override - public int read(byte[] data, int offset, int length) { - - /* check state and inputs */ - - if (!isOpen()) { - // A closed line can produce zero bytes of data. - return 0; - } + @Override + protected void connectLine(int bufferSize, Stream masterStream) + throws LineUnavailableException { + int fs = currentFormat.getFrameSize(); + float fr = currentFormat.getFrameRate(); + int bps = (int)(fs*fr); // bytes per second. - int frameSize = currentFormat.getFrameSize(); - - if (length % frameSize != 0) { - throw new IllegalArgumentException( - "amount of data to read does not represent an integral number of frames"); - } + // if 2 seconds' worth of data can fit in the buffer of the specified + // size, we don't have to adjust the latency. Otherwise we do, so as + // to avoid overruns. + long flags = Stream.FLAG_START_CORKED; + StreamBufferAttributes bufferAttributes; + if (bps*2 < bufferSize) { + // pulse audio completely ignores our fragmentSize attribute unless + // ADJUST_LATENCY is set, so we just leave it at -1. + bufferAttributes = new StreamBufferAttributes(bufferSize, -1, -1, -1, -1); + } else { + flags |= Stream.FLAG_ADJUST_LATENCY; + // in this case, the pulse audio docs: + // http://www.pulseaudio.org/wiki/LatencyControl + // say every field (including bufferSize) must be initialized + // to -1 except fragmentSize. + // XXX: but in my tests, it just sets it to about 4MB, which + // effectively makes it impossible to allocate a small buffer + // and nothing bad happens (yet) when you don't set it to -1 + // so we just leave it at bufferSize. + // XXX: the java api has no way to specify latency, which probably + // means it should be as low as possible. Right now this method's + // primary concern is avoiding dropouts, and if the user-provided + // buffer size is large enough, we leave the latency up to pulse + // audio (which sets it to something extremely high - about 2 + // seconds). We might want to always set a low latency. + int fragmentSize = bufferSize/2; + fragmentSize = Math.max((fragmentSize/fs)*fs, fs); + bufferAttributes = new StreamBufferAttributes(bufferSize, -1, -1, -1, fragmentSize); + } - if (length < 0) { - throw new IllegalArgumentException("length is negative"); - } - - if ( offset < 0 || offset > data.length - length) { - throw new ArrayIndexOutOfBoundsException("array size: " + data.length - + " offset:" + offset + " length:" + length ); - } + synchronized (eventLoop.threadLock) { + stream.connectForRecording(Stream.DEFAULT_DEVICE, flags, bufferAttributes); + } + } - /* everything ok */ + @Override + public int read(byte[] data, int offset, int length) { - int position = offset; - int remainingLength = length; - int sizeRead = 0; + /* check state and inputs */ - /* bytes read on each iteration of loop */ - int bytesRead; + if (!isOpen()) { + // A closed line can produce zero bytes of data. + return 0; + } - flushed = false; - drained = false; - - /* - * to read, we first take stuff from the fragmentBuffer - */ + int frameSize = currentFormat.getFrameSize(); - /* on first read() of the line, fragmentBuffer is null */ - if (fragmentBuffer != null) { - synchronized (this) { + if (length % frameSize != 0) { + throw new IllegalArgumentException( + "amount of data to read does not represent an integral number of frames"); + } - boolean fragmentBufferSmaller = fragmentBuffer.length < length; - int smallerBufferLength = Math.min(fragmentBuffer.length, - length); - System.arraycopy(fragmentBuffer, 0, data, position, - smallerBufferLength); - framesSinceOpen += smallerBufferLength - / currentFormat.getFrameSize(); + if (length < 0) { + throw new IllegalArgumentException("length is negative"); + } + + if ( offset < 0 || offset > data.length - length) { + throw new ArrayIndexOutOfBoundsException("array size: " + data.length + + " offset:" + offset + " length:" + length ); + } + + /* everything ok */ - if (!fragmentBufferSmaller) { - /* - * if fragment was larger, then we already have all the data - * we need. clean up the buffer before returning. Make a new - * fragmentBuffer from the remaining bytes - */ - int remainingBytesInFragment = (fragmentBuffer.length - length); - byte[] newFragmentBuffer = new byte[remainingBytesInFragment]; - System.arraycopy(fragmentBuffer, length, newFragmentBuffer, - 0, newFragmentBuffer.length); - fragmentBuffer = newFragmentBuffer; - return length; - } + int position = offset; + int remainingLength = length; + int sizeRead = 0; + + /* bytes read on each iteration of loop */ + int bytesRead; + + flushed = false; + drained = false; - /* done with fragment buffer, remove it */ - bytesRead = smallerBufferLength; - sizeRead += bytesRead; - position += bytesRead; - remainingLength -= bytesRead; - fragmentBuffer = null; + /* + * to read, we first take stuff from the fragmentBuffer + */ - } - } + /* on first read() of the line, fragmentBuffer is null */ + synchronized (this) { + if (fragmentBuffer != null) { + boolean fragmentBufferSmaller = fragmentBuffer.length < length; + int smallerBufferLength = Math.min(fragmentBuffer.length, + length); + System.arraycopy(fragmentBuffer, 0, data, position, + smallerBufferLength); + framesSinceOpen += smallerBufferLength + / currentFormat.getFrameSize(); - /* - * if we need to read more data, then we read from PulseAudio's buffer - */ - while (remainingLength != 0) { - synchronized (this) { + if (!fragmentBufferSmaller) { + /* + * if fragment was larger, then we already have all the data + * we need. clean up the buffer before returning. Make a new + * fragmentBuffer from the remaining bytes + */ + int remainingBytesInFragment = (fragmentBuffer.length - length); + byte[] newFragmentBuffer = new byte[remainingBytesInFragment]; + System.arraycopy(fragmentBuffer, length, newFragmentBuffer, + 0, newFragmentBuffer.length); + fragmentBuffer = newFragmentBuffer; + return length; + } - if (!isOpen() || !isStarted) { - return sizeRead; - } - - if (flushed) { - flushed = false; - return sizeRead; - } + /* done with fragment buffer, remove it */ + bytesRead = smallerBufferLength; + sizeRead += bytesRead; + position += bytesRead; + remainingLength -= bytesRead; + fragmentBuffer = null; + } + } - if (drained) { - drained = false; - return sizeRead; - } + /* + * if we need to read more data, then we read from PulseAudio's buffer + */ + while (remainingLength != 0) { + synchronized (this) { - byte[] currentFragment; - synchronized (eventLoop.threadLock) { + if (!isOpen() || !isStarted) { + return sizeRead; + } - /* read a fragment, and drop it from the server */ - currentFragment = stream.peek(); + if (flushed) { + flushed = false; + return sizeRead; + } - stream.drop(); - if (currentFragment == null) { - Debug.println(DebugLevel.Verbose, - "PulseAudioTargetDataLine.read(): " - + " error in stream.peek()"); - continue; - } + if (drained) { + drained = false; + return sizeRead; + } + + byte[] currentFragment; + synchronized (eventLoop.threadLock) { - bytesRead = Math.min(currentFragment.length, - remainingLength); + /* read a fragment, and drop it from the server */ + currentFragment = stream.peek(); + + stream.drop(); + if (currentFragment == null) { + Debug.println(DebugLevel.Verbose, + "PulseAudioTargetDataLine.read(): " + + " error in stream.peek()"); + continue; + } - /* - * we read more than we required, save the rest of the data - * in the fragmentBuffer - */ - if (bytesRead < currentFragment.length) { - /* allocate a buffer to store unsaved data */ - fragmentBuffer = new byte[currentFragment.length - - bytesRead]; + bytesRead = Math.min(currentFragment.length, + remainingLength); - /* copy over the unsaved data */ - System.arraycopy(currentFragment, bytesRead, - fragmentBuffer, 0, currentFragment.length - - bytesRead); - } + /* + * we read more than we required, save the rest of the data + * in the fragmentBuffer + */ + if (bytesRead < currentFragment.length) { + /* allocate a buffer to store unsaved data */ + fragmentBuffer = new byte[currentFragment.length + - bytesRead]; - System.arraycopy(currentFragment, 0, data, position, - bytesRead); + /* copy over the unsaved data */ + System.arraycopy(currentFragment, bytesRead, + fragmentBuffer, 0, currentFragment.length + - bytesRead); + } + + System.arraycopy(currentFragment, 0, data, position, + bytesRead); - sizeRead += bytesRead; - position += bytesRead; - remainingLength -= bytesRead; - framesSinceOpen += bytesRead / currentFormat.getFrameSize(); - } - } - } + sizeRead += bytesRead; + position += bytesRead; + remainingLength -= bytesRead; + framesSinceOpen += bytesRead / currentFormat.getFrameSize(); + } + } + } - // all the data should have been played by now - assert (sizeRead == length); + // all the data should have been played by now + assert (sizeRead == length); - return sizeRead; + return sizeRead; - } + } - @Override - public void drain() { + @Override + public void drain() { - // blocks when there is data on the line - // http://www.jsresources.org/faq_audio.html#stop_drain_tdl - while (true) { - synchronized (this) { - if (!isStarted || !isOpen()) { - break; - } - } - try { - //TODO: Is this the best length of sleep? - //Maybe in case this loop runs for a long time - //it would be good to switch to a longer - //sleep. Like bump it up each iteration after - //the Nth iteration, up to a MAXSLEEP length. - Thread.sleep(100); - } catch (InterruptedException e) { - // do nothing - } - } + // blocks when there is data on the line + // http://www.jsresources.org/faq_audio.html#stop_drain_tdl + while (true) { + synchronized (this) { + if (!isStarted || !isOpen()) { + break; + } + } + try { + //TODO: Is this the best length of sleep? + //Maybe in case this loop runs for a long time + //it would be good to switch to a longer + //sleep. Like bump it up each iteration after + //the Nth iteration, up to a MAXSLEEP length. + Thread.sleep(100); + } catch (InterruptedException e) { + // do nothing + } + } - synchronized (this) { - drained = true; - } + synchronized (this) { + drained = true; + } + } - } - - @Override - public void flush() { - if (isOpen()) { + @Override + public synchronized void flush() { + if (isOpen()) { - /* flush the buffer on pulseaudio's side */ - Operation operation; - synchronized (eventLoop.threadLock) { - operation = stream.flush(); - } - operation.waitForCompletion(); - operation.releaseReference(); - } + /* flush the buffer on pulseaudio's side */ + Operation operation; + synchronized (eventLoop.threadLock) { + operation = stream.flush(); + } + operation.waitForCompletion(); + operation.releaseReference(); + } - synchronized (this) { - flushed = true; - /* flush the partial fragment we stored */ - fragmentBuffer = null; - } - } + flushed = true; + /* flush the partial fragment we stored */ + fragmentBuffer = null; + } - @Override - public int available() { - if (!isOpen()) { - // a closed line has 0 bytes available. - return 0; - } + @Override + public int available() { + if (!isOpen()) { + // a closed line has 0 bytes available. + return 0; + } - synchronized (eventLoop.threadLock) { - return stream.getReableSize(); - } - } + synchronized (eventLoop.threadLock) { + return stream.getReableSize(); + } + } - @Override - public int getFramePosition() { - return (int) framesSinceOpen; - } + @Override + public int getFramePosition() { + return (int) framesSinceOpen; + } - @Override - public long getLongFramePosition() { - return framesSinceOpen; - } + @Override + public long getLongFramePosition() { + return framesSinceOpen; + } - @Override - public long getMicrosecondPosition() { - return (long) (framesSinceOpen / currentFormat.getFrameRate()); - } + @Override + public long getMicrosecondPosition() { + return (long) (framesSinceOpen / currentFormat.getFrameRate()); + } - /* - * A TargetData starts when we ask it to and continues playing until we ask - * it to stop. There are no buffer underruns/overflows or anything so we - * will just fire the LineEvents manually - */ + /* + * A TargetData starts when we ask it to and continues playing until we ask + * it to stop. There are no buffer underruns/overflows or anything so we + * will just fire the LineEvents manually + */ - @Override - synchronized public void start() { - super.start(); + @Override + synchronized public void start() { + super.start(); - fireLineEvent(new LineEvent(this, LineEvent.Type.START, framesSinceOpen)); - } + fireLineEvent(new LineEvent(this, LineEvent.Type.START, framesSinceOpen)); + } - @Override - synchronized public void stop() { - super.stop(); + @Override + synchronized public void stop() { + super.stop(); - fireLineEvent(new LineEvent(this, LineEvent.Type.STOP, framesSinceOpen)); - } + fireLineEvent(new LineEvent(this, LineEvent.Type.STOP, framesSinceOpen)); + } - @Override - public Line.Info getLineInfo() { - return new DataLine.Info(TargetDataLine.class, supportedFormats, - StreamBufferAttributes.MIN_VALUE, - StreamBufferAttributes.MAX_VALUE); - } + @Override + public Line.Info getLineInfo() { + return new DataLine.Info(TargetDataLine.class, supportedFormats, + StreamBufferAttributes.MIN_VALUE, + StreamBufferAttributes.MAX_VALUE); + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java Wed Jul 06 17:11:34 2011 +0100 @@ -42,47 +42,47 @@ final class PulseAudioTargetPort extends PulseAudioPort { - /* aka speaker */ + /* aka speaker */ - static { - SecurityWrapper.loadNativeLibrary(); - } + static { + SecurityWrapper.loadNativeLibrary(); + } - PulseAudioTargetPort(String name) { - super(name); - } + PulseAudioTargetPort(String name) { + super(name); + } - @Override - public void open() { + @Override + public void open() { - super.open(); + super.open(); - PulseAudioMixer parent = PulseAudioMixer.getInstance(); - parent.addTargetLine(this); - } + PulseAudioMixer parent = PulseAudioMixer.getInstance(); + parent.addTargetLine(this); + } - @Override - public void close() { + @Override + public void close() { - if (!isOpen) { - throw new IllegalStateException("not open, so cant close Port"); - } + if (!isOpen) { + throw new IllegalStateException("not open, so cant close Port"); + } - PulseAudioMixer parent = PulseAudioMixer.getInstance(); - parent.removeTargetLine(this); + PulseAudioMixer parent = PulseAudioMixer.getInstance(); + parent.removeTargetLine(this); - super.close(); - } + super.close(); + } - // FIXME - public native byte[] native_set_volume(float newValue); + // FIXME + public native byte[] native_set_volume(float newValue); - // FIXME - public native byte[] native_update_volume(); + // FIXME + public native byte[] native_update_volume(); - @Override - public Line.Info getLineInfo() { - return new Port.Info(Port.class, getName(), false); - } + @Override + public Line.Info getLineInfo() { + return new Port.Info(Port.class, getName(), false); + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioVolumeControl.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioVolumeControl.java Wed Jul 06 17:11:34 2011 +0100 @@ -41,61 +41,61 @@ final class PulseAudioVolumeControl extends FloatControl { - static final int MAX_VOLUME = 65536; - static final int MIN_VOLUME = 0; + static final int MAX_VOLUME = 65536; + static final int MIN_VOLUME = 0; - protected PulseAudioVolumeControl(PulseAudioPlaybackLine line, - EventLoop eventLoop) { + protected PulseAudioVolumeControl(PulseAudioPlaybackLine line, + EventLoop eventLoop) { - /* - * the initial volume is ignored by pulseaudio. - */ - super(FloatControl.Type.VOLUME, MIN_VOLUME, MAX_VOLUME, 1, -1, line - .getCachedVolume(), "pulseaudio units", "Volume Off", - "Default Volume", "Full Volume"); - this.line = line; - this.eventLoop = eventLoop; - } + /* + * the initial volume is ignored by pulseaudio. + */ + super(FloatControl.Type.VOLUME, MIN_VOLUME, MAX_VOLUME, 1, -1, line + .getCachedVolume(), "pulseaudio units", "Volume Off", + "Default Volume", "Full Volume"); + this.line = line; + this.eventLoop = eventLoop; + } - private EventLoop eventLoop; - private PulseAudioPlaybackLine line; + private EventLoop eventLoop; + private PulseAudioPlaybackLine line; - @Override - public synchronized void setValue(float newValue) { - if (newValue > MAX_VOLUME || newValue < MIN_VOLUME) { - throw new IllegalArgumentException("invalid value"); - } + @Override + public synchronized void setValue(float newValue) { + if (newValue > MAX_VOLUME || newValue < MIN_VOLUME) { + throw new IllegalArgumentException("invalid value"); + } - if (!line.isOpen()) { - return; - } + if (!line.isOpen()) { + return; + } - setStreamVolume(newValue); + setStreamVolume(newValue); - line.setCachedVolume(newValue); - } + line.setCachedVolume(newValue); + } - protected synchronized void setStreamVolume(float newValue) { - Operation op; - synchronized (eventLoop.threadLock) { - op = new Operation(line.native_set_volume(newValue)); - } + protected synchronized void setStreamVolume(float newValue) { + Operation op; + synchronized (eventLoop.threadLock) { + op = new Operation(line.native_set_volume(newValue)); + } - op.waitForCompletion(); - op.releaseReference(); + op.waitForCompletion(); + op.releaseReference(); - } + } - public synchronized float getValue() { - Operation op; - synchronized (eventLoop.threadLock) { - op = new Operation(line.native_update_volume()); - } + public synchronized float getValue() { + Operation op; + synchronized (eventLoop.threadLock) { + op = new Operation(line.native_update_volume()); + } - op.waitForCompletion(); - op.releaseReference(); + op.waitForCompletion(); + op.releaseReference(); - return line.getCachedVolume(); - } + return line.getCachedVolume(); + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/SecurityWrapper.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/SecurityWrapper.java Wed Jul 06 17:11:34 2011 +0100 @@ -9,23 +9,23 @@ */ final class SecurityWrapper { - static void loadNativeLibrary() { + static void loadNativeLibrary() { - if (System.getSecurityManager() != null) { - PrivilegedAction<Boolean> action = new PrivilegedAction<Boolean>() { - @Override - public Boolean run() { - System.loadLibrary("pulse-java"); - return true; - } + if (System.getSecurityManager() != null) { + PrivilegedAction<Boolean> action = new PrivilegedAction<Boolean>() { + @Override + public Boolean run() { + System.loadLibrary("pulse-java"); + return true; + } - }; + }; - AccessController.doPrivileged(action); + AccessController.doPrivileged(action); - } else { - System.loadLibrary("pulse-java"); - } + } else { + System.loadLibrary("pulse-java"); + } - } + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java Wed Jul 06 17:11:34 2011 +0100 @@ -37,6 +37,7 @@ package org.classpath.icedtea.pulseaudio; +import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -54,742 +55,812 @@ */ final class Stream { - public interface StateListener { - public void update(); - } + public interface StateListener { + public void update(); + } - public interface CorkListener { - public void update(); - } + public interface CorkListener { + public void update(); + } - public interface WriteListener { - public void update(); - } + public interface WriteListener { + public void update(); + } - public interface ReadListener { - public void update(); - } + public interface ReadListener { + public void update(); + } - public interface OverflowListener { - public void update(); - } + public interface OverflowListener { + public void update(); + } - public interface UnderflowListener { - public void update(); - } + public interface UnderflowListener { + public void update(); + } - public interface PlaybackStartedListener { - public void update(); - } + public interface PlaybackStartedListener { + public void update(); + } - public interface LatencyUpdateListener { - public void update(); - } + public interface LatencyUpdateListener { + public void update(); + } - public interface MovedListener { - public void update(); - } + public interface MovedListener { + public void update(); + } - public interface UpdateTimingInfoListener { - public void update(); - } + public interface UpdateTimingInfoListener { + public void update(); + } - public interface SuspendedListener { - public void update(); - } - - public static enum State { - UNCONNECTED, CREATING, READY, FAILED, TERMINATED, - } + public interface SuspendedListener { + public void update(); + } - public static enum Format { - PA_SAMPLE_U8, PA_SAMPLE_ULAW, PA_SAMPLE_ALAW, PA_SAMPLE_S16LE, PA_SAMPLE_S16BE, PA_SAMPLE_FLOAT32LE, PA_SAMPLE_FLOAT32BE, PA_SAMPLE_S32LE, PA_SAMPLE_S32BE - } - - public static final String DEFAULT_DEVICE = null; + // see comments in ContextEvent.java and Operation.java + // These are the possible stream states. + public static long STATE_UNCONNECTED = -1, + STATE_CREATING = -1, + STATE_READY = -1, + STATE_FAILED = -1, + STATE_TERMINATED = -1; - private byte[] streamPointer; - - static { - SecurityWrapper.loadNativeLibrary(); - } + // Throw an IllegalStateException if value is not one of the possible + // states. Otherwise return the input. + public static long checkNativeStreamState(long value) { + if (!Arrays.asList(STATE_UNCONNECTED, STATE_CREATING, + STATE_READY, STATE_FAILED, STATE_TERMINATED + ).contains(value)) { + throw new IllegalStateException("Illegal constant for ContextEvent: " + value); + } + return value; + } - private Format format; - private float cachedVolume; + // These are stream flags. + public static long FLAG_NOFLAGS = -1, + FLAG_START_CORKED = -1, + FLAG_INTERPOLATE_TIMING = -1, + FLAG_NOT_MONOTONIC = -1, + FLAG_AUTO_TIMING_UPDATE = -1, + FLAG_NO_REMAP_CHANNELS = -1, + FLAG_NO_REMIX_CHANNELS = -1, + FLAG_FIX_FORMAT = -1, + FLAG_FIX_RATE = -1, + FLAG_FIX_CHANNELS = -1, + FLAG_DONT_MOVE = -1, + FLAG_VARIABLE_RATE = -1, + FLAG_PEAK_DETECT = -1, + FLAG_START_MUTED = -1, + FLAG_ADJUST_LATENCY = -1, + FLAG_EARLY_REQUESTS = -1, + FLAG_DONT_INHIBIT_AUTO_SUSPEND = -1, + FLAG_START_UNMUTED = -1, + FLAG_FAIL_ON_SUSPEND = -1; - private List<StateListener> stateListeners; - private List<WriteListener> writeListeners; - private List<ReadListener> readListeners; - private List<OverflowListener> overflowListeners; - private List<UnderflowListener> underflowListeners; - private List<PlaybackStartedListener> playbackStartedListeners; - private List<LatencyUpdateListener> latencyUpdateListeners; - private List<MovedListener> movedListeners; - private List<SuspendedListener> suspendedListeners; - private List<CorkListener> corkListeners; - - private native void native_pa_stream_new(byte[] contextPointer, - String name, String format, int sampleRate, int channels); - - private native void native_pa_stream_unref(); - - private native int native_pa_stream_get_state(); - - private native byte[] native_pa_stream_get_context(); - - private native int native_pa_stream_get_index(); + private static native void init_constants(); - private native int native_pa_stream_get_device_index(); - - private native String native_pa_stream_get_device_name(); - - private native int native_pa_stream_is_suspended(); + // We don't change this to static longs like we did with all other pulse + // audio enums mirrored in java because we never use the pulse audio + // integer value of formats on the java side. In java, the handling of + // formats is strictly symbolic and string based. For that, enums are + // better. + public static enum Format { + PA_SAMPLE_U8, + PA_SAMPLE_ULAW, + PA_SAMPLE_ALAW, + PA_SAMPLE_S16LE, + PA_SAMPLE_S16BE, + PA_SAMPLE_FLOAT32LE, + PA_SAMPLE_FLOAT32BE, + PA_SAMPLE_S32LE, + PA_SAMPLE_S32BE + } - private native int native_pa_stream_connect_playback(String name, - int bufferMaxLength, int bufferTargetLength, - int bufferPreBuffering, int bufferMinimumRequest, - int bufferFragmentSize, int flags, byte[] volumePointer, - byte[] sync_streamPointer); + public static final String DEFAULT_DEVICE = null; + + private byte[] streamPointer; - private native int native_pa_stream_connect_record(String name, - int bufferMaxLength, int bufferTargetLength, - int bufferPreBuffering, int bufferMinimumRequest, - int bufferFragmentSize, int flags, byte[] volumePointer, - byte[] sync_streamPointer); - - private native int native_pa_stream_disconnect(); + static { + SecurityWrapper.loadNativeLibrary(); + init_constants(); + } - private native int native_pa_stream_write(byte[] data, int offset, - int length); - - private native byte[] native_pa_stream_peek(); + private Format format; + private float cachedVolume; - private native int native_pa_stream_drop(); - - private native int native_pa_stream_writable_size(); - - private native int native_pa_stream_readable_size(); + private StreamBufferAttributes bufAttr = new StreamBufferAttributes(0,0,0,0,0); + private static final Object bufAttrMutex = new Object(); - private native byte[] native_pa_stream_drain(); - - private native byte[] native_pa_stream_updateTimingInfo(); - - public native int bytesInBuffer(); + private List<StateListener> stateListeners; + private List<WriteListener> writeListeners; + private List<ReadListener> readListeners; + private List<OverflowListener> overflowListeners; + private List<UnderflowListener> underflowListeners; + private List<PlaybackStartedListener> playbackStartedListeners; + private List<LatencyUpdateListener> latencyUpdateListeners; + private List<MovedListener> movedListeners; + private List<SuspendedListener> suspendedListeners; + private List<CorkListener> corkListeners; - /* - * pa_operation pa_stream_update_timing_info (pa_streamp, - * pa_stream_success_cb_t cb, voiduserdata) Request a timing info structure - * update for a stream. - */ + private native void native_pa_stream_new(byte[] contextPointer, + String name, String format, int sampleRate, int channels); + + private native void native_pa_stream_unref(); + + private native long native_pa_stream_get_state(); + + private native byte[] native_pa_stream_get_context(); + + private native int native_pa_stream_get_index(); - private native int native_pa_stream_is_corked(); + private native int native_pa_stream_get_device_index(); + + private native String native_pa_stream_get_device_name(); + + private native int native_pa_stream_is_suspended(); - private native byte[] native_pa_stream_cork(int b); - - private native byte[] native_pa_stream_flush(); + private native int native_pa_stream_connect_playback(String name, + int bufferMaxLength, int bufferTargetLength, + int bufferPreBuffering, int bufferMinimumRequest, + int bufferFragmentSize, long flags, byte[] volumePointer, + byte[] sync_streamPointer); - /* - * pa_operation pa_stream_prebuf (pa_streams, pa_stream_success_cb_t cb, - * voiduserdata) Reenable prebuffering as specified in the pa_buffer_attr - * structure. - */ + private native int native_pa_stream_connect_record(String name, + int bufferMaxLength, int bufferTargetLength, + int bufferPreBuffering, int bufferMinimumRequest, + int bufferFragmentSize, long flags, byte[] volumePointer, + byte[] sync_streamPointer); + + private native int native_pa_stream_disconnect(); - private native byte[] native_pa_stream_trigger(); + private native int native_pa_stream_write(byte[] data, int offset, + int length); - /* returns an operationPointer */ - private native byte[] native_pa_stream_set_name(String name); + private native byte[] native_pa_stream_peek(); - /* Return the current playback/recording time */ - private native long native_pa_stream_get_time(); + private native int native_pa_stream_drop(); - /* Return the total stream latency */ - private native long native_pa_stream_get_latency(); + private native int native_pa_stream_writable_size(); + + private native int native_pa_stream_readable_size(); - /* - * const pa_timing_info pa_stream_get_timing_info (pa_streams) Return the - * latest raw timing data structure. - */ + private native byte[] native_pa_stream_drain(); - private native StreamSampleSpecification native_pa_stream_get_sample_spec(); + private native byte[] native_pa_stream_updateTimingInfo(); + + public native int bytesInBuffer(); - /* - * const pa_channel_map pa_stream_get_channel_map (pa_streams) Return a - * pointer to the stream's channel map. const - */ - private native StreamBufferAttributes native_pa_stream_get_buffer_attr(); + /* + * pa_operation pa_stream_update_timing_info (pa_streamp, + * pa_stream_success_cb_t cb, voiduserdata) Request a timing info structure + * update for a stream. + */ + + private native int native_pa_stream_is_corked(); + + private native byte[] native_pa_stream_cork(int b); - private native byte[] native_pa_stream_set_buffer_attr( - StreamBufferAttributes info); + private native byte[] native_pa_stream_flush(); - private native byte[] native_pa_stream_update_sample_rate(int rate); + /* + * pa_operation pa_stream_prebuf (pa_streams, pa_stream_success_cb_t cb, + * voiduserdata) Reenable prebuffering as specified in the pa_buffer_attr + * structure. + */ - native byte[] native_set_volume(float newValue); - - native byte[] native_update_volume(); + private native byte[] native_pa_stream_trigger(); - /* - * pa_operation pa_stream_proplist_update (pa_streams, pa_update_mode_t - * mode, pa_proplistp, pa_stream_success_cb_t cb, voiduserdata) Update the - * property list of the sink input/source output of this stream, adding new - * entries. pa_operation pa_stream_proplist_remove (pa_streams, const char - * const keys[], pa_stream_success_cb_t cb, voiduserdata) Update the - * property list of the sink input/source output of this stream, remove - * entries. int pa_stream_set_monitor_stream (pa_streams, uint32_t - * sink_input_idx) For record streams connected to a monitor source: monitor - * only a very specific sink input of the sink. uint32_t - * pa_stream_get_monitor_stream (pa_streams) Return what has been set with - * pa_stream_set_monitor_stream() ebfore. - */ + /* returns an operationPointer */ + private native byte[] native_pa_stream_set_name(String name); + + /* Return the current playback/recording time */ + private native long native_pa_stream_get_time(); + + /* Return the total stream latency */ + private native long native_pa_stream_get_latency(); - Stream(byte[] contextPointer, String name, Format format, int sampleRate, - int channels) { - // System.out.println("format: " + format.toString()); + /* + * const pa_timing_info pa_stream_get_timing_info (pa_streams) Return the + * latest raw timing data structure. + */ + + private native StreamSampleSpecification native_pa_stream_get_sample_spec(); + + /* + * const pa_channel_map pa_stream_get_channel_map (pa_streams) Return a + * pointer to the stream's channel map. const + */ + private native StreamBufferAttributes native_pa_stream_get_buffer_attr(); - stateListeners = new LinkedList<StateListener>(); - writeListeners = new LinkedList<WriteListener>(); - readListeners = new LinkedList<ReadListener>(); - overflowListeners = new LinkedList<OverflowListener>(); - underflowListeners = new LinkedList<UnderflowListener>(); - playbackStartedListeners = new LinkedList<PlaybackStartedListener>(); - latencyUpdateListeners = new LinkedList<LatencyUpdateListener>(); - movedListeners = new LinkedList<MovedListener>(); - suspendedListeners = new LinkedList<SuspendedListener>(); - corkListeners = new LinkedList<CorkListener>(); - this.format = format; + private native byte[] native_pa_stream_set_buffer_attr( + StreamBufferAttributes info); + + private native byte[] native_pa_stream_update_sample_rate(int rate); + + native byte[] native_set_volume(float newValue); + + native byte[] native_update_volume(); - StreamSampleSpecification spec = new StreamSampleSpecification(format, - sampleRate, channels); + /* + * pa_operation pa_stream_proplist_update (pa_streams, pa_update_mode_t + * mode, pa_proplistp, pa_stream_success_cb_t cb, voiduserdata) Update the + * property list of the sink input/source output of this stream, adding new + * entries. pa_operation pa_stream_proplist_remove (pa_streams, const char + * const keys[], pa_stream_success_cb_t cb, voiduserdata) Update the + * property list of the sink input/source output of this stream, remove + * entries. int pa_stream_set_monitor_stream (pa_streams, uint32_t + * sink_input_idx) For record streams connected to a monitor source: monitor + * only a very specific sink input of the sink. uint32_t + * pa_stream_get_monitor_stream (pa_streams) Return what has been set with + * pa_stream_set_monitor_stream() ebfore. + */ - native_pa_stream_new(contextPointer, name, spec.getFormat().toString(), - spec.getRate(), spec.getChannels()); - } - - void addStateListener(StateListener listener) { - synchronized (stateListeners) { - stateListeners.add(listener); - } - } + Stream(byte[] contextPointer, String name, Format format, int sampleRate, + int channels) { + // System.out.println("format: " + format.toString()); - void removeStateListener(StateListener listener) { - synchronized (stateListeners) { - stateListeners.remove(listener); - } - - } + stateListeners = new LinkedList<StateListener>(); + writeListeners = new LinkedList<WriteListener>(); + readListeners = new LinkedList<ReadListener>(); + overflowListeners = new LinkedList<OverflowListener>(); + underflowListeners = new LinkedList<UnderflowListener>(); + playbackStartedListeners = new LinkedList<PlaybackStartedListener>(); + latencyUpdateListeners = new LinkedList<LatencyUpdateListener>(); + movedListeners = new LinkedList<MovedListener>(); + suspendedListeners = new LinkedList<SuspendedListener>(); + corkListeners = new LinkedList<CorkListener>(); + this.format = format; - void addWriteListener(WriteListener listener) { - synchronized (writeListeners) { - writeListeners.add(listener); - } - } + StreamSampleSpecification spec = new StreamSampleSpecification(format, + sampleRate, channels); - void removeWriteListener(WriteListener listener) { - synchronized (writeListeners) { - writeListeners.remove(listener); - } - } + native_pa_stream_new(contextPointer, name, spec.getFormat().toString(), + spec.getRate(), spec.getChannels()); + } + + void addStateListener(StateListener listener) { + synchronized (stateListeners) { + stateListeners.add(listener); + } + } - void addReadListener(ReadListener listener) { - synchronized (readListeners) { - readListeners.add(listener); - } - } + void removeStateListener(StateListener listener) { + synchronized (stateListeners) { + stateListeners.remove(listener); + } - void removeReadListener(ReadListener listener) { - synchronized (readListeners) { - readListeners.remove(listener); - } - } + } - void addOverflowListener(OverflowListener listener) { - synchronized (overflowListeners) { - overflowListeners.add(listener); - } - } + void addWriteListener(WriteListener listener) { + synchronized (writeListeners) { + writeListeners.add(listener); + } + } - void removeOverflowListener(OverflowListener listener) { - synchronized (overflowListeners) { - overflowListeners.remove(listener); - } - } + void removeWriteListener(WriteListener listener) { + synchronized (writeListeners) { + writeListeners.remove(listener); + } + } - void addUnderflowListener(UnderflowListener listener) { - synchronized (underflowListeners) { - underflowListeners.add(listener); - } - } + void addReadListener(ReadListener listener) { + synchronized (readListeners) { + readListeners.add(listener); + } + } - void removeUnderflowListener(UnderflowListener listener) { - synchronized (underflowListeners) { - underflowListeners.remove(listener); - } - } + void removeReadListener(ReadListener listener) { + synchronized (readListeners) { + readListeners.remove(listener); + } + } - void addCorkListener(CorkListener listener) { - synchronized (corkListeners) { - corkListeners.add(listener); - } - } + void addOverflowListener(OverflowListener listener) { + synchronized (overflowListeners) { + overflowListeners.add(listener); + } + } - void removeCorkListener(CorkListener listener) { - synchronized (corkListeners) { - corkListeners.remove(listener); - } - } + void removeOverflowListener(OverflowListener listener) { + synchronized (overflowListeners) { + overflowListeners.remove(listener); + } + } - void addPlaybackStartedListener(PlaybackStartedListener listener) { - synchronized (playbackStartedListeners) { - playbackStartedListeners.add(listener); - } - } + void addUnderflowListener(UnderflowListener listener) { + synchronized (underflowListeners) { + underflowListeners.add(listener); + } + } - void removePlaybackStartedListener(PlaybackStartedListener listener) { - synchronized (playbackStartedListeners) { - playbackStartedListeners.remove(listener); - } - } + void removeUnderflowListener(UnderflowListener listener) { + synchronized (underflowListeners) { + underflowListeners.remove(listener); + } + } - void addLatencyUpdateListener(LatencyUpdateListener listener) { - synchronized (latencyUpdateListeners) { - latencyUpdateListeners.add(listener); - } - } + void addCorkListener(CorkListener listener) { + synchronized (corkListeners) { + corkListeners.add(listener); + } + } - void removeLatencyUpdateListener(LatencyUpdateListener listener) { - synchronized (playbackStartedListeners) { - latencyUpdateListeners.remove(listener); - } - } + void removeCorkListener(CorkListener listener) { + synchronized (corkListeners) { + corkListeners.remove(listener); + } + } - void addMovedListener(MovedListener listener) { - synchronized (movedListeners) { - movedListeners.add(listener); - } - } + void addPlaybackStartedListener(PlaybackStartedListener listener) { + synchronized (playbackStartedListeners) { + playbackStartedListeners.add(listener); + } + } - void removeMovedListener(MovedListener listener) { - synchronized (movedListeners) { - movedListeners.remove(listener); - } - } + void removePlaybackStartedListener(PlaybackStartedListener listener) { + synchronized (playbackStartedListeners) { + playbackStartedListeners.remove(listener); + } + } + + void addLatencyUpdateListener(LatencyUpdateListener listener) { + synchronized (latencyUpdateListeners) { + latencyUpdateListeners.add(listener); + } + } - void addSuspendedListener(SuspendedListener listener) { - synchronized (suspendedListeners) { - suspendedListeners.add(listener); - } - } + void removeLatencyUpdateListener(LatencyUpdateListener listener) { + synchronized (playbackStartedListeners) { + latencyUpdateListeners.remove(listener); + } + } - void removeSuspendedListener(SuspendedListener listener) { - synchronized (suspendedListeners) { - suspendedListeners.remove(listener); - } - } + void addMovedListener(MovedListener listener) { + synchronized (movedListeners) { + movedListeners.add(listener); + } + } - Stream.State getState() { - int state = native_pa_stream_get_state(); - switch (state) { - case 0: - return State.UNCONNECTED; - case 1: - return State.CREATING; - case 2: - return State.READY; - case 3: - return State.FAILED; - case 4: - return State.TERMINATED; - default: - throw new IllegalStateException("invalid stream state"); - } + void removeMovedListener(MovedListener listener) { + synchronized (movedListeners) { + movedListeners.remove(listener); + } + } + + void addSuspendedListener(SuspendedListener listener) { + synchronized (suspendedListeners) { + suspendedListeners.add(listener); + } + } - } - - byte[] getContextPointer() { - return native_pa_stream_get_context(); - } + void removeSuspendedListener(SuspendedListener listener) { + synchronized (suspendedListeners) { + suspendedListeners.remove(listener); + } + } - int getSinkInputIndex() { - return native_pa_stream_get_index(); - } + long getState() { + return checkNativeStreamState(native_pa_stream_get_state()); + } - /** - * - * @return the index of the sink or source this stream is connected to in - * the server - */ - int getDeviceIndex() { - return native_pa_stream_get_device_index(); - } + byte[] getContextPointer() { + return native_pa_stream_get_context(); + } + + int getSinkInputIndex() { + return native_pa_stream_get_index(); + } - /** - * - * @return the name of the sink or source this stream is connected to in the - * server - */ - String getDeviceName() { - return native_pa_stream_get_device_name(); - } + /** + * + * @return the index of the sink or source this stream is connected to in + * the server + */ + int getDeviceIndex() { + return native_pa_stream_get_device_index(); + } - /** - * if the sink or source this stream is connected to has been suspended. - * - * @return - */ - boolean isSuspended() { - return (native_pa_stream_is_suspended() != 0); - } + private void setBufAttr() { + synchronized(bufAttrMutex) { + bufAttr = native_pa_stream_get_buffer_attr(); + } + } + + @SuppressWarnings("unused") + private void bufferAttrCallback() { + setBufAttr(); + } - /** - * Connect the stream to a sink - * - * @param deviceName - * the device to connect to. use - * <code>null</code for the default device - * @throws LineUnavailableException - */ - void connectForPlayback(String deviceName, - StreamBufferAttributes bufferAttributes, byte[] syncStreamPointer) - throws LineUnavailableException { + int getBufferSize() { + synchronized (bufAttrMutex) { + return bufAttr.getMaxLength(); + } + } - int returnValue = native_pa_stream_connect_playback(deviceName, - bufferAttributes.getMaxLength(), bufferAttributes - .getTargetLength(), bufferAttributes.getPreBuffering(), - bufferAttributes.getMinimumRequest(), bufferAttributes - .getFragmentSize(), 0, null, syncStreamPointer); - if (returnValue < 0) { - throw new LineUnavailableException( - "Unable To connect a line for playback"); - } - } + /** + * + * @return the name of the sink or source this stream is connected to in the + * server + */ + String getDeviceName() { + return native_pa_stream_get_device_name(); + } + + /** + * if the sink or source this stream is connected to has been suspended. + * + * @return + */ + boolean isSuspended() { + return (native_pa_stream_is_suspended() != 0); + } - /** - * Connect the stream to a source. - * - * @throws LineUnavailableException - * - */ - void connectForRecording(String deviceName, - StreamBufferAttributes bufferAttributes) - throws LineUnavailableException { - - int returnValue = native_pa_stream_connect_record(deviceName, - bufferAttributes.getMaxLength(), bufferAttributes - .getTargetLength(), bufferAttributes.getPreBuffering(), - bufferAttributes.getMinimumRequest(), bufferAttributes - .getFragmentSize(), 0, null, null); - if (returnValue < 0) { - throw new LineUnavailableException( - "Unable to connect line for recording"); - } - } + /** + * Connect the stream to a sink + * + * @param deviceName + * the device to connect to. use + * <code>null</code for the default device + * @throws LineUnavailableException + */ + void connectForPlayback(String deviceName, + StreamBufferAttributes bufferAttributes, byte[] syncStreamPointer) + throws LineUnavailableException { - /** - * Disconnect a stream from a source/sink. - */ - void disconnect() { - int returnValue = native_pa_stream_disconnect(); - assert (returnValue == 0); - } + int returnValue = native_pa_stream_connect_playback( + deviceName, + bufferAttributes.getMaxLength(), + bufferAttributes.getTargetLength(), + bufferAttributes.getPreBuffering(), + bufferAttributes.getMinimumRequest(), + bufferAttributes.getFragmentSize(), + FLAG_START_CORKED, null, syncStreamPointer + ); + if (returnValue < 0) { + throw new LineUnavailableException( + "Unable To connect a line for playback"); + } + } - /** - * Write data to the server - * - * @param data - * @param length - * @return - */ - int write(byte[] data, int offset, int length) { - return native_pa_stream_write(data, offset, length); - } + /** + * Connect the stream to a source. + * + * @throws LineUnavailableException + * + */ + void connectForRecording(String deviceName, long flags, + StreamBufferAttributes bufferAttributes) + throws LineUnavailableException { - /** - * Read the next fragment from the buffer (for recording). - * - * - * @param data - */ - byte[] peek() { - return native_pa_stream_peek(); - } + int returnValue = native_pa_stream_connect_record( + deviceName, + bufferAttributes.getMaxLength(), + bufferAttributes.getTargetLength(), + bufferAttributes.getPreBuffering(), + bufferAttributes.getMinimumRequest(), + bufferAttributes.getFragmentSize(), + flags, null, null + ); + if (returnValue < 0) { + throw new LineUnavailableException( + "Unable to connect line for recording"); + } + } - /** - * - * Remove the current fragment on record streams. - */ - void drop() { - native_pa_stream_drop(); - } + /** + * Disconnect a stream from a source/sink. + */ + void disconnect() { + int returnValue = native_pa_stream_disconnect(); + assert (returnValue == 0); + } - /** - * Return the number of bytes that may be written using write(). - * - * @return - */ - int getWritableSize() { - return native_pa_stream_writable_size(); - } + /** + * Write data to the server + * + * @param data + * @param length + * @return + */ + int write(byte[] data, int offset, int length) { + return native_pa_stream_write(data, offset, length); + } - /** - * Return the number of bytes that may be read using peek(). - * - * @return - */ - int getReableSize() { - return native_pa_stream_readable_size(); - } + /** + * Read the next fragment from the buffer (for recording). + * + * + * @param data + */ + byte[] peek() { + return native_pa_stream_peek(); + } - /** - * Drain a playback stream - * - * @return - */ - Operation drain() { - Operation drainOperation = new Operation(native_pa_stream_drain()); - return drainOperation; - } + /** + * + * Remove the current fragment on record streams. + */ + void drop() { + native_pa_stream_drop(); + } - Operation updateTimingInfo() { - Operation updateOperation = new Operation( - native_pa_stream_updateTimingInfo()); - return updateOperation; - } + /** + * Return the number of bytes that may be written using write(). + * + * @return + */ + int getWritableSize() { + return native_pa_stream_writable_size(); + } - /** - * this function is called whenever the state changes - */ - @SuppressWarnings("unused") - private void stateCallback() { - synchronized (stateListeners) { - for (StateListener listener : stateListeners) { - listener.update(); - } - } - } + /** + * Return the number of bytes that may be read using peek(). + * + * @return + */ + int getReableSize() { + return native_pa_stream_readable_size(); + } - @SuppressWarnings("unused") - private void writeCallback() { - synchronized (writeListeners) { - for (WriteListener listener : writeListeners) { - listener.update(); - } - } - } + /** + * Drain a playback stream + * + * @return + */ + Operation drain() { + Operation drainOperation = new Operation(native_pa_stream_drain()); + return drainOperation; + } + + Operation updateTimingInfo() { + Operation updateOperation = new Operation( + native_pa_stream_updateTimingInfo()); + return updateOperation; + } - @SuppressWarnings("unused") - private void readCallback() { - synchronized (readListeners) { - for (ReadListener listener : readListeners) { - listener.update(); - } - } - } + /** + * this function is called whenever the state changes + */ + @SuppressWarnings("unused") + private void stateCallback() { + synchronized(EventLoop.getEventLoop().threadLock) { + if (getState() == Stream.STATE_READY) { + setBufAttr(); + } + } + synchronized (stateListeners) { + for (StateListener listener : stateListeners) { + listener.update(); + } + } + } - @SuppressWarnings("unused") - private void overflowCallback() { - System.out.println("overflowCallback called"); - synchronized (overflowListeners) { - for (OverflowListener listener : overflowListeners) { - listener.update(); - } - } - } + @SuppressWarnings("unused") + private void writeCallback() { + synchronized (writeListeners) { + for (WriteListener listener : writeListeners) { + listener.update(); + } + } + } - @SuppressWarnings("unused") - private void underflowCallback() { - synchronized (underflowListeners) { - for (UnderflowListener listener : underflowListeners) { - listener.update(); - } - } - } + @SuppressWarnings("unused") + private void readCallback() { + synchronized (readListeners) { + for (ReadListener listener : readListeners) { + listener.update(); + } + } + } - /** - * callback function that is called when a the server starts playback after - * an underrun or on initial startup - */ - @SuppressWarnings("unused") - private void playbackStartedCallback() { - synchronized (playbackStartedListeners) { - for (PlaybackStartedListener listener : playbackStartedListeners) { - listener.update(); - } - } - } + @SuppressWarnings("unused") + private void overflowCallback() { + System.out.println("overflowCallback called"); + synchronized (overflowListeners) { + for (OverflowListener listener : overflowListeners) { + listener.update(); + } + } + } + + @SuppressWarnings("unused") + private void underflowCallback() { + synchronized (underflowListeners) { + for (UnderflowListener listener : underflowListeners) { + listener.update(); + } + } + } - /** - * called whenever a latency information update happens - */ - @SuppressWarnings("unused") - private void latencyUpdateCallback() { - synchronized (latencyUpdateListeners) { - for (LatencyUpdateListener listener : latencyUpdateListeners) { - listener.update(); - } - } - } + /** + * callback function that is called when a the server starts playback after + * an underrun or on initial startup + */ + @SuppressWarnings("unused") + private void playbackStartedCallback() { + synchronized (playbackStartedListeners) { + for (PlaybackStartedListener listener : playbackStartedListeners) { + listener.update(); + } + } + } - /** - * whenever the stream is moved to a different sink/source - */ - @SuppressWarnings("unused") - private void movedCallback() { - synchronized (movedListeners) { - for (MovedListener listener : movedListeners) { - listener.update(); - } - } - } + /** + * called whenever a latency information update happens + */ + @SuppressWarnings("unused") + private void latencyUpdateCallback() { + synchronized (latencyUpdateListeners) { + for (LatencyUpdateListener listener : latencyUpdateListeners) { + listener.update(); + } + } + } - @SuppressWarnings("unused") - private void corkCallback() { - synchronized (corkListeners) { - for (CorkListener listener : corkListeners) { - listener.update(); - } - } - } + /** + * whenever the stream is moved to a different sink/source + */ + @SuppressWarnings("unused") + private void movedCallback() { + synchronized (movedListeners) { + for (MovedListener listener : movedListeners) { + listener.update(); + } + } + } - /** - * whenever the sink/source this stream is connected to is suspended or - * resumed - */ - @SuppressWarnings("unused") - private void suspendedCallback() { - synchronized (suspendedListeners) { - for (SuspendedListener listener : suspendedListeners) { - listener.update(); - } - } - } + @SuppressWarnings("unused") + private void corkCallback() { + synchronized (corkListeners) { + for (CorkListener listener : corkListeners) { + listener.update(); + } + } + } - boolean isCorked() { - int corked = native_pa_stream_is_corked(); - if (corked < 0) { - throw new IllegalStateException("Unable to determine state"); - } - return corked == 0 ? false : true; - } + /** + * whenever the sink/source this stream is connected to is suspended or + * resumed + */ + @SuppressWarnings("unused") + private void suspendedCallback() { + synchronized (suspendedListeners) { + for (SuspendedListener listener : suspendedListeners) { + listener.update(); + } + } + } - /** - * Pause (or resume) playback of this stream temporarily. - * - * @param cork - * @return - */ - Operation cork(boolean cork) { - int yes = cork ? 1 : 0; - Operation corkOperation = new Operation(native_pa_stream_cork(yes)); - return corkOperation; - } + boolean isCorked() { + int corked = native_pa_stream_is_corked(); + if (corked < 0) { + throw new IllegalStateException("Unable to determine state"); + } + return corked == 0 ? false : true; + } - Operation cork() { - return cork(true); - } + /** + * Pause (or resume) playback of this stream temporarily. + * + * @param cork + * @return + */ + Operation cork(boolean cork) { + int yes = cork ? 1 : 0; + Operation corkOperation = new Operation(native_pa_stream_cork(yes)); + return corkOperation; + } - Operation unCork() { - return cork(false); - } + Operation cork() { + return cork(true); + } - /** - * Flush the playback buffer of this stream. - * - * @return - */ - Operation flush() { - Operation flushOperation = new Operation(native_pa_stream_flush()); - return flushOperation; - } + Operation unCork() { + return cork(false); + } - /* - * Operation pa_stream_prebuf (pa_streams, pa_stream_success_cb_t cb, void - * userdata) - * - * Reenable prebuffering as specified in the pa_buffer_attr structure. - */ + /** + * Flush the playback buffer of this stream. + * + * @return + */ + Operation flush() { + Operation flushOperation = new Operation(native_pa_stream_flush()); + return flushOperation; + } + + /* + * Operation pa_stream_prebuf (pa_streams, pa_stream_success_cb_t cb, void + * userdata) + * + * Reenable prebuffering as specified in the pa_buffer_attr structure. + */ - /** - * Request immediate start of playback on this stream. - */ - Operation triggerStart() { - Operation triggerOperation = new Operation(native_pa_stream_trigger()); - return triggerOperation; - } + /** + * Request immediate start of playback on this stream. + */ + Operation triggerStart() { + Operation triggerOperation = new Operation(native_pa_stream_trigger()); + return triggerOperation; + } - /** - * set the stream's name - * - * @param name - * @return - */ - Operation setName(String name) { - Operation setNameOperation = new Operation( - native_pa_stream_set_name(name)); - return setNameOperation; - } + /** + * set the stream's name + * + * @param name + * @return + */ + Operation setName(String name) { + Operation setNameOperation = new Operation( + native_pa_stream_set_name(name)); + return setNameOperation; + } - /** - * - * - * @return a time between ? and ? - */ - long getTime() { - return native_pa_stream_get_time(); - } + /** + * + * + * @return a time between ? and ? + */ + long getTime() { + return native_pa_stream_get_time(); + } - /** - * @return the total stream latency in microseconds - */ - long getLatency() { - return native_pa_stream_get_latency(); - } + /** + * @return the total stream latency in microseconds + */ + long getLatency() { + return native_pa_stream_get_latency(); + } - /* - * const pa_timing_info pa_stream_get_timing_info (pa_streams) Return the - * latest raw timing data structure. - */ + /* + * const pa_timing_info pa_stream_get_timing_info (pa_streams) Return the + * latest raw timing data structure. + */ - Format getFormat() { - return format; - } + Format getFormat() { + return format; + } - /* - * const pa_channel_map pa_stream_get_channel_map (pa_streams) Return a - * pointer to the stream's channel map. - */ + /* + * const pa_channel_map pa_stream_get_channel_map (pa_streams) Return a + * pointer to the stream's channel map. + */ - StreamBufferAttributes getBufferAttributes() { - return native_pa_stream_get_buffer_attr(); - } + StreamBufferAttributes getBufferAttributes() { + return native_pa_stream_get_buffer_attr(); + } - Operation setBufferAtrributes(StreamBufferAttributes attr) { - return new Operation(native_pa_stream_set_buffer_attr(attr)); - } + Operation setBufferAtrributes(StreamBufferAttributes attr) { + return new Operation(native_pa_stream_set_buffer_attr(attr)); + } - /** - * Change the stream sampling rate during playback. - */ - Operation updateSampleRate(int rate) { - return new Operation(native_pa_stream_update_sample_rate(rate)); - } + /** + * Change the stream sampling rate during playback. + */ + Operation updateSampleRate(int rate) { + return new Operation(native_pa_stream_update_sample_rate(rate)); + } - byte[] getStreamPointer() { - return streamPointer; - } + byte[] getStreamPointer() { + return streamPointer; + } - void free() { - native_pa_stream_unref(); - } + void free() { + native_pa_stream_unref(); + } - float getCachedVolume() { - return this.cachedVolume; - } + float getCachedVolume() { + return this.cachedVolume; + } - void setCachedVolume(float volume) { - this.cachedVolume = volume; - } + void setCachedVolume(float volume) { + this.cachedVolume = volume; + } - void update_channels_and_volume(int channels, float volume) { - this.cachedVolume = volume; - } + void update_channels_and_volume(int channels, float volume) { + this.cachedVolume = volume; + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/StreamBufferAttributes.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/StreamBufferAttributes.java Wed Jul 06 17:11:34 2011 +0100 @@ -39,46 +39,46 @@ class StreamBufferAttributes { - public static final int SANE_DEFAULT = 50000; + public static final int SANE_DEFAULT = 50000; - // set these to proper values - // integer.max_value will crash the program! - public static final int MAX_VALUE = 1000000; - public static final int MIN_VALUE = 0; + // set these to proper values + // integer.max_value will crash the program! + public static final int MAX_VALUE = 1000000; + public static final int MIN_VALUE = 0; - private int maxLength; - private int targetLength; - private int preBuffering; - private int minimumRequest; - private int fragmentSize; + private int maxLength; + private int targetLength; + private int preBuffering; + private int minimumRequest; + private int fragmentSize; - StreamBufferAttributes(int maxLength, int targetLength, - int preBuffering, int minimumRequest, int fragmentSize) { - this.maxLength = maxLength; - this.targetLength = targetLength; - this.preBuffering = preBuffering; - this.minimumRequest = minimumRequest; - this.fragmentSize = fragmentSize; - } + StreamBufferAttributes(int maxLength, int targetLength, + int preBuffering, int minimumRequest, int fragmentSize) { + this.maxLength = maxLength; + this.targetLength = targetLength; + this.preBuffering = preBuffering; + this.minimumRequest = minimumRequest; + this.fragmentSize = fragmentSize; + } - int getMaxLength() { - return maxLength; - } + int getMaxLength() { + return maxLength; + } - int getTargetLength() { - return targetLength; - } + int getTargetLength() { + return targetLength; + } - int getPreBuffering() { - return preBuffering; - } + int getPreBuffering() { + return preBuffering; + } - int getMinimumRequest() { - return minimumRequest; - } + int getMinimumRequest() { + return minimumRequest; + } - int getFragmentSize() { - return fragmentSize; - } + int getFragmentSize() { + return fragmentSize; + } }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/StreamSampleSpecification.java Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/StreamSampleSpecification.java Wed Jul 06 17:11:34 2011 +0100 @@ -40,31 +40,31 @@ import org.classpath.icedtea.pulseaudio.Stream.Format; class StreamSampleSpecification { - private Format format; - private int rate; - private int channels; + private Format format; + private int rate; + private int channels; - public StreamSampleSpecification(Format format, int rate, int channels) { - this.format = format; - this.rate = rate; - this.channels = channels; - } + public StreamSampleSpecification(Format format, int rate, int channels) { + this.format = format; + this.rate = rate; + this.channels = channels; + } - public StreamSampleSpecification(String format, int rate, int channels) { - this.format = Format.valueOf(format); - this.rate = rate; - this.channels = channels; - } + public StreamSampleSpecification(String format, int rate, int channels) { + this.format = Format.valueOf(format); + this.rate = rate; + this.channels = channels; + } - public Format getFormat() { - return format; - } + public Format getFormat() { + return format; + } - public int getRate() { - return rate; - } + public int getRate() { + return rate; + } - public int getChannels() { - return channels; - } + public int getChannels() { + return channels; + } } \ No newline at end of file
--- a/pulseaudio/src/native/jni-common.c Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/native/jni-common.c Wed Jul 06 17:11:34 2011 +0100 @@ -44,193 +44,193 @@ * Throw an exception by name */ void throwByName(JNIEnv* env, const char* name, const char* msg) { - jclass cls = (*env)->FindClass(env, name); - if (cls != NULL) { - (*env)->ThrowNew(env, cls, msg); - return; - } + jclass cls = (*env)->FindClass(env, name); + if (cls != NULL) { + (*env)->ThrowNew(env, cls, msg); + return; + } } jint getJavaIntField(JNIEnv* env, jobject obj, char* fieldName) { - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "I"); - assert(fid); - jint value = (*env)->GetIntField(env, obj, fid); - return value; + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "I"); + assert(fid); + jint value = (*env)->GetIntField(env, obj, fid); + return value; } void setJavaIntField(JNIEnv *env, jobject obj, char *fieldName, jint value) { - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - jfieldID fid =(*env)->GetFieldID(env, cls, fieldName, "I"); - assert(fid); - (*env)->SetIntField(env, obj, fid, value); + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + jfieldID fid =(*env)->GetFieldID(env, cls, fieldName, "I"); + assert(fid); + (*env)->SetIntField(env, obj, fid, value); } jlong getJavaLongField(JNIEnv* env, jobject obj, char* name) { - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - jfieldID fid = (*env)->GetFieldID(env, cls, name, "J"); - assert(fid); - jint value = (*env)->GetLongField(env, obj, fid); - return value; + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + jfieldID fid = (*env)->GetFieldID(env, cls, name, "J"); + assert(fid); + jint value = (*env)->GetLongField(env, obj, fid); + return value; } void setJavaLongField(JNIEnv* env, jobject obj, char* name, jlong value) { - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - jfieldID fid =(*env)->GetFieldID(env, cls, name, "J"); - assert(fid); - (*env)->SetLongField(env, obj, fid, value); + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + jfieldID fid =(*env)->GetFieldID(env, cls, name, "J"); + assert(fid); + (*env)->SetLongField(env, obj, fid, value); } jbyteArray getJavaByteArrayField(JNIEnv* env, jobject obj, char* name) { - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - jfieldID fid = (*env)->GetFieldID(env, cls, name, "[B"); - assert(fid); - jbyteArray array = (*env)->GetObjectField(env, obj, fid); - assert(array); - return array; + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + jfieldID fid = (*env)->GetFieldID(env, cls, name, "[B"); + assert(fid); + jbyteArray array = (*env)->GetObjectField(env, obj, fid); + assert(array); + return array; } void setJavaByteArrayField(JNIEnv* env, jobject obj, char* name, - jbyteArray array) { + jbyteArray array) { - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - jfieldID fid = (*env)->GetFieldID(env, cls, name, "[B"); - assert(fid); + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + jfieldID fid = (*env)->GetFieldID(env, cls, name, "[B"); + assert(fid); - (*env)->SetObjectField(env, obj, fid, array); - return; + (*env)->SetObjectField(env, obj, fid, array); + return; } void callJavaVoidMethod(JNIEnv* env, jobject obj, const char* method_name) { - jclass cls = (*env)->GetObjectClass(env, obj); - if (cls == NULL) { - printf("unable to get class of object"); - return; - } - jmethodID mid = (*env)->GetMethodID(env, cls, method_name, "()V"); - if (mid == NULL) { - printf("unable to get method %s\n", method_name); - return; + jclass cls = (*env)->GetObjectClass(env, obj); + if (cls == NULL) { + printf("unable to get class of object"); + return; + } + jmethodID mid = (*env)->GetMethodID(env, cls, method_name, "()V"); + if (mid == NULL) { + printf("unable to get method %s\n", method_name); + return; - } - (*env)->CallVoidMethod(env, obj, mid); + } + (*env)->CallVoidMethod(env, obj, mid); - return; + return; } jobject getLockObject(JNIEnv* env) { - const char* eventLoopClassName = - "org/classpath/icedtea/pulseaudio/EventLoop"; + const char* eventLoopClassName = + "org/classpath/icedtea/pulseaudio/EventLoop"; - jclass eventLoopClass = (*env)->FindClass(env, eventLoopClassName); - assert(eventLoopClass); + jclass eventLoopClass = (*env)->FindClass(env, eventLoopClassName); + assert(eventLoopClass); - const char* getEventLoopIDSignature = - "()Lorg/classpath/icedtea/pulseaudio/EventLoop;"; - jmethodID getEventLoopID = (*env)->GetStaticMethodID(env, eventLoopClass, "getEventLoop", - getEventLoopIDSignature); - assert(getEventLoopID); + const char* getEventLoopIDSignature = + "()Lorg/classpath/icedtea/pulseaudio/EventLoop;"; + jmethodID getEventLoopID = (*env)->GetStaticMethodID(env, eventLoopClass, "getEventLoop", + getEventLoopIDSignature); + assert(getEventLoopID); - jobject eventLoop = (*env)->CallStaticObjectMethod(env, eventLoopClass, getEventLoopID); - assert(eventLoop); + jobject eventLoop = (*env)->CallStaticObjectMethod(env, eventLoopClass, getEventLoopID); + assert(eventLoop); - jfieldID lockID = (*env)->GetFieldID(env, eventLoopClass, "threadLock", - "Ljava/lang/Object;"); - assert(lockID); + jfieldID lockID = (*env)->GetFieldID(env, eventLoopClass, "threadLock", + "Ljava/lang/Object;"); + assert(lockID); - jobject lockObject = (*env)->GetObjectField(env, eventLoop, lockID); - assert(lockObject); - return lockObject; + jobject lockObject = (*env)->GetObjectField(env, eventLoop, lockID); + assert(lockObject); + return lockObject; } void notifyWaitingOperations(JNIEnv* env) { - jobject lockObject = getLockObject(env); + jobject lockObject = getLockObject(env); - (*env)->MonitorEnter(env, lockObject); + (*env)->MonitorEnter(env, lockObject); - jclass objectClass = (*env)->FindClass(env, "java/lang/Object"); - assert(objectClass); - jmethodID notifyAllID = (*env)->GetMethodID(env, objectClass, "notifyAll", "()V"); - assert(notifyAllID); + jclass objectClass = (*env)->FindClass(env, "java/lang/Object"); + assert(objectClass); + jmethodID notifyAllID = (*env)->GetMethodID(env, objectClass, "notifyAll", "()V"); + assert(notifyAllID); - (*env)->CallObjectMethod(env, lockObject, notifyAllID); + (*env)->CallObjectMethod(env, lockObject, notifyAllID); - (*env)->MonitorExit(env, lockObject); + (*env)->MonitorExit(env, lockObject); } void* getJavaPointer(JNIEnv* env, jobject obj, char* name) { - jbyteArray array = getJavaByteArrayField(env, obj, name); - assert(array); - void* value = convertJavaPointerToNative(env, array); - // allow returning NULL values - return value; + jbyteArray array = getJavaByteArrayField(env, obj, name); + assert(array); + void* value = convertJavaPointerToNative(env, array); + // allow returning NULL values + return value; } void setJavaPointer(JNIEnv* env, jobject obj, char* name, void* value) { - // allow NULL for value - jbyteArray array = convertNativePointerToJava(env, value); - assert(array); - setJavaByteArrayField(env, obj, name, array); - return; + // allow NULL for value + jbyteArray array = convertNativePointerToJava(env, value); + assert(array); + setJavaByteArrayField(env, obj, name, array); + return; } void* convertJavaPointerToNative(JNIEnv* env, jbyteArray pointer) { - // printf("convertJavaPointerToNative(): entering method\n"); + // printf("convertJavaPointerToNative(): entering method\n"); - void* returnPointer = NULL; + void* returnPointer = NULL; - // this is not the pointer, but the container of the pointer - assert(pointer); + // this is not the pointer, but the container of the pointer + assert(pointer); - jsize len = (*env)->GetArrayLength(env, pointer); - assert(len); - assert(len == sizeof(returnPointer)); + jsize len = (*env)->GetArrayLength(env, pointer); + assert(len); + assert(len == sizeof(returnPointer)); - jbyte* data = (*env)->GetByteArrayElements(env, pointer, NULL); - if (data == NULL) { - return NULL; // oome; - } - memcpy(&returnPointer, data, sizeof(returnPointer)); - (*env)->ReleaseByteArrayElements(env, pointer, data, 0); + jbyte* data = (*env)->GetByteArrayElements(env, pointer, NULL); + if (data == NULL) { + return NULL; // oome; + } + memcpy(&returnPointer, data, sizeof(returnPointer)); + (*env)->ReleaseByteArrayElements(env, pointer, data, 0); - // printf("convertJavaPointerToNative(): leaving method\n"); - return returnPointer; + // printf("convertJavaPointerToNative(): leaving method\n"); + return returnPointer; } jbyteArray convertNativePointerToJava(JNIEnv* env, void* pointer) { - // printf("convertNativePointerToJava(): entering method\n"); + // printf("convertNativePointerToJava(): entering method\n"); - jbyteArray array = (*env)->NewByteArray(env, sizeof(pointer)); - if (array == NULL) { - return 0; // oome? - } + jbyteArray array = (*env)->NewByteArray(env, sizeof(pointer)); + if (array == NULL) { + return 0; // oome? + } - jbyte* data = (*env)->GetByteArrayElements(env, array, NULL); - if (data == NULL) { - return 0; // oome - } + jbyte* data = (*env)->GetByteArrayElements(env, array, NULL); + if (data == NULL) { + return 0; // oome + } - memcpy(data, &pointer, sizeof(pointer)); - (*env)->ReleaseByteArrayElements(env, array, data, 0); + memcpy(data, &pointer, sizeof(pointer)); + (*env)->ReleaseByteArrayElements(env, array, data, 0); - // printf("convertNativePointerToJava(): leaving method\n"); + // printf("convertNativePointerToJava(): leaving method\n"); - return array; + return array; }
--- a/pulseaudio/src/native/jni-common.h Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/native/jni-common.h Wed Jul 06 17:11:34 2011 +0100 @@ -39,20 +39,30 @@ #define _JNI_COMMON_H #include <jni.h> + /* - * This file contains some commonly used functions - * + * This file contains some commonly used functions + * */ +// Sets the field with name field_name from jclass clz to pa_prefix_field_name. +#define SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, java_prefix, pa_prefix, name) \ + do { \ + char *java_full_name = #java_prefix #name; \ + jfieldID fid = (*env)->GetStaticFieldID(env, clz, java_full_name, "J"); \ + assert(fid); \ + (*env)->SetStaticLongField(env, clz, fid, PA_##pa_prefix##_##name); \ + } while(0); + typedef struct java_context_t { - JNIEnv* env; - jobject obj; + JNIEnv* env; + jobject obj; } java_context_t; /* Exception Handling */ void throwByName(JNIEnv* const env, const char* const name, - const char* const msg); + const char* const msg); #define ILLEGAL_ARGUMENT_EXCEPTION "java/lang/IllegalArgumentException" #define ILLEGAL_STATE_EXCEPTION "java/lang/IllegalStateException" @@ -72,7 +82,7 @@ jbyteArray getJavaByteArrayField(JNIEnv* env, jobject obj, char* name); void setJavaByteArrayField(JNIEnv* env, jobject obj, char* name, - jbyteArray array); + jbyteArray array); /* Pointers and Java */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_ContextEvent.c Wed Jul 06 17:11:34 2011 +0100 @@ -0,0 +1,63 @@ +/* org_classpath_icedtea_pulseaudio_EventLoop.c + Copyright (C) 2011 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ + +#include <pulse/pulseaudio.h> + +#include "org_classpath_icedtea_pulseaudio_ContextEvent.h" +#include "jni-common.h" + +// we don't prefix the java names with anything, so we leave the third argument +// empty +#define SET_CONTEXT_ENUM(env, clz, name) \ + SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, , CONTEXT, name) + +/* + * Class: org_classpath_icedtea_pulseaudio_ContextEvent + * Method: init_constants + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_ContextEvent_init_1constants + (JNIEnv *env, jclass clz) { + SET_CONTEXT_ENUM(env, clz, UNCONNECTED); + SET_CONTEXT_ENUM(env, clz, CONNECTING); + SET_CONTEXT_ENUM(env, clz, AUTHORIZING); + SET_CONTEXT_ENUM(env, clz, SETTING_NAME); + SET_CONTEXT_ENUM(env, clz, READY); + SET_CONTEXT_ENUM(env, clz, FAILED); + SET_CONTEXT_ENUM(env, clz, TERMINATED); +} +
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c Wed Jul 06 17:11:34 2011 +0100 @@ -50,82 +50,82 @@ JNIEnv* pulse_thread_env = NULL; void sink_list_success_cb(pa_context *context, const pa_sink_info *i, int eol, - void *userdata) { + void *userdata) { - if (eol == 0) { - jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, - java_context->obj); - assert(cls); - jstring name = (*pulse_thread_env)->NewStringUTF(pulse_thread_env, i->name); - assert(name); - jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls, - "sink_callback", "(Ljava/lang/String;)V"); - assert(mid1); - (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, - java_context->obj, mid1, name) ; - } else { - assert(pulse_thread_env); - notifyWaitingOperations(pulse_thread_env); - } + if (eol == 0) { + jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, + java_context->obj); + assert(cls); + jstring name = (*pulse_thread_env)->NewStringUTF(pulse_thread_env, i->name); + assert(name); + jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls, + "sink_callback", "(Ljava/lang/String;)V"); + assert(mid1); + (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, + java_context->obj, mid1, name) ; + } else { + assert(pulse_thread_env); + notifyWaitingOperations(pulse_thread_env); + } } void source_list_success_cb(pa_context *context, const pa_source_info *i, - int eol, void *userdata) { + int eol, void *userdata) { - if (eol == 0) { - jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, - java_context->obj); - assert(cls); - jstring name = (*pulse_thread_env)->NewStringUTF(pulse_thread_env, i->name); - assert(name); - jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls, - "source_callback", "(Ljava/lang/String;)V"); - assert(mid1); - (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, - java_context->obj, mid1, name) ; - } else { - assert(pulse_thread_env); - notifyWaitingOperations(pulse_thread_env); - } + if (eol == 0) { + jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, + java_context->obj); + assert(cls); + jstring name = (*pulse_thread_env)->NewStringUTF(pulse_thread_env, i->name); + assert(name); + jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls, + "source_callback", "(Ljava/lang/String;)V"); + assert(mid1); + (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, + java_context->obj, mid1, name) ; + } else { + assert(pulse_thread_env); + notifyWaitingOperations(pulse_thread_env); + } } static void context_change_callback(pa_context* context, void* userdata) { - assert(context); - assert(userdata == NULL); + assert(context); + assert(userdata == NULL); - //java_context_t* java_context = (java_context_t*)userdata; - JNIEnv* env = java_context->env; - jobject obj = java_context->obj; + //java_context_t* java_context = (java_context_t*)userdata; + JNIEnv* env = java_context->env; + jobject obj = java_context->obj; - // printf("context state changed to %d\n", pa_context_get_state(context)); + // printf("context state changed to %d\n", pa_context_get_state(context)); - /* Call the EventLoop.update method in java - * to handle all java-side events - */ - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - jmethodID mid = (*env)->GetMethodID(env, cls, "update", "(I)V"); - assert(mid); - (*env)->CallVoidMethod(env, obj, mid, pa_context_get_state(context)); - return; + /* Call the EventLoop.update method in java + * to handle all java-side events + */ + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + jmethodID mid = (*env)->GetMethodID(env, cls, "update", "(J)V"); + assert(mid); + (*env)->CallVoidMethod(env, obj, mid, pa_context_get_state(context)); + return; } static int poll_function(struct pollfd *ufds, unsigned long nfds, int timeout, - void *userdata) { + void *userdata) { - JNIEnv* env = pulse_thread_env; - assert(env); - jobject lockObject = getLockObject(env); + JNIEnv* env = pulse_thread_env; + assert(env); + jobject lockObject = getLockObject(env); - (*env)->MonitorExit(env, lockObject); + (*env)->MonitorExit(env, lockObject); - int value = poll(ufds, nfds, timeout); + int value = poll(ufds, nfds, timeout); - (*env)->MonitorEnter(env, lockObject); - return value; + (*env)->MonitorEnter(env, lockObject); + return value; } /* @@ -136,62 +136,62 @@ JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_EventLoop_native_1setup (JNIEnv* env, jobject obj, jstring appName, jstring server) { - assert(appName != NULL); + assert(appName != NULL); - // printf("native_setup() called\n"); - pa_mainloop *mainloop = pa_mainloop_new(); - assert(mainloop != NULL); - pa_mainloop_api *mainloop_api = pa_mainloop_get_api(mainloop); - assert(mainloop != NULL); + // printf("native_setup() called\n"); + pa_mainloop *mainloop = pa_mainloop_new(); + assert(mainloop != NULL); + pa_mainloop_api *mainloop_api = pa_mainloop_get_api(mainloop); + assert(mainloop != NULL); - pa_context *context = NULL; + pa_context *context = NULL; - const char* string_appName; - string_appName = (*env)->GetStringUTFChars(env, appName, NULL); - if (string_appName == NULL) { - return; /* a OutOfMemoryError thrown by vm */ - } - // printf("using appName : %s\n", string_appName); - context = pa_context_new(mainloop_api, string_appName); - assert(mainloop != NULL); - (*env)->ReleaseStringUTFChars(env, appName, string_appName); + const char* string_appName; + string_appName = (*env)->GetStringUTFChars(env, appName, NULL); + if (string_appName == NULL) { + return; /* a OutOfMemoryError thrown by vm */ + } + // printf("using appName : %s\n", string_appName); + context = pa_context_new(mainloop_api, string_appName); + assert(mainloop != NULL); + (*env)->ReleaseStringUTFChars(env, appName, string_appName); - obj = (*env)->NewGlobalRef(env, obj); + obj = (*env)->NewGlobalRef(env, obj); - java_context = malloc(sizeof(java_context_t)); - java_context->env = env; - pulse_thread_env = env; - java_context->obj = obj; + java_context = malloc(sizeof(java_context_t)); + java_context->env = env; + pulse_thread_env = env; + java_context->obj = obj; - pa_context_set_state_callback(context, context_change_callback, NULL); + pa_context_set_state_callback(context, context_change_callback, NULL); - if (server != NULL) { - /* obtain the server from the caller */ - const char* string_server = NULL; - string_server = (*env)->GetStringUTFChars(env, server, NULL); - if (string_server == NULL) { - /* error, so clean up */ - (*env)->DeleteGlobalRef(env, java_context->obj); - pa_context_disconnect(context); - pa_mainloop_free(mainloop); - free(java_context); - return; /* OutOfMemoryError */ - } - // printf("About to connect to server: %s\n", string_server); - pa_context_connect(context, string_server, 0, NULL); - (*env)->ReleaseStringUTFChars(env, appName, string_server); - } else { - // printf("using default server\n"); - pa_context_connect(context, NULL, 0, NULL); - } + if (server != NULL) { + /* obtain the server from the caller */ + const char* string_server = NULL; + string_server = (*env)->GetStringUTFChars(env, server, NULL); + if (string_server == NULL) { + /* error, so clean up */ + (*env)->DeleteGlobalRef(env, java_context->obj); + pa_context_disconnect(context); + pa_mainloop_free(mainloop); + free(java_context); + return; /* OutOfMemoryError */ + } + // printf("About to connect to server: %s\n", string_server); + pa_context_connect(context, string_server, 0, NULL); + (*env)->ReleaseStringUTFChars(env, appName, string_server); + } else { + // printf("using default server\n"); + pa_context_connect(context, NULL, 0, NULL); + } - // set polling function - pa_mainloop_set_poll_func(mainloop, poll_function, NULL); + // set polling function + pa_mainloop_set_poll_func(mainloop, poll_function, NULL); - setJavaPointer(env, obj, "mainloopPointer", mainloop); - setJavaPointer(env, obj, "contextPointer", context); - // printf("native_setup() returning\n"); - return; + setJavaPointer(env, obj, "mainloopPointer", mainloop); + setJavaPointer(env, obj, "contextPointer", context); + // printf("native_setup() returning\n"); + return; } /* @@ -202,24 +202,24 @@ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_EventLoop_native_1iterate (JNIEnv* env, jobject obj, jint timeout) { - pa_mainloop* mainloop = (pa_mainloop*) getJavaPointer(env, obj, "mainloopPointer"); - assert(mainloop); + pa_mainloop* mainloop = (pa_mainloop*) getJavaPointer(env, obj, "mainloopPointer"); + assert(mainloop); - int returnval; + int returnval; - returnval = pa_mainloop_prepare(mainloop, timeout); - if ( returnval < 0) { - return -1; - } - returnval = pa_mainloop_poll(mainloop); - if ( returnval < 0) { - return -1; - } - returnval = pa_mainloop_dispatch(mainloop); - if ( returnval < 0) { - return -1; - } - return returnval; + returnval = pa_mainloop_prepare(mainloop, timeout); + if ( returnval < 0) { + return -1; + } + returnval = pa_mainloop_poll(mainloop); + if ( returnval < 0) { + return -1; + } + returnval = pa_mainloop_dispatch(mainloop); + if ( returnval < 0) { + return -1; + } + return returnval; } @@ -231,11 +231,11 @@ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_EventLoop_nativeUpdateTargetPortNameList (JNIEnv* env, jobject obj) { - pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); - assert(context); - pa_operation *o = pa_context_get_sink_info_list(context, sink_list_success_cb, NULL); - assert(o); - return convertNativePointerToJava(env, o); + pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); + assert(context); + pa_operation *o = pa_context_get_sink_info_list(context, sink_list_success_cb, NULL); + assert(o); + return convertNativePointerToJava(env, o); } @@ -246,15 +246,15 @@ */ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_EventLoop_nativeUpdateSourcePortNameList (JNIEnv * env, jobject obj) { - pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); - assert(context); - pa_operation *o = pa_context_get_source_info_list(context, source_list_success_cb, NULL); - assert(o); - return convertNativePointerToJava(env, o); + pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); + assert(context); + pa_operation *o = pa_context_get_source_info_list(context, source_list_success_cb, NULL); + assert(o); + return convertNativePointerToJava(env, o); } static void context_drain_complete_callback(pa_context* context, void* userdata) { - pa_context_disconnect(context); + pa_context_disconnect(context); } @@ -266,32 +266,32 @@ JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_EventLoop_native_1shutdown (JNIEnv *env, jobject obj) { - // printf("native_shutdown() starting\n"); + // printf("native_shutdown() starting\n"); - pa_mainloop* mainloop = (pa_mainloop*) getJavaPointer(env, obj, "mainloopPointer"); - assert(mainloop != NULL); + pa_mainloop* mainloop = (pa_mainloop*) getJavaPointer(env, obj, "mainloopPointer"); + assert(mainloop != NULL); - pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); - assert(context != NULL); + pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); + assert(context != NULL); - pa_operation* o = pa_context_drain(context, context_drain_complete_callback, NULL); - if ( o == NULL) { - pa_context_disconnect(context); - pa_mainloop_free(mainloop); - } else { - pa_operation_unref(o); - } - - pa_context_unref(context); - (*env)->DeleteGlobalRef(env, java_context->obj); + pa_operation* o = pa_context_drain(context, context_drain_complete_callback, NULL); + if ( o == NULL) { + pa_context_disconnect(context); + pa_mainloop_free(mainloop); + } else { + pa_operation_unref(o); + } - free(java_context); - java_context = NULL; + pa_context_unref(context); + (*env)->DeleteGlobalRef(env, java_context->obj); - setJavaPointer(env, obj, "mainloopPointer", NULL); - setJavaPointer(env, obj, "contextPointer", NULL); + free(java_context); + java_context = NULL; - // printf("native_shutdown() returning\n"); + setJavaPointer(env, obj, "mainloopPointer", NULL); + setJavaPointer(env, obj, "contextPointer", NULL); + + // printf("native_shutdown() returning\n"); }
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Operation.c Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Operation.c Wed Jul 06 17:11:34 2011 +0100 @@ -40,6 +40,24 @@ #include "jni-common.h" #include <pulse/pulseaudio.h> +// we don't prefix the java names with anything, so we leave the third argument +// empty +#define SET_OP_ENUM(env, clz, name) \ + SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, , OPERATION, name) + +/* + * Class: org_classpath_icedtea_pulseaudio_Operation + * Method: init_constants + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Operation_init_1constants + (JNIEnv *env, jclass clz) { + SET_OP_ENUM(env, clz, RUNNING); + SET_OP_ENUM(env, clz, DONE); + SET_OP_ENUM(env, clz, CANCELLED); +} + + /* * Class: org_classpath_icedtea_pulseaudio_Operation * Method: native_ref @@ -48,9 +66,9 @@ JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Operation_native_1ref (JNIEnv* env, jobject obj) { - pa_operation* operation = (pa_operation*) getJavaPointer(env, obj, "operationPointer"); - assert(operation); - pa_operation_ref(operation); + pa_operation* operation = (pa_operation*) getJavaPointer(env, obj, "operationPointer"); + assert(operation); + pa_operation_ref(operation); } @@ -62,10 +80,9 @@ JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Operation_native_1unref (JNIEnv* env, jobject obj) { - pa_operation* operation = (pa_operation*) getJavaPointer(env, obj, "operationPointer"); - assert(operation); - pa_operation_unref(operation); - + pa_operation* operation = (pa_operation*) getJavaPointer(env, obj, "operationPointer"); + assert(operation); + pa_operation_unref(operation); } /* @@ -73,11 +90,11 @@ * Method: native_get_state * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Operation_native_1get_1state +JNIEXPORT jlong JNICALL Java_org_classpath_icedtea_pulseaudio_Operation_native_1get_1state (JNIEnv *env, jobject obj) { - pa_operation* operation = (pa_operation*) getJavaPointer(env, obj, "operationPointer"); - assert(operation); - int state = pa_operation_get_state(operation); - return state; + pa_operation* operation = (pa_operation*) getJavaPointer(env, obj, "operationPointer"); + assert(operation); + jlong state = pa_operation_get_state(operation); + return state; }
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourcePort.c Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourcePort.c Wed Jul 06 17:11:34 2011 +0100 @@ -4,37 +4,37 @@ #include <string.h> typedef struct java_context { - JNIEnv* env; - jobject obj; + JNIEnv* env; + jobject obj; } java_context; extern JNIEnv* pulse_thread_env; void source_callback(pa_context *context, int success, void *userdata) { - assert(context); - assert(pulse_thread_env); - notifyWaitingOperations(pulse_thread_env); + assert(context); + assert(pulse_thread_env); + notifyWaitingOperations(pulse_thread_env); } void get_source_volume_callback(pa_context *context, const pa_source_info *i, - int eol, void *userdata) { - assert(context); - assert(pulse_thread_env); - - if (eol == 0) { - // printf("%s\n", i->name); - jobject obj = (jobject) userdata; - assert(obj); - jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj); - assert(cls); - jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls, - "update_channels_and_volume", "(IF)V"); - assert(mid1); - (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, obj, mid1, - (int) (i->volume).channels, (float) (i->volume).values[0]) ; - } else { - notifyWaitingOperations(pulse_thread_env); - } + int eol, void *userdata) { + assert(context); + assert(pulse_thread_env); + + if (eol == 0) { + // printf("%s\n", i->name); + jobject obj = (jobject) userdata; + assert(obj); + jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj); + assert(cls); + jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls, + "update_channels_and_volume", "(IF)V"); + assert(mid1); + (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, obj, mid1, + (int) (i->volume).channels, (float) (i->volume).values[0]) ; + } else { + notifyWaitingOperations(pulse_thread_env); + } } /* @@ -44,23 +44,23 @@ */ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1update_1volume (JNIEnv *env, jobject obj) { - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - jfieldID fid = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;"); - assert(fid); - jstring jstr = (*env)->GetObjectField(env, obj, fid); - assert(jstr); - const char *name = (*env)->GetStringUTFChars(env, jstr, NULL); - if (name == NULL) { - return NULL; // oome - } - - pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); - assert(context); - obj = (*env)->NewGlobalRef(env, obj); - pa_operation *o = pa_context_get_source_info_by_name (context, (char*) name, get_source_volume_callback, obj); - assert(o); - return convertNativePointerToJava(env, o); + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + jfieldID fid = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;"); + assert(fid); + jstring jstr = (*env)->GetObjectField(env, obj, fid); + assert(jstr); + const char *name = (*env)->GetStringUTFChars(env, jstr, NULL); + if (name == NULL) { + return NULL; // oome + } + + pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); + assert(context); + obj = (*env)->NewGlobalRef(env, obj); + pa_operation *o = pa_context_get_source_info_by_name (context, (char*) name, get_source_volume_callback, obj); + assert(o); + return convertNativePointerToJava(env, o); } /* @@ -70,33 +70,33 @@ */ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1set_1volume (JNIEnv *env, jobject obj, jfloat value) { - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - - jfieldID fid = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;"); - assert(fid); - - jstring jstr = (*env)->GetObjectField(env, obj, fid); - assert(jstr); - - const char *name = (*env)->GetStringUTFChars(env, jstr, NULL); - if (name == NULL) { - return NULL; // oome - } - - pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); - assert(context); - - obj = (*env)->NewGlobalRef(env, obj); - fid = (*env)->GetFieldID(env, cls, "channels", "I"); - assert(fid); - - jint channels = (*env)->GetIntField(env, obj, fid); - pa_cvolume cv; - - pa_operation *o = pa_context_set_source_volume_by_name (context, (char*) name,pa_cvolume_set(&cv, channels, value), source_callback, obj); - assert(o); - - return convertNativePointerToJava(env, o); + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + + jfieldID fid = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;"); + assert(fid); + + jstring jstr = (*env)->GetObjectField(env, obj, fid); + assert(jstr); + + const char *name = (*env)->GetStringUTFChars(env, jstr, NULL); + if (name == NULL) { + return NULL; // oome + } + + pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); + assert(context); + + obj = (*env)->NewGlobalRef(env, obj); + fid = (*env)->GetFieldID(env, cls, "channels", "I"); + assert(fid); + + jint channels = (*env)->GetIntField(env, obj, fid); + pa_cvolume cv; + + pa_operation *o = pa_context_set_source_volume_by_name (context, (char*) name,pa_cvolume_set(&cv, channels, value), source_callback, obj); + assert(o); + + return convertNativePointerToJava(env, o); }
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioTargetPort.c Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioTargetPort.c Wed Jul 06 17:11:34 2011 +0100 @@ -5,35 +5,35 @@ #include <string.h> typedef struct java_context { - JNIEnv* env; - jobject obj; + JNIEnv* env; + jobject obj; } java_context; extern JNIEnv* pulse_thread_env; static void sink_callback(pa_context *context, int success, void *userdata) { - notifyWaitingOperations(pulse_thread_env); + notifyWaitingOperations(pulse_thread_env); } static void get_sink_volume_callback(pa_context *context, const pa_sink_info *i, - int eol, void *userdata) { - assert(context); - assert(pulse_thread_env); + int eol, void *userdata) { + assert(context); + assert(pulse_thread_env); - if (eol == 0) { - // printf("%s\n", i->name); - jobject obj = (jobject) userdata; - assert(obj); - jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj); - assert(cls); - jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls, - "update_channels_and_volume", "(IF)V"); - assert(mid1); - (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, obj, mid1, - (int) (i->volume).channels, (float) (i->volume).values[0]) ; - } else { - notifyWaitingOperations(pulse_thread_env); - } + if (eol == 0) { + // printf("%s\n", i->name); + jobject obj = (jobject) userdata; + assert(obj); + jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj); + assert(cls); + jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls, + "update_channels_and_volume", "(IF)V"); + assert(mid1); + (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, obj, mid1, + (int) (i->volume).channels, (float) (i->volume).values[0]) ; + } else { + notifyWaitingOperations(pulse_thread_env); + } } @@ -45,29 +45,29 @@ */ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1update_1volume (JNIEnv *env, jobject obj) { - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - - jfieldID fid = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;"); - assert(fid); - - jstring jstr = (*env)->GetObjectField(env, obj, fid); - assert(jstr); - - const char *name = (*env)->GetStringUTFChars(env, jstr, NULL); - if (name == NULL) { - return NULL; // oome - } - - pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); - assert(context); - - obj = (*env)->NewGlobalRef(env, obj); - - pa_operation *o = pa_context_get_sink_info_by_name (context, (char*) name, get_sink_volume_callback, obj); - assert(o); - - return convertNativePointerToJava(env, o); + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + + jfieldID fid = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;"); + assert(fid); + + jstring jstr = (*env)->GetObjectField(env, obj, fid); + assert(jstr); + + const char *name = (*env)->GetStringUTFChars(env, jstr, NULL); + if (name == NULL) { + return NULL; // oome + } + + pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); + assert(context); + + obj = (*env)->NewGlobalRef(env, obj); + + pa_operation *o = pa_context_get_sink_info_by_name (context, (char*) name, get_sink_volume_callback, obj); + assert(o); + + return convertNativePointerToJava(env, o); } /* @@ -77,31 +77,31 @@ */ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1set_1volume (JNIEnv *env, jobject obj, jfloat value) { - jclass cls = (*env)->GetObjectClass(env, obj); - assert(cls); - - jfieldID fid = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;"); - assert(fid); - - jstring jstr = (*env)->GetObjectField(env, obj, fid); - assert(jstr); - - const char *name = (*env)->GetStringUTFChars(env, jstr, NULL); - if (name == NULL) { - return NULL; // return oome - } - - pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); - assert(context); - - obj = (*env)->NewGlobalRef(env, obj); - fid = (*env)->GetFieldID(env, cls, "channels", "I"); - assert(fid); - - jint channels = (*env)->GetIntField(env, obj, fid); - pa_cvolume cv; - pa_operation *o = pa_context_set_sink_volume_by_name (context, (char*) name,pa_cvolume_set(&cv, channels, value), sink_callback, obj); - assert(o); - - return convertNativePointerToJava(env, o); + jclass cls = (*env)->GetObjectClass(env, obj); + assert(cls); + + jfieldID fid = (*env)->GetFieldID(env, cls, "name", "Ljava/lang/String;"); + assert(fid); + + jstring jstr = (*env)->GetObjectField(env, obj, fid); + assert(jstr); + + const char *name = (*env)->GetStringUTFChars(env, jstr, NULL); + if (name == NULL) { + return NULL; // return oome + } + + pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer"); + assert(context); + + obj = (*env)->NewGlobalRef(env, obj); + fid = (*env)->GetFieldID(env, cls, "channels", "I"); + assert(fid); + + jint channels = (*env)->GetIntField(env, obj, fid); + pa_cvolume cv; + pa_operation *o = pa_context_set_sink_volume_by_name (context, (char*) name,pa_cvolume_set(&cv, channels, value), sink_callback, obj); + assert(o); + + return convertNativePointerToJava(env, o); }
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c Wed Jun 01 02:35:43 2011 +0100 +++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c Wed Jul 06 17:11:34 2011 +0100 @@ -8,236 +8,293 @@ #define CONTEXT_POINTER "contextPointer" typedef struct java_context { - JNIEnv* env; - jobject obj; + JNIEnv* env; + jobject obj; } java_context; extern JNIEnv* pulse_thread_env; static void set_sink_input_volume_callback(pa_context* context, int success, - void* userdata) { - notifyWaitingOperations(pulse_thread_env); + void* userdata) { + notifyWaitingOperations(pulse_thread_env); } const char* getStringFromFormat(pa_sample_format_t format) { - const char* value; + const char* value; - if (format == PA_SAMPLE_U8) { - value = "PA_SAMPLE_U8"; - } else if (format == PA_SAMPLE_ALAW) { - value = "PA_SAMPLE_ALAW"; - } else if (format == PA_SAMPLE_ULAW) { - value = "PA_SAMPLE_ULAW"; - } else if (format == PA_SAMPLE_S16BE) { - value = "PA_SAMPLE_S16BE"; - } else if (format == PA_SAMPLE_S16LE) { - value = "PA_SAMPLE_S16LE"; - } else if (format == PA_SAMPLE_S32BE) { - value = "PA_SAMPLE_S32BE"; - } else if (format == PA_SAMPLE_S32LE) { - value = "PA_SAMPLE_S32LE"; - } else { - value = "PA_SAMPLE_INVALID"; - } + if (format == PA_SAMPLE_U8) { + value = "PA_SAMPLE_U8"; + } else if (format == PA_SAMPLE_ALAW) { + value = "PA_SAMPLE_ALAW"; + } else if (format == PA_SAMPLE_ULAW) { + value = "PA_SAMPLE_ULAW"; + } else if (format == PA_SAMPLE_S16BE) { + value = "PA_SAMPLE_S16BE"; + } else if (format == PA_SAMPLE_S16LE) { + value = "PA_SAMPLE_S16LE"; + } else if (format == PA_SAMPLE_S32BE) { + value = "PA_SAMPLE_S32BE"; + } else if (format == PA_SAMPLE_S32LE) { + value = "PA_SAMPLE_S32LE"; + } else { + value = "PA_SAMPLE_INVALID"; + } - return value; + return value; } pa_sample_format_t getFormatFromString(const char* encoding) { - pa_sample_format_t format; + pa_sample_format_t format; - if (strcmp(encoding, "PA_SAMPLE_U8") == 0) { - format = PA_SAMPLE_U8; - } else if (strcmp(encoding, "PA_SAMPLE_ALAW") == 0) { - format = PA_SAMPLE_ALAW; - } else if (strcmp(encoding, "PA_SAMPLE_ULAW;") == 0) { - format = PA_SAMPLE_ULAW; - } else if (strcmp(encoding, "PA_SAMPLE_S16BE") == 0) { - format = PA_SAMPLE_S16BE; - } else if (strcmp(encoding, "PA_SAMPLE_S16LE") == 0) { - format = PA_SAMPLE_S16LE; - } else if (strcmp(encoding, "PA_SAMPLE_S32BE") == 0) { - format = PA_SAMPLE_S32BE; - } else if (strcmp(encoding, "PA_SAMPLE_S32LE") == 0) { - format = PA_SAMPLE_S32LE; - } else { - format = PA_SAMPLE_INVALID; - } + if (strcmp(encoding, "PA_SAMPLE_U8") == 0) { + format = PA_SAMPLE_U8; + } else if (strcmp(encoding, "PA_SAMPLE_ALAW") == 0) { + format = PA_SAMPLE_ALAW; + } else if (strcmp(encoding, "PA_SAMPLE_ULAW;") == 0) { + format = PA_SAMPLE_ULAW; + } else if (strcmp(encoding, "PA_SAMPLE_S16BE") == 0) { + format = PA_SAMPLE_S16BE; + } else if (strcmp(encoding, "PA_SAMPLE_S16LE") == 0) { + format = PA_SAMPLE_S16LE; + } else if (strcmp(encoding, "PA_SAMPLE_S32BE") == 0) { + format = PA_SAMPLE_S32BE; + } else if (strcmp(encoding, "PA_SAMPLE_S32LE") == 0) { + format = PA_SAMPLE_S32LE; + } else { + format = PA_SAMPLE_INVALID; + } - return format; + return format; } static void stream_state_callback(pa_stream* stream, void *userdata) { - //printf("stream_state_callback called\n"); + //printf("stream_state_callback called\n"); - java_context* context = userdata; - assert(stream); - assert(context); - assert(context->env); - assert(context->obj); + java_context* context = userdata; + assert(stream); + assert(context); + assert(context->env); + assert(context->obj); - if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { - callJavaVoidMethod(context->env, context->obj, "stateCallback"); - } else { - callJavaVoidMethod(pulse_thread_env, context->obj, "stateCallback"); - } + if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + callJavaVoidMethod(context->env, context->obj, "stateCallback"); + } else { + callJavaVoidMethod(pulse_thread_env, context->obj, "stateCallback"); + } } static void stream_write_callback(pa_stream *stream, size_t length, - void *userdata) { - // printf("stream_write_callback called\n"); + void *userdata) { + // printf("stream_write_callback called\n"); - java_context* context = userdata; - assert(stream); - assert(context); - assert(context->env); - assert(context->obj); + java_context* context = userdata; + assert(stream); + assert(context); + assert(context->env); + assert(context->obj); - if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { - callJavaVoidMethod(context->env, context->obj, "writeCallback"); - } else { - callJavaVoidMethod(pulse_thread_env, context->obj, "writeCallback"); - } + if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + callJavaVoidMethod(context->env, context->obj, "writeCallback"); + } else { + callJavaVoidMethod(pulse_thread_env, context->obj, "writeCallback"); + } } static void stream_read_callback(pa_stream *stream, size_t length, - void *userdata) { - // printf("stream_read_callback called\n"); + void *userdata) { + // printf("stream_read_callback called\n"); - java_context* context = userdata; - assert(stream); - assert(context); - assert(context->env); - assert(context->obj); + java_context* context = userdata; + assert(stream); + assert(context); + assert(context->env); + assert(context->obj); - if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { - callJavaVoidMethod(context->env, context->obj, "readCallback"); - } else { - callJavaVoidMethod(pulse_thread_env, context->obj, "readCallback"); - } + if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + callJavaVoidMethod(context->env, context->obj, "readCallback"); + } else { + callJavaVoidMethod(pulse_thread_env, context->obj, "readCallback"); + } } static void stream_overflow_callback(pa_stream *stream, void *userdata) { - //printf("stream_overflow_callback called\n"); + //printf("stream_overflow_callback called\n"); - java_context* context = userdata; - assert(stream); - assert(context); - assert(context->env); - assert(context->obj); + java_context* context = userdata; + assert(stream); + assert(context); + assert(context->env); + assert(context->obj); - if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { - callJavaVoidMethod(context->env, context->obj, "overflowCallback"); - } else { - callJavaVoidMethod(pulse_thread_env, context->obj, "overflowCallback"); - } + if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + callJavaVoidMethod(context->env, context->obj, "overflowCallback"); + } else { + callJavaVoidMethod(pulse_thread_env, context->obj, "overflowCallback"); + } } static void stream_underflow_callback(pa_stream *stream, void *userdata) { - // printf("stream_underflow_callback called\n"); + // printf("stream_underflow_callback called\n"); - java_context* context = userdata; - assert(stream); - assert(context); - assert(context->env); - assert(context->obj); + java_context* context = userdata; + assert(stream); + assert(context); + assert(context->env); + assert(context->obj); - if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { - callJavaVoidMethod(context->env, context->obj, "underflowCallback"); - } else { - callJavaVoidMethod(pulse_thread_env, context->obj, "underflowCallback"); - } + if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + callJavaVoidMethod(context->env, context->obj, "underflowCallback"); + } else { + callJavaVoidMethod(pulse_thread_env, context->obj, "underflowCallback"); + } } static void update_timing_info_callback(pa_stream* stream, int success, void* userdata) { - assert(stream); - JNIEnv* env = pulse_thread_env; - assert(env); + assert(stream); + JNIEnv* env = pulse_thread_env; + assert(env); - notifyWaitingOperations(env); + notifyWaitingOperations(env); - if (success == 0) { - throwByName(env, ILLEGAL_STATE_EXCEPTION, "drain failed"); - } + if (success == 0) { + throwByName(env, ILLEGAL_STATE_EXCEPTION, "drain failed"); + } } - // requires pulseaudio 0.9.11 :( static void stream_started_callback(pa_stream *stream, void *userdata) { - // printf("stream_started_callback called\n"); - java_context* context = userdata; - assert(stream); - assert(context); - assert(context->env); - assert(context->obj); + // printf("stream_started_callback called\n"); + java_context* context = userdata; + assert(stream); + assert(context); + assert(context->env); + assert(context->obj); - if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { - callJavaVoidMethod(context->env, context->obj, - "playbackStartedCallback"); - } else { - callJavaVoidMethod(pulse_thread_env, context->obj, - "playbackStartedCallback"); - } + if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + callJavaVoidMethod(context->env, context->obj, + "playbackStartedCallback"); + } else { + callJavaVoidMethod(pulse_thread_env, context->obj, + "playbackStartedCallback"); + } } static void stream_latency_update_callback(pa_stream *stream, void *userdata) { - // printf("stream_latency_update_callback called\n"); + // printf("stream_latency_update_callback called\n"); - java_context* context = userdata; - assert(stream); - assert(context); - assert(context->env); - assert(context->obj); + java_context* context = userdata; + assert(stream); + assert(context); + assert(context->env); + assert(context->obj); - if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { - callJavaVoidMethod(context->env, context->obj, "latencyUpdateCallback"); - } else { - callJavaVoidMethod(pulse_thread_env, context->obj, - "latencyUpdateCallback"); - } + if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + callJavaVoidMethod(context->env, context->obj, "latencyUpdateCallback"); + } else { + callJavaVoidMethod(pulse_thread_env, context->obj, + "latencyUpdateCallback"); + } } static void stream_moved_callback(pa_stream *stream, void *userdata) { - // printf("stream_moved_callback called\n"); + // printf("stream_moved_callback called\n"); - java_context* context = userdata; - assert(stream); - assert(context); - assert(context->env); - assert(context->obj); + java_context* context = userdata; + assert(stream); + assert(context); + assert(context->env); + assert(context->obj); - if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { - callJavaVoidMethod(context->env, context->obj, "movedCallback"); - } else { - callJavaVoidMethod(pulse_thread_env, context->obj, "movedCallback"); - } + if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + callJavaVoidMethod(context->env, context->obj, "movedCallback"); + } else { + callJavaVoidMethod(pulse_thread_env, context->obj, "movedCallback"); + } } static void stream_suspended_callback(pa_stream *stream, void *userdata) { - // printf("stream_suspended_callback called\n"); + // printf("stream_suspended_callback called\n"); + + java_context* context = userdata; + assert(stream); + assert(context); + assert(context->env); + assert(context->obj); + + if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + callJavaVoidMethod(context->env, context->obj, "suspendedCallback"); + } else { + callJavaVoidMethod(pulse_thread_env, context->obj, "suspendedCallback"); + } + +} + +static void buf_attr_changed_callback(pa_stream *stream, void *userdata) { + java_context* context = userdata; + assert(stream); + assert(context); + assert(context->env); + assert(context->obj); + + if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { + callJavaVoidMethod(context->env, context->obj, "bufferAttrCallback"); + } else { + callJavaVoidMethod(pulse_thread_env, context->obj, "bufferAttrCallback"); + } +} - java_context* context = userdata; - assert(stream); - assert(context); - assert(context->env); - assert(context->obj); +// used to set stream flags and states. +// The names in Stream.java have a {STATE_,FLAG_} prefix, but we don't want to +// add the underscore in every line in init_constants, so we add it here. If +// constants with no prefix are ever introduced (i.e. java_prefix is "", +// it's important to remove the ##_ ) +#define SET_STREAM_ENUM(env, clz, java_prefix, state_name) \ + SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, java_prefix##_, STREAM, state_name) - if (pa_stream_get_state(stream) == PA_STREAM_CREATING) { - callJavaVoidMethod(context->env, context->obj, "suspendedCallback"); - } else { - callJavaVoidMethod(pulse_thread_env, context->obj, "suspendedCallback"); - } +/* + * Class: org_classpath_icedtea_pulseaudio_Stream + * Method: init_constants + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_init_1constants + (JNIEnv *env, jclass clz) { + // set states. + SET_STREAM_ENUM(env, clz, STATE, UNCONNECTED); + SET_STREAM_ENUM(env, clz, STATE, CREATING); + SET_STREAM_ENUM(env, clz, STATE, READY); + SET_STREAM_ENUM(env, clz, STATE, FAILED); + SET_STREAM_ENUM(env, clz, STATE, TERMINATED); + // set flags. + SET_STREAM_ENUM(env, clz, FLAG, NOFLAGS); + SET_STREAM_ENUM(env, clz, FLAG, START_CORKED); + SET_STREAM_ENUM(env, clz, FLAG, INTERPOLATE_TIMING); + SET_STREAM_ENUM(env, clz, FLAG, NOT_MONOTONIC); + SET_STREAM_ENUM(env, clz, FLAG, AUTO_TIMING_UPDATE); + SET_STREAM_ENUM(env, clz, FLAG, NO_REMAP_CHANNELS); + SET_STREAM_ENUM(env, clz, FLAG, NO_REMIX_CHANNELS); + SET_STREAM_ENUM(env, clz, FLAG, FIX_FORMAT); + SET_STREAM_ENUM(env, clz, FLAG, FIX_RATE); + SET_STREAM_ENUM(env, clz, FLAG, FIX_CHANNELS); + SET_STREAM_ENUM(env, clz, FLAG, DONT_MOVE); + SET_STREAM_ENUM(env, clz, FLAG, VARIABLE_RATE); + SET_STREAM_ENUM(env, clz, FLAG, PEAK_DETECT); + SET_STREAM_ENUM(env, clz, FLAG, START_MUTED); + SET_STREAM_ENUM(env, clz, FLAG, ADJUST_LATENCY); + SET_STREAM_ENUM(env, clz, FLAG, EARLY_REQUESTS); + SET_STREAM_ENUM(env, clz, FLAG, DONT_INHIBIT_AUTO_SUSPEND); + SET_STREAM_ENUM(env, clz, FLAG, START_UNMUTED); + SET_STREAM_ENUM(env, clz, FLAG, FAIL_ON_SUSPEND); } /* @@ -247,73 +304,73 @@ */ JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1new (JNIEnv* env, jobject obj, jbyteArray contextPointer, jstring nameString, - jstring encodingString, jint sampleRate, jint channels) { + jstring encodingString, jint sampleRate, jint channels) { - // printf("creating a new PulseAudio stream\n"); + // printf("creating a new PulseAudio stream\n"); - java_context* j_context = malloc(sizeof(java_context)); - assert(j_context); - j_context->env = env; - j_context->obj = (*env)->NewGlobalRef(env, obj); + java_context* j_context = malloc(sizeof(java_context)); + assert(j_context); + j_context->env = env; + j_context->obj = (*env)->NewGlobalRef(env, obj); - pa_context* context = convertJavaPointerToNative(env, contextPointer); - assert(context); + pa_context* context = convertJavaPointerToNative(env, contextPointer); + assert(context); - const char* name = NULL; - if (nameString) { - name = (*env)->GetStringUTFChars(env,nameString, NULL); - if (name == NULL) { - (*env)->DeleteGlobalRef(env, obj); - free(j_context); - return; // oome thrown - } - } + const char* name = NULL; + if (nameString) { + name = (*env)->GetStringUTFChars(env,nameString, NULL); + if (name == NULL) { + (*env)->DeleteGlobalRef(env, obj); + free(j_context); + return; // oome thrown + } + } - const char *encoding = (*env)->GetStringUTFChars(env, encodingString, NULL); - if( encoding == NULL) { - return; //oome thrown - } + const char *encoding = (*env)->GetStringUTFChars(env, encodingString, NULL); + if( encoding == NULL) { + return; //oome thrown + } - pa_sample_spec sample_spec; + pa_sample_spec sample_spec; - sample_spec.format = getFormatFromString(encoding); - sample_spec.rate = sampleRate; - sample_spec.channels = channels; + sample_spec.format = getFormatFromString(encoding); + sample_spec.rate = sampleRate; + sample_spec.channels = channels; - if ( !pa_sample_spec_valid(&sample_spec)) { - throwByName(env, "java/lang/IllegalArgumentException", "Invalid format"); - (*env)->ReleaseStringUTFChars(env, encodingString, encoding); - if (name) { - (*env)->ReleaseStringUTFChars(env, nameString,name); - } - return; - } + if ( !pa_sample_spec_valid(&sample_spec)) { + throwByName(env, "java/lang/IllegalArgumentException", "Invalid format"); + (*env)->ReleaseStringUTFChars(env, encodingString, encoding); + if (name) { + (*env)->ReleaseStringUTFChars(env, nameString,name); + } + return; + } - pa_stream* stream = pa_stream_new(context, name, &sample_spec, NULL); - assert(stream); - if (name) { - (*env)->ReleaseStringUTFChars(env, nameString,name); - } + pa_stream* stream = pa_stream_new(context, name, &sample_spec, NULL); + assert(stream); + if (name) { + (*env)->ReleaseStringUTFChars(env, nameString,name); + } - setJavaPointer(env, obj, "streamPointer", stream); + setJavaPointer(env, obj, "streamPointer", stream); - /* - * - * The stream has been created; now setup the callbacks - * so we can do somethig about them - * - */ + /* + * + * The stream has been created; now setup the callbacks + * so we can do somethig about them + * + */ - pa_stream_set_state_callback (stream, stream_state_callback, j_context); - pa_stream_set_write_callback (stream, stream_write_callback, j_context); - pa_stream_set_read_callback (stream, stream_read_callback, j_context); - pa_stream_set_overflow_callback (stream, stream_overflow_callback, j_context); - pa_stream_set_underflow_callback (stream, stream_underflow_callback, j_context); - pa_stream_set_started_callback (stream, stream_started_callback, j_context); - pa_stream_set_latency_update_callback (stream, stream_latency_update_callback, j_context); - pa_stream_set_moved_callback (stream, stream_moved_callback, j_context); - pa_stream_set_suspended_callback (stream, stream_suspended_callback, j_context); - + pa_stream_set_state_callback (stream, stream_state_callback, j_context); + pa_stream_set_write_callback (stream, stream_write_callback, j_context); + pa_stream_set_read_callback (stream, stream_read_callback, j_context); + pa_stream_set_overflow_callback (stream, stream_overflow_callback, j_context); + pa_stream_set_underflow_callback (stream, stream_underflow_callback, j_context); + pa_stream_set_started_callback (stream, stream_started_callback, j_context); + pa_stream_set_latency_update_callback (stream, stream_latency_update_callback, j_context); + pa_stream_set_moved_callback (stream, stream_moved_callback, j_context); + pa_stream_set_suspended_callback (stream, stream_suspended_callback, j_context); + pa_stream_set_buffer_attr_callback(stream, buf_attr_changed_callback, j_context); } /* @@ -323,10 +380,10 @@ */ JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1unref (JNIEnv* env, jobject obj) { - pa_stream* stream = getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - pa_stream_unref(stream); - setJavaPointer(env, obj, "streamPointer", NULL); + pa_stream* stream = getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + pa_stream_unref(stream); + setJavaPointer(env, obj, "streamPointer", NULL); } /* @@ -334,11 +391,11 @@ * Method: native_pa_stream_get_state * Signature: ()I */ -JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1state +JNIEXPORT jlong JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1state (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - return pa_stream_get_state(stream); + pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + return pa_stream_get_state(stream); } /* @@ -349,11 +406,11 @@ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1context (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - pa_context* context = pa_stream_get_context(stream); - assert(context); - return convertNativePointerToJava(env, context); + pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + pa_context* context = pa_stream_get_context(stream); + assert(context); + return convertNativePointerToJava(env, context); } /* @@ -363,9 +420,9 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1index (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - return pa_stream_get_index(stream); + pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + return pa_stream_get_index(stream); } /* @@ -375,9 +432,9 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1device_1index (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - return pa_stream_get_device_index(stream); + pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + return pa_stream_get_device_index(stream); } /* @@ -387,11 +444,11 @@ */ JNIEXPORT jstring JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1device_1name (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - const char* name = pa_stream_get_device_name(stream); - assert(name); - return (*env)->NewStringUTF(env, name); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + const char* name = pa_stream_get_device_name(stream); + assert(name); + return (*env)->NewStringUTF(env, name); } /* @@ -401,9 +458,9 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1is_1suspended (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - return pa_stream_is_suspended(stream); + pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + return pa_stream_is_suspended(stream); } /* @@ -413,54 +470,44 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1connect_1playback (JNIEnv* env, jobject obj, jstring device, jint bufferMaxLength, - jint bufferTargetLength, jint bufferPreBuffering, - jint bufferMinimumRequest, jint bufferFragmentSize, jint flags, - jbyteArray volumePointer, jbyteArray sync_streamPointer) { + jint bufferTargetLength, jint bufferPreBuffering, + jint bufferMinimumRequest, jint bufferFragmentSize, jlong flags, + jbyteArray volumePointer, jbyteArray sync_streamPointer) { + pa_stream *sync_stream; + if(sync_streamPointer != NULL) { + sync_stream = convertJavaPointerToNative(env, sync_streamPointer); + printf("Master stream is %p\n", sync_stream); + } else { + sync_stream = NULL; + } - pa_stream *sync_stream; - if(sync_streamPointer != NULL) { - sync_stream = convertJavaPointerToNative(env, sync_streamPointer); - printf("Master stream is %p\n", sync_stream); - } else { - sync_stream = NULL; - } + pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - - pa_buffer_attr buffer_attr; + pa_buffer_attr buffer_attr; - memset(&buffer_attr, 0, sizeof(buffer_attr)); - - buffer_attr.maxlength = (uint32_t) bufferMaxLength; - buffer_attr.tlength = (uint32_t) bufferTargetLength; - buffer_attr.prebuf = (uint32_t) bufferPreBuffering; - buffer_attr.minreq = (uint32_t) bufferMinimumRequest; + memset(&buffer_attr, 0, sizeof(buffer_attr)); - /* - printf("buffer maxlength: %u\n", buffer_attr.maxlength); - printf("buffer tlength: %u\n", buffer_attr.tlength); - printf("buffer prebuf: %u\n", buffer_attr.prebuf); - printf("buffer minreq: %u\n", buffer_attr.minreq); - printf("buffer fragsize: %u\n", buffer_attr.fragsize); - */ + buffer_attr.maxlength = (uint32_t) bufferMaxLength; + buffer_attr.tlength = (uint32_t) bufferTargetLength; + buffer_attr.prebuf = (uint32_t) bufferPreBuffering; + buffer_attr.minreq = (uint32_t) bufferMinimumRequest; - const char* dev = NULL; - if (device != NULL) { - dev = (*env)->GetStringUTFChars(env, device, NULL); - if (dev == NULL) { - return -1; // oome thrown - } - } - /* Set flags to 0 to fix problem with draining before calling start, might need to - be changed back to PA_STREAM_START_CORKED in the future, if we'll be able to implement - synchronization*/ - int value = pa_stream_connect_playback(stream, dev, &buffer_attr, PA_STREAM_START_CORKED, NULL, sync_stream); + const char* dev = NULL; + if (device != NULL) { + dev = (*env)->GetStringUTFChars(env, device, NULL); + if (dev == NULL) { + return -1; // oome thrown + } + } - if (dev != NULL) { - (*env)->ReleaseStringUTFChars(env, device, dev); - dev = NULL; - } - return value; + int value = pa_stream_connect_playback(stream, dev, &buffer_attr, + (pa_stream_flags_t) flags, NULL, sync_stream); + + if (dev != NULL) { + (*env)->ReleaseStringUTFChars(env, device, dev); + dev = NULL; + } + return value; } /* @@ -470,41 +517,34 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1connect_1record (JNIEnv* env, jobject obj, jstring device, jint bufferMaxLength, - jint bufferTargetLength, jint bufferPreBuffereing, - jint bufferMinimumRequest, jint bufferFragmentSize, jint flags, - jbyteArray volumePointer, jbyteArray sync_streamPointer) { + jint bufferTargetLength, jint bufferPreBuffereing, + jint bufferMinimumRequest, jint bufferFragmentSize, jlong flags, + jbyteArray volumePointer, jbyteArray sync_streamPointer) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); - pa_buffer_attr buffer_attr; - memset(&buffer_attr, 0 , sizeof(buffer_attr)); - buffer_attr.maxlength = (uint32_t) bufferMaxLength; - buffer_attr.fragsize = (uint32_t) bufferFragmentSize; + pa_buffer_attr buffer_attr; + memset(&buffer_attr, 0 , sizeof(buffer_attr)); + buffer_attr.maxlength = (uint32_t) bufferMaxLength; + buffer_attr.fragsize = (uint32_t) bufferFragmentSize; - /* - printf("buffer maxlength: %u\n", buffer_attr.maxlength); - printf("buffer tlength: %u\n", buffer_attr.tlength); - printf("buffer prebuf: %u\n", buffer_attr.prebuf); - printf("buffer minreq: %u\n", buffer_attr.minreq); - printf("buffer fragsize: %u\n", buffer_attr.fragsize); - */ + const char* dev = NULL; + if (device != NULL) { + dev = (*env)->GetStringUTFChars(env, device, NULL); + if (dev == NULL) { + return -1; // oome thrown + } + } - const char* dev = NULL; - if (device != NULL) { - dev = (*env)->GetStringUTFChars(env, device, NULL); - if (dev == NULL) { - return -1; // oome thrown - } - } + int value = pa_stream_connect_record(stream, dev, &buffer_attr, + (pa_stream_flags_t) flags); - int value = pa_stream_connect_record(stream, dev, &buffer_attr, flags); - - if (dev != NULL) { - (*env)->ReleaseStringUTFChars(env, device, dev); - dev = NULL; - } - return value; + if (dev != NULL) { + (*env)->ReleaseStringUTFChars(env, device, dev); + dev = NULL; + } + return value; } @@ -515,11 +555,11 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1disconnect (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - int return_value = pa_stream_disconnect(stream); + pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + int return_value = pa_stream_disconnect(stream); - return return_value; + return return_value; } /* @@ -529,16 +569,16 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1write (JNIEnv* env, jobject obj, jbyteArray data, jint offset, jint data_length) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - jbyte* data_buffer = (*env)->GetByteArrayElements(env, data, NULL); - if (data_buffer == NULL) { - return -1; // oome thrown - } - jbyte* buffer_start = data_buffer + offset; - int value = pa_stream_write(stream, buffer_start, data_length, NULL, 0, PA_SEEK_RELATIVE); - (*env)->ReleaseByteArrayElements(env, data, data_buffer, 0); - return value; + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + jbyte* data_buffer = (*env)->GetByteArrayElements(env, data, NULL); + if (data_buffer == NULL) { + return -1; // oome thrown + } + jbyte* buffer_start = data_buffer + offset; + int value = pa_stream_write(stream, buffer_start, data_length, NULL, 0, PA_SEEK_RELATIVE); + (*env)->ReleaseByteArrayElements(env, data, data_buffer, 0); + return value; } /* @@ -549,29 +589,29 @@ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1peek (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - const void* startLocation; - size_t count; + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + const void* startLocation; + size_t count; - if ( pa_stream_peek(stream, &startLocation, &count) < 0 ) { - return NULL; - } + if ( pa_stream_peek(stream, &startLocation, &count) < 0 ) { + return NULL; + } - /* no data available */ - if (startLocation == NULL) { - return NULL; - } + /* no data available */ + if (startLocation == NULL) { + return NULL; + } - jsize length = count; - jbyteArray data = (*env)->NewByteArray(env, length); + jsize length = count; + jbyteArray data = (*env)->NewByteArray(env, length); - if ( data == NULL) { - return NULL; // oome thrown - } + if ( data == NULL) { + return NULL; // oome thrown + } - (*env)->SetByteArrayRegion(env, data, 0, count, startLocation); - return data; + (*env)->SetByteArrayRegion(env, data, 0, count, startLocation); + return data; } /* @@ -581,9 +621,9 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1drop (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - return pa_stream_drop(stream); + pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + return pa_stream_drop(stream); } /* @@ -593,12 +633,12 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1writable_1size (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - if(!stream) { - return 0; - } - size_t size = pa_stream_writable_size(stream); - return size; + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + if(!stream) { + return 0; + } + size_t size = pa_stream_writable_size(stream); + return size; } @@ -609,22 +649,22 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1readable_1size (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - return pa_stream_readable_size(stream); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + return pa_stream_readable_size(stream); } static void drain_callback(pa_stream* stream, int success, void* userdata) { - assert(stream); - JNIEnv* env = pulse_thread_env; - assert(env); + assert(stream); + JNIEnv* env = pulse_thread_env; + assert(env); - notifyWaitingOperations(env); + notifyWaitingOperations(env); - if (success == 0) { - throwByName(env, ILLEGAL_STATE_EXCEPTION, "drain failed"); - } + if (success == 0) { + throwByName(env, ILLEGAL_STATE_EXCEPTION, "drain failed"); + } } @@ -635,11 +675,11 @@ */ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1drain (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - pa_operation* operation = pa_stream_drain(stream, drain_callback, NULL); - assert(operation); - return convertNativePointerToJava(env, operation); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + pa_operation* operation = pa_stream_drain(stream, drain_callback, NULL); + assert(operation); + return convertNativePointerToJava(env, operation); } /* @@ -649,23 +689,23 @@ */ JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1is_1corked (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - return pa_stream_is_corked(stream); + pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + return pa_stream_is_corked(stream); } static void cork_callback(pa_stream* stream, int success, void* userdata) { - java_context* context = userdata; - assert(stream); - assert(context); - JNIEnv* env = pulse_thread_env; - assert(env); - notifyWaitingOperations(env); + java_context* context = userdata; + assert(stream); + assert(context); + JNIEnv* env = pulse_thread_env; + assert(env); + notifyWaitingOperations(env); - if (success == 0) { - throwByName(env, ILLEGAL_STATE_EXCEPTION, "cork failed"); - } + if (success == 0) { + throwByName(env, ILLEGAL_STATE_EXCEPTION, "cork failed"); + } } @@ -676,26 +716,26 @@ */ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1cork (JNIEnv* env, jobject obj, jint yes) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - java_context* j_context = malloc(sizeof(java_context)); - assert(j_context); - j_context->env = env; - j_context->obj = (*env)->NewGlobalRef(env, obj); - pa_operation* operation = pa_stream_cork(stream, yes, cork_callback, j_context); - assert(operation); - return convertNativePointerToJava(env, operation); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + java_context* j_context = malloc(sizeof(java_context)); + assert(j_context); + j_context->env = env; + j_context->obj = (*env)->NewGlobalRef(env, obj); + pa_operation* operation = pa_stream_cork(stream, yes, cork_callback, j_context); + assert(operation); + return convertNativePointerToJava(env, operation); } static void flush_callback(pa_stream* stream, int success, void* userdata) { - assert(stream); - JNIEnv* env = pulse_thread_env; - assert(env); - notifyWaitingOperations(env); + assert(stream); + JNIEnv* env = pulse_thread_env; + assert(env); + notifyWaitingOperations(env); - if (success == 0) { - throwByName(env, ILLEGAL_STATE_EXCEPTION, "flush failed"); - } + if (success == 0) { + throwByName(env, ILLEGAL_STATE_EXCEPTION, "flush failed"); + } } @@ -706,22 +746,22 @@ */ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1flush (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - pa_operation* operation = pa_stream_flush(stream, flush_callback, NULL); - assert(operation); - return convertNativePointerToJava(env, operation); + pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + pa_operation* operation = pa_stream_flush(stream, flush_callback, NULL); + assert(operation); + return convertNativePointerToJava(env, operation); } static void trigger_callback(pa_stream* stream, int success, void* userdata) { - assert(stream); - JNIEnv* env = pulse_thread_env; - assert(env); - notifyWaitingOperations(env); + assert(stream); + JNIEnv* env = pulse_thread_env; + assert(env); + notifyWaitingOperations(env); - if (success == 0) { - throwByName(env, ILLEGAL_STATE_EXCEPTION, "trigger failed"); - } + if (success == 0) { + throwByName(env, ILLEGAL_STATE_EXCEPTION, "trigger failed"); + } } @@ -732,21 +772,21 @@ */ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1trigger (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - pa_operation* operation = pa_stream_trigger(stream, trigger_callback, NULL); - assert(operation); - return convertNativePointerToJava(env, operation); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + pa_operation* operation = pa_stream_trigger(stream, trigger_callback, NULL); + assert(operation); + return convertNativePointerToJava(env, operation); } static void set_name_callback(pa_stream* stream, int success, void* userdata) { - assert(stream); - JNIEnv* env = pulse_thread_env; - notifyWaitingOperations(env); + assert(stream); + JNIEnv* env = pulse_thread_env; + notifyWaitingOperations(env); - if (success == 0) { - throwByName(env, ILLEGAL_STATE_EXCEPTION, "set_name failed"); - } + if (success == 0) { + throwByName(env, ILLEGAL_STATE_EXCEPTION, "set_name failed"); + } } /* @@ -756,20 +796,20 @@ */ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1set_1name (JNIEnv* env, jobject obj, jstring newName) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); - const char* name; - name = (*env)->GetStringUTFChars(env, newName, NULL); - if (name == NULL) { - return 0; // OutOfMemoryError already thrown - } + const char* name; + name = (*env)->GetStringUTFChars(env, newName, NULL); + if (name == NULL) { + return 0; // OutOfMemoryError already thrown + } - pa_operation* operation = pa_stream_set_name(stream, name, set_name_callback, NULL); - assert(operation); - (*env)->ReleaseStringUTFChars(env, newName, name); + pa_operation* operation = pa_stream_set_name(stream, name, set_name_callback, NULL); + assert(operation); + (*env)->ReleaseStringUTFChars(env, newName, name); - return convertNativePointerToJava(env, operation); + return convertNativePointerToJava(env, operation); } /* @@ -779,14 +819,14 @@ */ JNIEXPORT jlong JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1time (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); - pa_usec_t time = 0; - int result = pa_stream_get_time (stream,&time); - assert(result == 0); + pa_usec_t time = 0; + int result = pa_stream_get_time (stream,&time); + assert(result == 0); - return time; + return time; } @@ -797,14 +837,14 @@ */ JNIEXPORT jlong JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1latency (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - pa_usec_t returnValue = 0; - int negative = 0; - int result = pa_stream_get_latency ( stream, &returnValue, &negative); - assert(result == 0); - assert(negative == 0); - return returnValue; + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + pa_usec_t returnValue = 0; + int negative = 0; + int result = pa_stream_get_latency ( stream, &returnValue, &negative); + assert(result == 0); + assert(negative == 0); + return returnValue; } /* @@ -814,30 +854,30 @@ */ JNIEXPORT jobject JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1sample_1spec (JNIEnv* env, jobject obj) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); - const pa_sample_spec* sample_spec = pa_stream_get_sample_spec(stream); - assert(sample_spec); + const pa_sample_spec* sample_spec = pa_stream_get_sample_spec(stream); + assert(sample_spec); - char* name = "Lorg/classpath/icedtea/pulseaudio/StreamSampleSpecification;"; - jclass cls = (*env)->FindClass(env, name); - assert(cls); - jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "V"); - assert(constructor_mid); + char* name = "Lorg/classpath/icedtea/pulseaudio/StreamSampleSpecification;"; + jclass cls = (*env)->FindClass(env, name); + assert(cls); + jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "V"); + assert(constructor_mid); - const char* formatString = getStringFromFormat(sample_spec->format); - assert(formatString); - int rate = sample_spec->rate; - int channels = sample_spec->channels; + const char* formatString = getStringFromFormat(sample_spec->format); + assert(formatString); + int rate = sample_spec->rate; + int channels = sample_spec->channels; - jstring format = (*env)->NewStringUTF(env, formatString); - if ( format == NULL) { - return NULL; // oome - } - jobject return_object = (*env)->NewObject(env, cls, constructor_mid, format, rate, channels); + jstring format = (*env)->NewStringUTF(env, formatString); + if ( format == NULL) { + return NULL; // oome + } + jobject return_object = (*env)->NewObject(env, cls, constructor_mid, format, rate, channels); - return return_object; + return return_object; } /* @@ -848,41 +888,41 @@ JNIEXPORT jobject JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1buffer_1attr (JNIEnv* env, jobject obj) { - // printf("in native_pa_stream_get_buffer_attributes"); + // printf("in native_pa_stream_get_buffer_attributes"); - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - const pa_buffer_attr* buffer = pa_stream_get_buffer_attr(stream); - assert(buffer); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + const pa_buffer_attr* buffer = pa_stream_get_buffer_attr(stream); + assert(buffer); - const char* class_name = "Lorg/classpath/icedtea/pulseaudio/StreamBufferAttributes;"; - jclass cls = (*env)->FindClass(env, class_name); - assert(cls); - jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "(IIIII)V"); - assert(constructor_mid); - jint maxLength = buffer->maxlength; - jint targetLength = buffer->tlength; - jint preBuffering = buffer->prebuf; - jint minimumRequest = buffer->minreq; - jint fragmentSize = buffer->fragsize; + const char* class_name = "Lorg/classpath/icedtea/pulseaudio/StreamBufferAttributes;"; + jclass cls = (*env)->FindClass(env, class_name); + assert(cls); + jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "(IIIII)V"); + assert(constructor_mid); + jint maxLength = buffer->maxlength; + jint targetLength = buffer->tlength; + jint preBuffering = buffer->prebuf; + jint minimumRequest = buffer->minreq; + jint fragmentSize = buffer->fragsize; - jobject return_object = (*env)->NewObject(env, cls, constructor_mid, maxLength, targetLength, - preBuffering, minimumRequest, fragmentSize); + jobject return_object = (*env)->NewObject(env, cls, constructor_mid, maxLength, targetLength, + preBuffering, minimumRequest, fragmentSize); - return return_object; + return return_object; } static void set_buffer_attr_callback(pa_stream* stream, int success, - void* userdata) { + void* userdata) { - assert(stream); - JNIEnv* env = pulse_thread_env; - assert(env); - notifyWaitingOperations(env); + assert(stream); + JNIEnv* env = pulse_thread_env; + assert(env); + notifyWaitingOperations(env); - if (success == 0) { - throwByName(env, ILLEGAL_STATE_EXCEPTION, "set_buffer_attr failed"); - } + if (success == 0) { + throwByName(env, ILLEGAL_STATE_EXCEPTION, "set_buffer_attr failed"); + } } /* @@ -893,58 +933,58 @@ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1set_1buffer_1attr (JNIEnv* env, jobject obj, jobject bufferAttributeObject) { - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); - jclass cls = (*env)->GetObjectClass(env, bufferAttributeObject); - assert(cls); + jclass cls = (*env)->GetObjectClass(env, bufferAttributeObject); + assert(cls); - pa_buffer_attr buffer; + pa_buffer_attr buffer; - jmethodID getMaxLengthID = (*env)->GetMethodID(env,cls,"getMaxLength","()I"); - assert(getMaxLengthID); - buffer.maxlength = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getMaxLengthID); + jmethodID getMaxLengthID = (*env)->GetMethodID(env,cls,"getMaxLength","()I"); + assert(getMaxLengthID); + buffer.maxlength = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getMaxLengthID); - jmethodID getTargetLengthID = (*env)->GetMethodID(env,cls,"getTargetLength","()I"); - assert(getTargetLengthID); - buffer.tlength = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getTargetLengthID); + jmethodID getTargetLengthID = (*env)->GetMethodID(env,cls,"getTargetLength","()I"); + assert(getTargetLengthID); + buffer.tlength = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getTargetLengthID); - jmethodID getPreBufferingID = (*env)->GetMethodID(env,cls,"getPreBuffering","()I"); - assert(getPreBufferingID); - buffer.prebuf = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getPreBufferingID); + jmethodID getPreBufferingID = (*env)->GetMethodID(env,cls,"getPreBuffering","()I"); + assert(getPreBufferingID); + buffer.prebuf = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getPreBufferingID); - jmethodID getMinimumRequestID = (*env)->GetMethodID(env, cls, "getMinimumRequest", "()I"); - assert(getMinimumRequestID); - buffer.minreq = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getMinimumRequestID ); + jmethodID getMinimumRequestID = (*env)->GetMethodID(env, cls, "getMinimumRequest", "()I"); + assert(getMinimumRequestID); + buffer.minreq = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getMinimumRequestID ); - jmethodID getFragmentSizeID = (*env)->GetMethodID(env,cls,"getFragmentSize","()I"); - assert(getFragmentSizeID); - buffer.fragsize = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getFragmentSizeID ); + jmethodID getFragmentSizeID = (*env)->GetMethodID(env,cls,"getFragmentSize","()I"); + assert(getFragmentSizeID); + buffer.fragsize = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getFragmentSizeID ); - /* - const pa_buffer_attr* old_buffer = pa_stream_get_buffer_attr(stream); + /* + const pa_buffer_attr* old_buffer = pa_stream_get_buffer_attr(stream); - printf("old buffer values: %u %u %u %u %u\n", old_buffer->maxlength, old_buffer->tlength, old_buffer->prebuf, old_buffer->minreq, old_buffer->fragsize); + printf("old buffer values: %u %u %u %u %u\n", old_buffer->maxlength, old_buffer->tlength, old_buffer->prebuf, old_buffer->minreq, old_buffer->fragsize); - printf("want these values: %u %u %u %u %u\n", buffer.maxlength, buffer.tlength, buffer.prebuf, buffer.minreq, buffer.fragsize); - */ + printf("want these values: %u %u %u %u %u\n", buffer.maxlength, buffer.tlength, buffer.prebuf, buffer.minreq, buffer.fragsize); + */ - pa_operation* operation = pa_stream_set_buffer_attr(stream, &buffer, set_buffer_attr_callback, NULL); + pa_operation* operation = pa_stream_set_buffer_attr(stream, &buffer, set_buffer_attr_callback, NULL); - assert(operation); - return convertNativePointerToJava(env,operation); + assert(operation); + return convertNativePointerToJava(env,operation); } static void update_sample_rate_callback(pa_stream* stream, int success, - void* userdata) { - assert(stream); - JNIEnv* env = pulse_thread_env; - assert(env); - notifyWaitingOperations(env); + void* userdata) { + assert(stream); + JNIEnv* env = pulse_thread_env; + assert(env); + notifyWaitingOperations(env); - if (success == 0) { - throwByName(env, ILLEGAL_STATE_EXCEPTION, "update_sampl_rate failed"); - } + if (success == 0) { + throwByName(env, ILLEGAL_STATE_EXCEPTION, "update_sampl_rate failed"); + } } /* @@ -955,13 +995,13 @@ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1update_1sample_1rate (JNIEnv* env, jobject obj, jint newRate) { - uint32_t rate = (uint32_t) newRate; + uint32_t rate = (uint32_t) newRate; - pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - pa_operation* operation = pa_stream_update_sample_rate(stream,rate, update_sample_rate_callback, NULL); - assert(operation); - return convertNativePointerToJava(env, operation); + pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + pa_operation* operation = pa_stream_update_sample_rate(stream,rate, update_sample_rate_callback, NULL); + assert(operation); + return convertNativePointerToJava(env, operation); } @@ -973,45 +1013,45 @@ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1set_1volume (JNIEnv *env, jobject obj, jfloat new_volume) { - pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - pa_context *context = pa_stream_get_context(stream); - assert(context); + pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + pa_context *context = pa_stream_get_context(stream); + assert(context); - int stream_id = pa_stream_get_index(stream); - int channels = pa_stream_get_sample_spec(stream)->channels; - pa_cvolume cv; + int stream_id = pa_stream_get_index(stream); + int channels = pa_stream_get_sample_spec(stream)->channels; + pa_cvolume cv; - pa_operation* o = pa_context_set_sink_input_volume(context, stream_id, pa_cvolume_set(&cv, channels, new_volume), set_sink_input_volume_callback, NULL); - assert(o); + pa_operation* o = pa_context_set_sink_input_volume(context, stream_id, pa_cvolume_set(&cv, channels, new_volume), set_sink_input_volume_callback, NULL); + assert(o); - return convertNativePointerToJava(env, o); + return convertNativePointerToJava(env, o); } static void get_sink_input_volume_callback(pa_context *context, const pa_sink_input_info *i, - int eol, void *userdata) { + int eol, void *userdata) { - JNIEnv* env = pulse_thread_env; + JNIEnv* env = pulse_thread_env; - assert(context); - assert(env); - jobject obj = (jobject) userdata; - assert(obj); + assert(context); + assert(env); + jobject obj = (jobject) userdata; + assert(obj); - if (eol == 0) { - jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj); - assert(cls); - jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls, - "update_channels_and_volume", "(IF)V"); - assert(mid1); - (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, obj, mid1, - (int) (i->volume).channels, (float) (i->volume).values[0]) ; - } else { - notifyWaitingOperations(pulse_thread_env); - (*env)->DeleteGlobalRef(env, obj); - } + if (eol == 0) { + jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj); + assert(cls); + jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls, + "update_channels_and_volume", "(IF)V"); + assert(mid1); + (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, obj, mid1, + (int) (i->volume).channels, (float) (i->volume).values[0]) ; + } else { + notifyWaitingOperations(pulse_thread_env); + (*env)->DeleteGlobalRef(env, obj); + } } /* @@ -1022,37 +1062,37 @@ JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1update_1volume (JNIEnv* env, jobject obj) { - pa_stream* stream = getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); + pa_stream* stream = getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); - int sink_input_index = pa_stream_get_index(stream); + int sink_input_index = pa_stream_get_index(stream); - pa_context* context = pa_stream_get_context(stream); - assert(context); + pa_context* context = pa_stream_get_context(stream); + assert(context); - obj = (*env)->NewGlobalRef(env, obj); - pa_operation *o = pa_context_get_sink_input_info(context, sink_input_index , get_sink_input_volume_callback, obj); - assert(o); - return convertNativePointerToJava(env, o); + obj = (*env)->NewGlobalRef(env, obj); + pa_operation *o = pa_context_get_sink_input_info(context, sink_input_index , get_sink_input_volume_callback, obj); + assert(o); + return convertNativePointerToJava(env, o); } JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_bytesInBuffer(JNIEnv *env, jobject obj) { - pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - const pa_timing_info *timing_info = pa_stream_get_timing_info(stream); - int write_index = timing_info->write_index; - int read_index = timing_info->read_index; - return write_index - read_index; + pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + const pa_timing_info *timing_info = pa_stream_get_timing_info(stream); + int write_index = timing_info->write_index; + int read_index = timing_info->read_index; + return write_index - read_index; } JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1updateTimingInfo(JNIEnv* env, jobject obj) { - pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER); - assert(stream); - pa_operation* o = pa_stream_update_timing_info(stream, update_timing_info_callback, NULL); - assert(o); - return convertNativePointerToJava(env, o); + pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER); + assert(stream); + pa_operation* o = pa_stream_update_timing_info(stream, update_timing_info_callback, NULL); + assert(o); + return convertNativePointerToJava(env, o); }