8033367: [macosx] Appletviewer was broken in jdk8 b124
Reviewed-by: anthony, serb
This commit is contained in:
parent
8bd889eb2a
commit
87beb419b9
jdk
make/lib
src/macosx
bin
classes
native/sun
@ -1358,7 +1358,7 @@ endif
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
|
||||
LIBAWT_LWAWT_FILES := \
|
||||
awt.m \
|
||||
AWT_debug.m \
|
||||
ApplicationDelegate.m \
|
||||
CFRetainedResource.m \
|
||||
CGLGraphicsConfig.m \
|
||||
|
@ -994,7 +994,7 @@ SetXStartOnFirstThreadArg()
|
||||
|
||||
sameThread = JNI_TRUE;
|
||||
// Set a variable that tells us we started on the main thread.
|
||||
// This is used by the AWT during startup. (See awt.m)
|
||||
// This is used by the AWT during startup. (See LWCToolkit.m)
|
||||
char envVar[80];
|
||||
snprintf(envVar, sizeof(envVar), "JAVA_STARTED_ON_FIRST_THREAD_%d", getpid());
|
||||
setenv(envVar, "1", 1);
|
||||
|
@ -58,15 +58,8 @@ public class Application {
|
||||
static Application sApplication = null;
|
||||
|
||||
static {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("awt");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
checkSecurity();
|
||||
Toolkit.getDefaultToolkit(); // Start AppKit
|
||||
if (!Beans.isDesignTime()) {
|
||||
nativeInitializeApplicationDelegate();
|
||||
}
|
||||
|
@ -40,9 +40,6 @@ import sun.java2d.*;
|
||||
*/
|
||||
public final class CGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
|
||||
// Global initialization of the Cocoa runtime.
|
||||
private static native void initCocoa();
|
||||
|
||||
/**
|
||||
* Fetch an array of all valid CoreGraphics display identifiers.
|
||||
*/
|
||||
@ -60,21 +57,8 @@ public final class CGraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
public static void init() { }
|
||||
|
||||
static {
|
||||
java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("awt");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
java.security.AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
if (isHeadless()) return null;
|
||||
initCocoa();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Load libraries and initialize the Toolkit.
|
||||
Toolkit.getDefaultToolkit();
|
||||
// Install the correct surface manager factory.
|
||||
SurfaceManagerFactory.setInstance(new MacosxSurfaceManagerFactory());
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ import java.net.MalformedURLException;
|
||||
|
||||
import sun.awt.*;
|
||||
import sun.awt.datatransfer.DataTransferer;
|
||||
import sun.awt.util.ThreadGroupUtils;
|
||||
import sun.java2d.opengl.OGLRenderQueue;
|
||||
import sun.lwawt.*;
|
||||
import sun.lwawt.LWWindowPeer.PeerType;
|
||||
@ -70,7 +71,7 @@ public final class LWCToolkit extends LWToolkit {
|
||||
private static final int BUTTONS = 5;
|
||||
|
||||
private static native void initIDs();
|
||||
|
||||
private static native void initAppkit(ThreadGroup appKitThreadGroup, boolean headless);
|
||||
private static CInputMethodDescriptor sInputMethodDescriptor;
|
||||
|
||||
static {
|
||||
@ -119,6 +120,7 @@ public final class LWCToolkit extends LWToolkit {
|
||||
areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty("sun.awt.enableExtraMouseButtons", "true"));
|
||||
//set system property if not yet assigned
|
||||
System.setProperty("sun.awt.enableExtraMouseButtons", ""+areExtraMouseButtonsEnabled);
|
||||
initAppkit(ThreadGroupUtils.getRootThreadGroup(), GraphicsEnvironment.isHeadless());
|
||||
}
|
||||
|
||||
/*
|
||||
@ -166,7 +168,7 @@ public final class LWCToolkit extends LWToolkit {
|
||||
// This is only called from native code.
|
||||
static void systemColorsChanged() {
|
||||
EventQueue.invokeLater(() -> {
|
||||
AccessController.doPrivileged ((PrivilegedAction<Object>) () -> {
|
||||
AccessController.doPrivileged( (PrivilegedAction<Object>) () -> {
|
||||
AWTAccessor.getSystemColorAccessor().updateSystemColors();
|
||||
return null;
|
||||
});
|
||||
|
@ -30,24 +30,6 @@
|
||||
#import "AWT_debug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_awt_CGraphicsEnvironment
|
||||
* Method: initCocoa
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_CGraphicsEnvironment_initCocoa
|
||||
(JNIEnv *env, jclass self)
|
||||
{
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
// Inform Cocoa that we're multi-threaded.
|
||||
// Creating a short-lived NSThread is the recommended way of doing so.
|
||||
[NSThread detachNewThreadSelector:@selector(self) toTarget:[NSObject class] withObject:nil];
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
}
|
||||
|
||||
#define MAX_DISPLAYS 64
|
||||
|
||||
/*
|
||||
|
@ -24,7 +24,12 @@
|
||||
*/
|
||||
|
||||
#import <dlfcn.h>
|
||||
#import <pthread.h>
|
||||
#import <objc/runtime.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Security/AuthSession.h>
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
|
||||
|
||||
#include "jni_util.h"
|
||||
#import "CMenuBar.h"
|
||||
@ -34,6 +39,8 @@
|
||||
#import "AWT_debug.h"
|
||||
#import "CSystemColors.h"
|
||||
#import "NSApplicationAWT.h"
|
||||
#import "PropertiesUtilities.h"
|
||||
#import "ApplicationDelegate.h"
|
||||
|
||||
#import "sun_lwawt_macosx_LWCToolkit.h"
|
||||
|
||||
@ -42,6 +49,17 @@
|
||||
int gNumberOfButtons;
|
||||
jint* gButtonDownMasks;
|
||||
|
||||
// Indicates that the app has been started with -XstartOnFirstThread
|
||||
// (directly or via WebStart settings), and AWT should not run its
|
||||
// own event loop in this mode. Even if a loop isn't running yet,
|
||||
// we expect an embedder (e.g. SWT) to start it some time later.
|
||||
static BOOL forceEmbeddedMode = NO;
|
||||
|
||||
// This is the data necessary to have JNI_OnLoad wait for AppKit to start.
|
||||
static BOOL sAppKitStarted = NO;
|
||||
static pthread_mutex_t sAppKitStarted_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t sAppKitStarted_cv = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
@implementation AWTToolkit
|
||||
|
||||
static long eventCount;
|
||||
@ -115,6 +133,233 @@ static long eventCount;
|
||||
}
|
||||
@end
|
||||
|
||||
void setBusy(BOOL busy) {
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
static JNF_CLASS_CACHE(jc_AWTAutoShutdown, "sun/awt/AWTAutoShutdown");
|
||||
|
||||
if (busy) {
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_notifyBusyMethod, jc_AWTAutoShutdown, "notifyToolkitThreadBusy", "()V");
|
||||
JNFCallStaticVoidMethod(env, jm_notifyBusyMethod);
|
||||
} else {
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_notifyFreeMethod, jc_AWTAutoShutdown, "notifyToolkitThreadFree", "()V");
|
||||
JNFCallStaticVoidMethod(env, jm_notifyFreeMethod);
|
||||
}
|
||||
}
|
||||
|
||||
static void setUpAWTAppKit(BOOL installObservers)
|
||||
{
|
||||
if (installObservers) {
|
||||
AWT_STARTUP_LOG(@"Setting up busy observers");
|
||||
|
||||
// Add CFRunLoopObservers to call into AWT so that AWT knows that the
|
||||
// AWT thread (which is the AppKit main thread) is alive. This way AWT
|
||||
// will not automatically shutdown.
|
||||
CFRunLoopObserverRef busyObserver = CFRunLoopObserverCreateWithHandler(
|
||||
NULL, // CFAllocator
|
||||
kCFRunLoopAfterWaiting, // CFOptionFlags
|
||||
true, // repeats
|
||||
NSIntegerMax, // order
|
||||
^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
|
||||
setBusy(YES);
|
||||
});
|
||||
|
||||
CFRunLoopObserverRef notBusyObserver = CFRunLoopObserverCreateWithHandler(
|
||||
NULL, // CFAllocator
|
||||
kCFRunLoopBeforeWaiting, // CFOptionFlags
|
||||
true, // repeats
|
||||
NSIntegerMin, // order
|
||||
^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
|
||||
setBusy(NO);
|
||||
});
|
||||
|
||||
CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
|
||||
CFRunLoopAddObserver(runLoop, busyObserver, kCFRunLoopDefaultMode);
|
||||
CFRunLoopAddObserver(runLoop, notBusyObserver, kCFRunLoopDefaultMode);
|
||||
|
||||
CFRelease(busyObserver);
|
||||
CFRelease(notBusyObserver);
|
||||
|
||||
setBusy(YES);
|
||||
}
|
||||
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnv];
|
||||
static JNF_CLASS_CACHE(jc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit");
|
||||
static JNF_STATIC_MEMBER_CACHE(jsm_installToolkitThreadInJava, jc_LWCToolkit, "installToolkitThreadInJava", "()V");
|
||||
JNFCallStaticVoidMethod(env, jsm_installToolkitThreadInJava);
|
||||
}
|
||||
|
||||
BOOL isSWTInWebStart(JNIEnv* env) {
|
||||
NSString *swtWebStart = [PropertiesUtilities javaSystemPropertyForKey:@"com.apple.javaws.usingSWT" withEnv:env];
|
||||
return [@"true" isCaseInsensitiveLike:swtWebStart];
|
||||
}
|
||||
|
||||
static void AWT_NSUncaughtExceptionHandler(NSException *exception) {
|
||||
NSLog(@"Apple AWT Internal Exception: %@", [exception description]);
|
||||
}
|
||||
|
||||
@interface AWTStarter : NSObject
|
||||
+ (void)start:(BOOL)headless;
|
||||
+ (void)starter:(BOOL)onMainThread headless:(BOOL)headless;
|
||||
+ (void)appKitIsRunning:(id)arg;
|
||||
@end
|
||||
|
||||
@implementation AWTStarter
|
||||
|
||||
+ (BOOL) isConnectedToWindowServer {
|
||||
SecuritySessionId session_id;
|
||||
SessionAttributeBits session_info;
|
||||
OSStatus status = SessionGetInfo(callerSecuritySession, &session_id, &session_info);
|
||||
if (status != noErr) return NO;
|
||||
if (!(session_info & sessionHasGraphicAccess)) return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL) markAppAsDaemon {
|
||||
id jrsAppKitAWTClass = objc_getClass("JRSAppKitAWT");
|
||||
SEL markAppSel = @selector(markAppIsDaemon);
|
||||
if (![jrsAppKitAWTClass respondsToSelector:markAppSel]) return NO;
|
||||
return [jrsAppKitAWTClass performSelector:markAppSel] ? YES : NO;
|
||||
}
|
||||
|
||||
+ (void)appKitIsRunning:(id)arg {
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
AWT_STARTUP_LOG(@"About to message AppKit started");
|
||||
|
||||
// Signal that AppKit has started (or is already running).
|
||||
pthread_mutex_lock(&sAppKitStarted_mutex);
|
||||
sAppKitStarted = YES;
|
||||
pthread_cond_signal(&sAppKitStarted_cv);
|
||||
pthread_mutex_unlock(&sAppKitStarted_mutex);
|
||||
|
||||
AWT_STARTUP_LOG(@"Finished messaging AppKit started");
|
||||
}
|
||||
|
||||
+ (void)start:(BOOL)headless
|
||||
{
|
||||
// onMainThread is NOT the same at SWT mode!
|
||||
// If the JVM was started on the first thread for SWT, but the SWT loads the AWT on a secondary thread,
|
||||
// onMainThread here will be false but SWT mode will be true. If we are currently on the main thread, we don't
|
||||
// need to throw AWT startup over to another thread.
|
||||
BOOL onMainThread = [NSThread isMainThread];
|
||||
|
||||
NSString* msg = [NSString stringWithFormat:@"+[AWTStarter start headless:%d] { onMainThread:%d }", headless, onMainThread];
|
||||
AWT_STARTUP_LOG(msg);
|
||||
|
||||
if (!headless)
|
||||
{
|
||||
// Listen for the NSApp to start. This indicates that JNI_OnLoad can proceed.
|
||||
// It must wait because there is a chance that another java thread will grab
|
||||
// the AppKit lock before the +[NSApplication sharedApplication] returns.
|
||||
// See <rdar://problem/3492666> for an example.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:[AWTStarter class]
|
||||
selector:@selector(appKitIsRunning:)
|
||||
name:NSApplicationDidFinishLaunchingNotification
|
||||
object:nil];
|
||||
|
||||
AWT_STARTUP_LOG(@"+[AWTStarter start:::]: registered NSApplicationDidFinishLaunchingNotification");
|
||||
}
|
||||
|
||||
[ThreadUtilities performOnMainThreadWaiting:NO block:^() {
|
||||
[AWTStarter starter:onMainThread headless:headless];
|
||||
}];
|
||||
|
||||
|
||||
if (!headless && !onMainThread) {
|
||||
|
||||
AWT_STARTUP_LOG(@"about to wait on AppKit startup mutex");
|
||||
|
||||
// Wait here for AppKit to have started (or for AWT to have been loaded into
|
||||
// an already running NSApplication).
|
||||
pthread_mutex_lock(&sAppKitStarted_mutex);
|
||||
while (sAppKitStarted == NO) {
|
||||
pthread_cond_wait(&sAppKitStarted_cv, &sAppKitStarted_mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&sAppKitStarted_mutex);
|
||||
|
||||
// AWT gets here AFTER +[AWTStarter appKitIsRunning:] is called.
|
||||
AWT_STARTUP_LOG(@"got out of the AppKit startup mutex");
|
||||
}
|
||||
|
||||
if (!headless) {
|
||||
// Don't set the delegate until the NSApplication has been created and
|
||||
// its finishLaunching has initialized it.
|
||||
// ApplicationDelegate is the support code for com.apple.eawt.
|
||||
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
|
||||
id<NSApplicationDelegate> delegate = [ApplicationDelegate sharedDelegate];
|
||||
if (delegate != nil) {
|
||||
OSXAPP_SetApplicationDelegate(delegate);
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)starter:(BOOL)wasOnMainThread headless:(BOOL)headless {
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
// Add the exception handler of last resort
|
||||
NSSetUncaughtExceptionHandler(AWT_NSUncaughtExceptionHandler);
|
||||
|
||||
// Headless mode trumps either ordinary AWT or SWT-in-AWT mode. Declare us a daemon and return.
|
||||
if (headless) {
|
||||
// Note that we don't install run loop observers in headless mode
|
||||
// because we don't need them (see 7174704)
|
||||
if (!forceEmbeddedMode) {
|
||||
setUpAWTAppKit(false);
|
||||
}
|
||||
[AWTStarter markAppAsDaemon];
|
||||
return;
|
||||
}
|
||||
|
||||
if (forceEmbeddedMode) {
|
||||
AWT_STARTUP_LOG(@"in SWT or SWT/WebStart mode");
|
||||
|
||||
// Init a default NSApplication instance instead of the NSApplicationAWT.
|
||||
// Note that [NSApp isRunning] will return YES after that, though
|
||||
// this behavior isn't specified anywhere. We rely on that.
|
||||
NSApplicationLoad();
|
||||
}
|
||||
|
||||
// This will create a NSApplicationAWT for standalone AWT programs, unless there is
|
||||
// already a NSApplication instance. If there is already a NSApplication instance,
|
||||
// and -[NSApplication isRunning] returns YES, AWT is embedded inside another
|
||||
// AppKit Application.
|
||||
NSApplication *app = [NSApplicationAWT sharedApplication];
|
||||
BOOL isEmbedded = ![NSApp isKindOfClass:[NSApplicationAWT class]];
|
||||
[ThreadUtilities setAWTEmbedded:isEmbedded];
|
||||
|
||||
if (!isEmbedded) {
|
||||
// Install run loop observers and set the AppKit Java thread name
|
||||
setUpAWTAppKit(true);
|
||||
}
|
||||
|
||||
// AWT gets to this point BEFORE NSApplicationDidFinishLaunchingNotification is sent.
|
||||
if (![app isRunning]) {
|
||||
AWT_STARTUP_LOG(@"+[AWTStarter startAWT]: ![app isRunning]");
|
||||
// This is where the AWT AppKit thread parks itself to process events.
|
||||
[NSApplicationAWT runAWTLoopWithApp: app];
|
||||
} else {
|
||||
// We're either embedded, or showing a splash screen
|
||||
if (isEmbedded) {
|
||||
AWT_STARTUP_LOG(@"running embedded");
|
||||
|
||||
// We don't track if the runloop is busy, so set it free to let AWT finish when it needs
|
||||
setBusy(NO);
|
||||
} else {
|
||||
AWT_STARTUP_LOG(@"running after showing a splash screen");
|
||||
}
|
||||
|
||||
// Signal so that JNI_OnLoad can proceed.
|
||||
if (!wasOnMainThread) [AWTStarter appKitIsRunning:nil];
|
||||
|
||||
// Proceed to exit this call as there is no reason to run the NSApplication event loop.
|
||||
}
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_LWCToolkit
|
||||
* Method: nativeSyncQueue
|
||||
@ -169,52 +414,6 @@ Java_sun_lwawt_macosx_LWCToolkit_beep
|
||||
NSBeep(); // produces both sound and visual flash, if configured in System Preferences
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_LWCToolkit
|
||||
* Method: initIDs
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_lwawt_macosx_LWCToolkit_initIDs
|
||||
(JNIEnv *env, jclass klass) {
|
||||
// set thread names
|
||||
if (![ThreadUtilities isAWTEmbedded]) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void){
|
||||
[[NSThread currentThread] setName:@"AppKit Thread"];
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
static JNF_CLASS_CACHE(jc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit");
|
||||
static JNF_STATIC_MEMBER_CACHE(jsm_installToolkitThreadInJava, jc_LWCToolkit, "installToolkitThreadInJava", "()V");
|
||||
JNFCallStaticVoidMethod(env, jsm_installToolkitThreadInJava);
|
||||
});
|
||||
}
|
||||
|
||||
gNumberOfButtons = sun_lwawt_macosx_LWCToolkit_BUTTONS;
|
||||
|
||||
jclass inputEventClazz = (*env)->FindClass(env, "java/awt/event/InputEvent");
|
||||
CHECK_NULL(inputEventClazz);
|
||||
jmethodID getButtonDownMasksID = (*env)->GetStaticMethodID(env, inputEventClazz, "getButtonDownMasks", "()[I");
|
||||
CHECK_NULL(getButtonDownMasksID);
|
||||
jintArray obj = (jintArray)(*env)->CallStaticObjectMethod(env, inputEventClazz, getButtonDownMasksID);
|
||||
jint * tmp = (*env)->GetIntArrayElements(env, obj, JNI_FALSE);
|
||||
CHECK_NULL(tmp);
|
||||
|
||||
gButtonDownMasks = (jint*)SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(jint), gNumberOfButtons);
|
||||
if (gButtonDownMasks == NULL) {
|
||||
gNumberOfButtons = 0;
|
||||
(*env)->ReleaseIntArrayElements(env, obj, tmp, JNI_ABORT);
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < gNumberOfButtons; i++) {
|
||||
gButtonDownMasks[i] = tmp[i];
|
||||
}
|
||||
|
||||
(*env)->ReleaseIntArrayElements(env, obj, tmp, 0);
|
||||
(*env)->DeleteLocalRef(env, obj);
|
||||
}
|
||||
|
||||
static UInt32 RGB(NSColor *c) {
|
||||
c = [c colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
|
||||
if (c == nil)
|
||||
@ -443,3 +642,84 @@ Java_sun_font_FontManager_populateFontFileNameMap
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_LWCToolkit
|
||||
* Method: initIDs
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_lwawt_macosx_LWCToolkit_initIDs
|
||||
(JNIEnv *env, jclass klass) {
|
||||
|
||||
JNF_COCOA_ENTER(env)
|
||||
|
||||
gNumberOfButtons = sun_lwawt_macosx_LWCToolkit_BUTTONS;
|
||||
|
||||
jclass inputEventClazz = (*env)->FindClass(env, "java/awt/event/InputEvent");
|
||||
CHECK_NULL(inputEventClazz);
|
||||
jmethodID getButtonDownMasksID = (*env)->GetStaticMethodID(env, inputEventClazz, "getButtonDownMasks", "()[I");
|
||||
CHECK_NULL(getButtonDownMasksID);
|
||||
jintArray obj = (jintArray)(*env)->CallStaticObjectMethod(env, inputEventClazz, getButtonDownMasksID);
|
||||
jint * tmp = (*env)->GetIntArrayElements(env, obj, JNI_FALSE);
|
||||
CHECK_NULL(tmp);
|
||||
|
||||
gButtonDownMasks = (jint*)SAFE_SIZE_ARRAY_ALLOC(malloc, sizeof(jint), gNumberOfButtons);
|
||||
if (gButtonDownMasks == NULL) {
|
||||
gNumberOfButtons = 0;
|
||||
(*env)->ReleaseIntArrayElements(env, obj, tmp, JNI_ABORT);
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < gNumberOfButtons; i++) {
|
||||
gButtonDownMasks[i] = tmp[i];
|
||||
}
|
||||
|
||||
(*env)->ReleaseIntArrayElements(env, obj, tmp, 0);
|
||||
(*env)->DeleteLocalRef(env, obj);
|
||||
|
||||
JNF_COCOA_EXIT(env)
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_lwawt_macosx_LWCToolkit
|
||||
* Method: initAppkit
|
||||
* Signature: (Ljava/lang/ThreadGroup;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_lwawt_macosx_LWCToolkit_initAppkit
|
||||
(JNIEnv *env, jclass klass, jobject appkitThreadGroup, jboolean headless) {
|
||||
JNF_COCOA_ENTER(env)
|
||||
|
||||
[ThreadUtilities setAppkitThreadGroup:(*env)->NewGlobalRef(env, appkitThreadGroup)];
|
||||
|
||||
// Launcher sets this env variable if -XstartOnFirstThread is specified
|
||||
char envVar[80];
|
||||
snprintf(envVar, sizeof(envVar), "JAVA_STARTED_ON_FIRST_THREAD_%d", getpid());
|
||||
if (getenv(envVar) != NULL) {
|
||||
forceEmbeddedMode = YES;
|
||||
unsetenv(envVar);
|
||||
}
|
||||
|
||||
if (isSWTInWebStart(env)) {
|
||||
forceEmbeddedMode = YES;
|
||||
}
|
||||
|
||||
[AWTStarter start:headless ? YES : NO];
|
||||
|
||||
JNF_COCOA_EXIT(env)
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
OSXAPP_SetJavaVM(vm);
|
||||
|
||||
// We need to let Foundation know that this is a multithreaded application, if it isn't already.
|
||||
if (![NSThread isMultiThreaded]) {
|
||||
[NSThread detachNewThreadSelector:nil toTarget:nil withObject:nil];
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
|
@ -1,460 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import <pthread.h>
|
||||
#import <objc/runtime.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Security/AuthSession.h>
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
|
||||
|
||||
#import "NSApplicationAWT.h"
|
||||
#import "PropertiesUtilities.h"
|
||||
#import "ThreadUtilities.h"
|
||||
#import "AWT_debug.h"
|
||||
#import "ApplicationDelegate.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
|
||||
// The symbol is defined in libosxapp.dylib (ThreadUtilities.m)
|
||||
extern JavaVM *jvm;
|
||||
|
||||
// Indicates if AWT is running embedded (in SWT, FX, elsewhere)
|
||||
static BOOL isEmbedded = NO;
|
||||
|
||||
// Indicates that the app has been started with -XstartOnFirstThread
|
||||
// (directly or via WebStart settings), and AWT should not run its
|
||||
// own event loop in this mode. Even if a loop isn't running yet,
|
||||
// we expect an embedder (e.g. SWT) to start it some time later.
|
||||
static BOOL forceEmbeddedMode = NO;
|
||||
|
||||
static bool ShouldPrintVerboseDebugging() {
|
||||
static int debug = -1;
|
||||
if (debug == -1) {
|
||||
debug = (int)(getenv("JAVA_AWT_VERBOSE") != NULL) || (DEBUG != 0);
|
||||
}
|
||||
return (bool)debug;
|
||||
}
|
||||
|
||||
// This is the data necessary to have JNI_OnLoad wait for AppKit to start.
|
||||
static BOOL sAppKitStarted = NO;
|
||||
static pthread_mutex_t sAppKitStarted_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t sAppKitStarted_cv = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
void setBusy(BOOL isBusy);
|
||||
static void BusyObserver(CFRunLoopObserverRef ref, CFRunLoopActivity what, void* arg);
|
||||
static void NotBusyObserver(CFRunLoopObserverRef ref, CFRunLoopActivity what, void* arg);
|
||||
static void AWT_NSUncaughtExceptionHandler(NSException *exception);
|
||||
|
||||
static CFRunLoopObserverRef busyObserver = NULL;
|
||||
static CFRunLoopObserverRef notBusyObserver = NULL;
|
||||
|
||||
static void setUpAWTAppKit()
|
||||
{
|
||||
BOOL verbose = ShouldPrintVerboseDebugging();
|
||||
if (verbose) AWT_DEBUG_LOG(@"setting up busy observers");
|
||||
|
||||
// Add CFRunLoopObservers to call into AWT so that AWT knows that the
|
||||
// AWT thread (which is the AppKit main thread) is alive. This way AWT
|
||||
// will not automatically shutdown.
|
||||
busyObserver = CFRunLoopObserverCreate(
|
||||
NULL, // CFAllocator
|
||||
kCFRunLoopAfterWaiting, // CFOptionFlags
|
||||
true, // repeats
|
||||
NSIntegerMax, // order
|
||||
&BusyObserver, // CFRunLoopObserverCallBack
|
||||
NULL); // CFRunLoopObserverContext
|
||||
|
||||
notBusyObserver = CFRunLoopObserverCreate(
|
||||
NULL, // CFAllocator
|
||||
kCFRunLoopBeforeWaiting, // CFOptionFlags
|
||||
true, // repeats
|
||||
NSIntegerMin, // order
|
||||
&NotBusyObserver, // CFRunLoopObserverCallBack
|
||||
NULL); // CFRunLoopObserverContext
|
||||
|
||||
CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
|
||||
CFRunLoopAddObserver(runLoop, busyObserver, kCFRunLoopDefaultMode);
|
||||
CFRunLoopAddObserver(runLoop, notBusyObserver, kCFRunLoopDefaultMode);
|
||||
|
||||
CFRelease(busyObserver);
|
||||
CFRelease(notBusyObserver);
|
||||
|
||||
setBusy(YES);
|
||||
}
|
||||
|
||||
static void setUpAppKitThreadName()
|
||||
{
|
||||
BOOL verbose = ShouldPrintVerboseDebugging();
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
|
||||
// Set the java name of the AppKit main thread appropriately.
|
||||
jclass threadClass = NULL;
|
||||
jstring name = NULL;
|
||||
jobject curThread = NULL;
|
||||
|
||||
threadClass = (*env)->FindClass(env, "java/lang/Thread");
|
||||
if (threadClass == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
|
||||
jmethodID currentThreadID = (*env)->GetStaticMethodID(env, threadClass, "currentThread", "()Ljava/lang/Thread;");
|
||||
if (currentThreadID == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
|
||||
jmethodID setName = (*env)->GetMethodID(env, threadClass, "setName", "(Ljava/lang/String;)V");
|
||||
if (setName == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
|
||||
|
||||
curThread = (*env)->CallStaticObjectMethod(env, threadClass, currentThreadID); // AWT_THREADING Safe (known object)
|
||||
if (curThread == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
|
||||
name = (*env)->NewStringUTF(env, "AWT-AppKit");
|
||||
if (name == NULL || (*env)->ExceptionCheck(env)) goto cleanup;
|
||||
(*env)->CallVoidMethod(env, curThread, setName, name); // AWT_THREADING Safe (known object)
|
||||
if ((*env)->ExceptionCheck(env)) goto cleanup;
|
||||
|
||||
cleanup:
|
||||
if (threadClass != NULL) {
|
||||
(*env)->DeleteLocalRef(env, threadClass);
|
||||
}
|
||||
if (name != NULL) {
|
||||
(*env)->DeleteLocalRef(env, name);
|
||||
}
|
||||
if (curThread != NULL) {
|
||||
(*env)->DeleteLocalRef(env, curThread);
|
||||
}
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
(*env)->ExceptionDescribe(env);
|
||||
(*env)->ExceptionClear(env);
|
||||
}
|
||||
|
||||
if (verbose) AWT_DEBUG_LOG(@"finished setting thread name");
|
||||
}
|
||||
|
||||
|
||||
// Returns true if java believes it is running headless
|
||||
BOOL isHeadless(JNIEnv *env) {
|
||||
// Just access the property directly, instead of using GraphicsEnvironment.isHeadless.
|
||||
// This is because this may be called while AWT is being loaded, and calling AWT
|
||||
// while it is being loaded will deadlock.
|
||||
static JNF_CLASS_CACHE(jc_Toolkit, "java/awt/GraphicsEnvironment");
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_isHeadless, jc_Toolkit, "isHeadless", "()Z");
|
||||
return JNFCallStaticBooleanMethod(env, jm_isHeadless);
|
||||
}
|
||||
|
||||
BOOL isSWTInWebStart(JNIEnv* env) {
|
||||
NSString *swtWebStart = [PropertiesUtilities javaSystemPropertyForKey:@"com.apple.javaws.usingSWT" withEnv:env];
|
||||
return [@"true" isCaseInsensitiveLike:swtWebStart];
|
||||
}
|
||||
|
||||
void setBusy(BOOL busy) {
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnv];
|
||||
static JNF_CLASS_CACHE(jc_AWTAutoShutdown, "sun/awt/AWTAutoShutdown");
|
||||
|
||||
if (busy) {
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_notifyBusyMethod, jc_AWTAutoShutdown, "notifyToolkitThreadBusy", "()V");
|
||||
JNFCallStaticVoidMethod(env, jm_notifyBusyMethod);
|
||||
} else {
|
||||
static JNF_STATIC_MEMBER_CACHE(jm_notifyFreeMethod, jc_AWTAutoShutdown, "notifyToolkitThreadFree", "()V");
|
||||
JNFCallStaticVoidMethod(env, jm_notifyFreeMethod);
|
||||
}
|
||||
}
|
||||
|
||||
static void BusyObserver(CFRunLoopObserverRef ref, CFRunLoopActivity what, void* arg) {
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
// This is only called with the selector kCFRunLoopAfterWaiting.
|
||||
#ifndef PRODUCT_BUILD
|
||||
assert(what == kCFRunLoopAfterWaiting);
|
||||
#endif /* PRODUCT_BUILD */
|
||||
|
||||
setBusy(YES);
|
||||
}
|
||||
|
||||
static void NotBusyObserver(CFRunLoopObserverRef ref, CFRunLoopActivity what, void* arg) {
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
// This is only called with the selector kCFRunLoopBeforeWaiting.
|
||||
#ifndef PRODUCT_BUILD
|
||||
assert(what == kCFRunLoopBeforeWaiting);
|
||||
#endif /* PRODUCT_BUILD */
|
||||
|
||||
setBusy(NO);
|
||||
}
|
||||
|
||||
static void AWT_NSUncaughtExceptionHandler(NSException *exception) {
|
||||
NSLog(@"Apple AWT Internal Exception: %@", [exception description]);
|
||||
}
|
||||
|
||||
// This is an empty Obj-C object just so that -peformSelectorOnMainThread can be used.
|
||||
@interface AWTStarter : NSObject { }
|
||||
+ (void)start:(BOOL)headless;
|
||||
- (void)starter:(NSArray*)args;
|
||||
+ (void)appKitIsRunning:(id)arg;
|
||||
@end
|
||||
|
||||
@implementation AWTStarter
|
||||
|
||||
+ (BOOL) isConnectedToWindowServer {
|
||||
SecuritySessionId session_id;
|
||||
SessionAttributeBits session_info;
|
||||
OSStatus status = SessionGetInfo(callerSecuritySession, &session_id, &session_info);
|
||||
if (status != noErr) return NO;
|
||||
if (!(session_info & sessionHasGraphicAccess)) return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL) markAppAsDaemon {
|
||||
id jrsAppKitAWTClass = objc_getClass("JRSAppKitAWT");
|
||||
SEL markAppSel = @selector(markAppIsDaemon);
|
||||
if (![jrsAppKitAWTClass respondsToSelector:markAppSel]) return NO;
|
||||
return [jrsAppKitAWTClass performSelector:markAppSel] ? YES : NO;
|
||||
}
|
||||
|
||||
+ (void)appKitIsRunning:(id)arg {
|
||||
// Headless: NO
|
||||
// Embedded: BOTH
|
||||
// Multiple Calls: NO
|
||||
// Callers: AppKit's NSApplicationDidFinishLaunchingNotification or +[AWTStarter startAWT:]
|
||||
AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
BOOL verbose = ShouldPrintVerboseDebugging();
|
||||
if (verbose) AWT_DEBUG_LOG(@"about to message AppKit started");
|
||||
|
||||
// Signal that AppKit has started (or is already running).
|
||||
pthread_mutex_lock(&sAppKitStarted_mutex);
|
||||
sAppKitStarted = YES;
|
||||
pthread_cond_signal(&sAppKitStarted_cv);
|
||||
pthread_mutex_unlock(&sAppKitStarted_mutex);
|
||||
|
||||
if (verbose) AWT_DEBUG_LOG(@"finished messaging AppKit started");
|
||||
}
|
||||
|
||||
+ (void)start:(BOOL)headless
|
||||
{
|
||||
BOOL verbose = ShouldPrintVerboseDebugging();
|
||||
|
||||
// Headless: BOTH
|
||||
// Embedded: BOTH
|
||||
// Multiple Calls: NO
|
||||
// Caller: JNI_OnLoad
|
||||
|
||||
// onMainThread is NOT the same at SWT mode!
|
||||
// If the JVM was started on the first thread for SWT, but the SWT loads the AWT on a secondary thread,
|
||||
// onMainThread here will be false but SWT mode will be true. If we are currently on the main thread, we don't
|
||||
// need to throw AWT startup over to another thread.
|
||||
BOOL onMainThread = (pthread_main_np() != 0);
|
||||
|
||||
if (verbose) {
|
||||
NSString *msg = [NSString stringWithFormat:@"+[AWTStarter start headless:%d] { onMainThread:%d }", headless, onMainThread];
|
||||
AWT_DEBUG_LOG(msg);
|
||||
}
|
||||
|
||||
if (!headless)
|
||||
{
|
||||
// Listen for the NSApp to start. This indicates that JNI_OnLoad can proceed.
|
||||
// It must wait because there is a chance that another java thread will grab
|
||||
// the AppKit lock before the +[NSApplication sharedApplication] returns.
|
||||
// See <rdar://problem/3492666> for an example.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:[AWTStarter class]
|
||||
selector:@selector(appKitIsRunning:)
|
||||
name:NSApplicationDidFinishLaunchingNotification
|
||||
object:nil];
|
||||
|
||||
if (verbose) NSLog(@"+[AWTStarter start:::]: registered NSApplicationDidFinishLaunchingNotification");
|
||||
}
|
||||
|
||||
id st = [[AWTStarter alloc] init];
|
||||
|
||||
NSArray * args = [NSArray arrayWithObjects:
|
||||
[NSNumber numberWithBool: onMainThread],
|
||||
[NSNumber numberWithBool: headless],
|
||||
[NSNumber numberWithBool: verbose],
|
||||
nil];
|
||||
|
||||
if (onMainThread) {
|
||||
[st starter:args];
|
||||
} else {
|
||||
[st performSelectorOnMainThread: @selector(starter:) withObject:args waitUntilDone:NO];
|
||||
}
|
||||
|
||||
if (!headless && !onMainThread) {
|
||||
if (verbose) AWT_DEBUG_LOG(@"about to wait on AppKit startup mutex");
|
||||
|
||||
// Wait here for AppKit to have started (or for AWT to have been loaded into
|
||||
// an already running NSApplication).
|
||||
pthread_mutex_lock(&sAppKitStarted_mutex);
|
||||
while (sAppKitStarted == NO) {
|
||||
pthread_cond_wait(&sAppKitStarted_cv, &sAppKitStarted_mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&sAppKitStarted_mutex);
|
||||
|
||||
// AWT gets here AFTER +[AWTStarter appKitIsRunning:] is called.
|
||||
if (verbose) AWT_DEBUG_LOG(@"got out of the AppKit startup mutex");
|
||||
}
|
||||
|
||||
if (!headless) {
|
||||
// Don't set the delegate until the NSApplication has been created and
|
||||
// its finishLaunching has initialized it.
|
||||
// ApplicationDelegate is the support code for com.apple.eawt.
|
||||
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
|
||||
id<NSApplicationDelegate> delegate = [ApplicationDelegate sharedDelegate];
|
||||
if (delegate != nil) {
|
||||
OSXAPP_SetApplicationDelegate(delegate);
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)starter:(NSArray*)args {
|
||||
NSAutoreleasePool *pool = [NSAutoreleasePool new];
|
||||
|
||||
BOOL onMainThread = [[args objectAtIndex:0] boolValue];
|
||||
BOOL headless = [[args objectAtIndex:1] boolValue];
|
||||
BOOL verbose = [[args objectAtIndex:2] boolValue];
|
||||
|
||||
BOOL wasOnMainThread = onMainThread;
|
||||
|
||||
// Add the exception handler of last resort
|
||||
NSSetUncaughtExceptionHandler(AWT_NSUncaughtExceptionHandler);
|
||||
|
||||
// Headless mode trumps either ordinary AWT or SWT-in-AWT mode. Declare us a daemon and return.
|
||||
if (headless) {
|
||||
// Note that we don't install run loop observers in headless mode
|
||||
// because we don't need them (see 7174704)
|
||||
if (!forceEmbeddedMode) {
|
||||
setUpAppKitThreadName();
|
||||
}
|
||||
[AWTStarter markAppAsDaemon];
|
||||
return;
|
||||
}
|
||||
|
||||
if (forceEmbeddedMode) {
|
||||
if (verbose) NSLog(@"in SWT or SWT/WebStart mode");
|
||||
|
||||
// Init a default NSApplication instance instead of the NSApplicationAWT.
|
||||
// Note that [NSApp isRunning] will return YES after that, though
|
||||
// this behavior isn't specified anywhere. We rely on that.
|
||||
NSApplicationLoad();
|
||||
}
|
||||
|
||||
// This will create a NSApplicationAWT for standalone AWT programs, unless there is
|
||||
// already a NSApplication instance. If there is already a NSApplication instance,
|
||||
// and -[NSApplication isRunning] returns YES, AWT is embedded inside another
|
||||
// AppKit Application.
|
||||
NSApplication *app = [NSApplicationAWT sharedApplication];
|
||||
isEmbedded = ![NSApp isKindOfClass:[NSApplicationAWT class]];
|
||||
[ThreadUtilities setAWTEmbedded:isEmbedded];
|
||||
|
||||
if (!isEmbedded) {
|
||||
// Install run loop observers and set the AppKit Java thread name
|
||||
setUpAWTAppKit();
|
||||
setUpAppKitThreadName();
|
||||
}
|
||||
|
||||
// AWT gets to this point BEFORE NSApplicationDidFinishLaunchingNotification is sent.
|
||||
if (![app isRunning]) {
|
||||
if (verbose) AWT_DEBUG_LOG(@"+[AWTStarter startAWT]: ![app isRunning]");
|
||||
|
||||
// This is where the AWT AppKit thread parks itself to process events.
|
||||
[NSApplicationAWT runAWTLoopWithApp: app];
|
||||
} else {
|
||||
// We're either embedded, or showing a splash screen
|
||||
if (isEmbedded) {
|
||||
if (verbose) AWT_DEBUG_LOG(@"running embedded");
|
||||
|
||||
// We don't track if the runloop is busy, so set it free to let AWT finish when it needs
|
||||
setBusy(NO);
|
||||
} else {
|
||||
if (verbose) AWT_DEBUG_LOG(@"running after showing a splash screen");
|
||||
}
|
||||
|
||||
// Signal so that JNI_OnLoad can proceed.
|
||||
if (!wasOnMainThread) [AWTStarter appKitIsRunning:nil];
|
||||
|
||||
// Proceed to exit this call as there is no reason to run the NSApplication event loop.
|
||||
}
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
BOOL verbose = ShouldPrintVerboseDebugging();
|
||||
if (verbose) AWT_DEBUG_LOG(@"entered JNI_OnLoad");
|
||||
|
||||
// Headless: BOTH
|
||||
// Embedded: BOTH
|
||||
// Multiple Calls: NO
|
||||
// Caller: JavaVM classloader
|
||||
|
||||
// Keep a static reference for other archives.
|
||||
OSXAPP_SetJavaVM(vm);
|
||||
|
||||
JNIEnv *env = NULL;
|
||||
|
||||
// Need JNIEnv for JNF_COCOA_ENTER(env); macro below
|
||||
jint status = (*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4);
|
||||
if (status != JNI_OK || env == NULL) {
|
||||
AWT_DEBUG_LOG(@"Can't get JNIEnv");
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
JNF_COCOA_ENTER(env);
|
||||
|
||||
// Launcher sets this env variable if -XstartOnFirstThread is specified
|
||||
char envVar[80];
|
||||
snprintf(envVar, sizeof(envVar), "JAVA_STARTED_ON_FIRST_THREAD_%d", getpid());
|
||||
if (getenv(envVar) != NULL) {
|
||||
forceEmbeddedMode = YES;
|
||||
unsetenv(envVar);
|
||||
}
|
||||
|
||||
if (isSWTInWebStart(env)) {
|
||||
forceEmbeddedMode = YES;
|
||||
}
|
||||
JNIEnv* env = [ThreadUtilities getJNIEnvUncached];
|
||||
jclass jc_ThreadGroupUtils = (*env)->FindClass(env, "sun/awt/util/ThreadGroupUtils");
|
||||
jmethodID sjm_getRootThreadGroup = (*env)->GetStaticMethodID(env, jc_ThreadGroupUtils, "getRootThreadGroup", "()Ljava/lang/ThreadGroup;");
|
||||
jobject rootThreadGroup = (*env)->CallStaticObjectMethod(env, jc_ThreadGroupUtils, sjm_getRootThreadGroup);
|
||||
[ThreadUtilities setAppkitThreadGroup:(*env)->NewGlobalRef(env, rootThreadGroup)];
|
||||
// The current thread was attached in getJNIEnvUnchached.
|
||||
// Detach it back. It will be reattached later if needed with a proper TG
|
||||
[ThreadUtilities detachCurrentThread];
|
||||
|
||||
BOOL headless = isHeadless(env);
|
||||
|
||||
// We need to let Foundation know that this is a multithreaded application, if it isn't already.
|
||||
if (![NSThread isMultiThreaded]) {
|
||||
[NSThread detachNewThreadSelector:nil toTarget:nil withObject:nil];
|
||||
}
|
||||
|
||||
[AWTStarter start:headless];
|
||||
|
||||
JNF_COCOA_EXIT(env);
|
||||
|
||||
if (verbose) AWT_DEBUG_LOG(@"exiting JNI_OnLoad");
|
||||
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2014, 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
|
||||
@ -28,12 +28,16 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
bool ShouldPrintVerboseDebugging();
|
||||
|
||||
#define kInternalError "java/lang/InternalError"
|
||||
|
||||
#define AWT_DEBUG_LOG(str) \
|
||||
NSLog(@"\tCocoa AWT: %@ %@", str, [NSThread callStackSymbols])
|
||||
|
||||
#define AWT_STARTUP_LOG(str) \
|
||||
if (ShouldPrintVerboseDebugging()) AWT_DEBUG_LOG((str))
|
||||
|
||||
#define AWT_DEBUG_BUG_REPORT_MESSAGE \
|
||||
NSLog(@"\tPlease file a bug report at http://bugreport.java.com/bugreport \
|
||||
with this message and a reproducible test case.")
|
||||
|
34
jdk/src/macosx/native/sun/osxapp/AWT_debug.m
Normal file
34
jdk/src/macosx/native/sun/osxapp/AWT_debug.m
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#import "AWT_debug.h"
|
||||
|
||||
bool ShouldPrintVerboseDebugging() {
|
||||
static int debug = -1;
|
||||
if (debug == -1) {
|
||||
debug = (int)(getenv("JAVA_AWT_VERBOSE") != NULL);
|
||||
}
|
||||
return (bool)debug;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user