package org.gudy.azureus2.ui.swt.osx;
import java.lang.reflect.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.internal.C;
import org.eclipse.swt.widgets.*;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.util.AERunnable;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.ui.swt.Messages;
import org.gudy.azureus2.ui.swt.Utils;
import org.gudy.azureus2.ui.swt.config.wizard.ConfigureWizard;
import org.gudy.azureus2.ui.swt.help.AboutWindow;
import org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper;
import org.gudy.azureus2.ui.swt.nat.NatTestWindow;
import org.gudy.azureus2.ui.swt.speedtest.SpeedTestWizard;
import com.aelitis.azureus.ui.UIFunctions;
import com.aelitis.azureus.ui.UIFunctionsManager;
import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
/**
* You can exclude this file (or this whole path) for non OSX builds
*
* Hook some Cocoa specific abilities:
* - App->About <BR>
* - App->Preferences <BR>
* - App->Exit <BR>
* <BR>
* - OpenDocument (possible limited to only files?) <BR>
*
* This code was influenced by the
* <a href="http://www.transparentech.com/opensource/cocoauienhancer">
* CocoaUIEnhancer</a>, which was influenced by the
* <a href="http://www.simidude.com/blog/2008/macify-a-swt-application-in-a-cross-platform-way/">
* CarbonUIEnhancer from Agynami</a>.
*
* Both cocoa implementations are modified from
* <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.ui.cocoa/src/org/eclipse/ui/internal/cocoa/CocoaUIEnhancer.java">
* org.eclipse.ui.internal.cocoa.CocoaUIEnhancer</a>
*/
public class CocoaUIEnhancer
{
private static final boolean DEBUG = false;
private static Object /*Callback*/ callBack3;
private static long callBack3Addr;
private static Object /*Callback*/ callBack4;
private static long callBack4Addr;
private static CocoaUIEnhancer instance;
private static final int kServicesMenuItem = 4;
// private static final int kHideApplicationMenuItem = 6;
// private static final int kQuitMenuItem = 10;
//private static int NSWindowCloseButton = 0;
//private static int NSWindowDocumentIconButton = 4;
//private static int NSWindowMiniaturizeButton = 1;
private static int NSWindowToolbarButton = 3;
//private static int NSWindowZoomButton = 2;
private static long sel_application_openFile_;
private static long sel_application_openFiles_;
private static long sel_applicationShouldHandleReopen_;
private static long sel_toolbarButtonClicked_;
private static boolean alreadyHaveOpenDoc;
static final byte[] SWT_OBJECT = {
'S',
'W',
'T',
'_',
'O',
'B',
'J',
'E',
'C',
'T',
'\0'
};
private long delegateIdSWTApplication;
private long delegateJniRef;
private Object delegate;
private static boolean initialized = false;
private static Class<?> osCls = classForName("org.eclipse.swt.internal.cocoa.OS");
private static Class<?> nsmenuCls = classForName("org.eclipse.swt.internal.cocoa.NSMenu");
private static Class<?> nsmenuitemCls = classForName("org.eclipse.swt.internal.cocoa.NSMenuItem");
private static Class<?> nsapplicationCls = classForName("org.eclipse.swt.internal.cocoa.NSApplication");
private static Class<?> nsarrayCls = classForName("org.eclipse.swt.internal.cocoa.NSArray");
private static Class<?> nsstringCls = classForName("org.eclipse.swt.internal.cocoa.NSString");
private static Class<?> nsidCls = classForName("org.eclipse.swt.internal.cocoa.id");
private static Class<?> nsautoreleasepoolCls = classForName("org.eclipse.swt.internal.cocoa.NSAutoreleasePool");
private static Class<?> nsworkspaceCls = classForName("org.eclipse.swt.internal.cocoa.NSWorkspace");
private static Class<?> nsimageCls = classForName("org.eclipse.swt.internal.cocoa.NSImage");
private static Class<?> nssizeCls = classForName("org.eclipse.swt.internal.cocoa.NSSize");
static {
Class<CocoaUIEnhancer> clazz = CocoaUIEnhancer.class;
Class<?> callbackCls = classForName("org.eclipse.swt.internal.Callback");
try {
SWT.class.getDeclaredField("OpenDocument");
alreadyHaveOpenDoc = true;
} catch (Throwable t) {
alreadyHaveOpenDoc = false;
}
try {
Method mGetAddress = callbackCls.getMethod("getAddress", new Class[0]);
Constructor<?> consCallback = callbackCls.getConstructor(new Class<?>[] {
Object.class,
String.class,
int.class
});
//callBack3 = new Callback(clazz, "actionProc", 3);
callBack3 = consCallback.newInstance(new Object[] {
clazz,
"actionProc",
3
});
Object object = mGetAddress.invoke(callBack3, (Object[]) null);
callBack3Addr = convertToLong(object);
if (callBack3Addr == 0) {
SWT.error(SWT.ERROR_NO_MORE_CALLBACKS);
}
//callBack4 = new Callback(clazz, "actionProc", 4);
callBack4 = consCallback.newInstance(new Object[] {
clazz,
"actionProc",
4
});
object = mGetAddress.invoke(callBack4, (Object[]) null);
callBack4Addr = convertToLong(object);
if (callBack4Addr == 0) {
SWT.error(SWT.ERROR_NO_MORE_CALLBACKS);
}
} catch (Throwable e) {
Debug.out(e);
}
}
static int /*long*/actionProc(int /*long*/id, int /*long*/sel,
int /*long*/arg0) {
return (int)actionProc((long)id, (long)sel, (long)arg0);
}
static long actionProc(long id, long sel,
long arg0) {
if (DEBUG) {
System.err.println("id=" + id + ";sel=" + sel);
}
if (sel == sel_toolbarButtonClicked_) {
try {
Field fldsel_window = osCls.getField("sel_window");
Object windowId = invoke(osCls, "objc_msgSend", new Object[] {
wrapPointer(arg0),
fldsel_window.get(null)
});
final Shell shellAffected = (Shell) invoke(Display.class,
Display.getCurrent(), "findWidget", new Object[] {
windowId
});
Utils.execSWTThread(new AERunnable() {
public void runSupport() {
int type;
Long l = (Long) shellAffected.getData("OSX.ToolBarToggle");
if (l == null || l.longValue() == 0) {
type = SWT.Collapse;
} else {
type = SWT.Expand;
}
Event event = new Event();
event.type = type;
event.display = shellAffected.getDisplay();
event.widget = shellAffected;
shellAffected.notifyListeners(type, event);
shellAffected.setData("OSX.ToolBarToggle", new Long(
type == SWT.Collapse ? 1 : 0));
}
});
} catch (Throwable t) {
Debug.out(t);
}
}
return 0;
}
static int /*long*/actionProc(int /*long*/id, int /*long*/sel,
int /*long*/arg0, int /*long*/arg1)
throws Throwable {
return (int)actionProc((long)id, (long)sel, (long)arg0, (long)arg1);
}
static long actionProc(long id, long sel,
long arg0, long arg1)
throws Throwable {
if (DEBUG) {
System.err.println("actionProc 4 " + id + "/" + sel);
}
Display display = Display.getCurrent();
if (display == null)
return 0;
if (!alreadyHaveOpenDoc && sel == sel_application_openFile_) {
Constructor<?> conNSString = nsstringCls.getConstructor(new Class[] {
int.class
});
Object file = conNSString.newInstance(arg1);
String fileString = (String) invoke(file, "getString");
if (DEBUG) {
System.err.println("OMG GOT OpenFile " + fileString);
}
OSXFileOpen.fileOpen(fileString);
} else if (!alreadyHaveOpenDoc && sel == sel_application_openFiles_) {
Constructor<?> conNSArray = nsarrayCls.getConstructor(new Class[] {
int.class
});
Constructor<?> conNSString = nsstringCls.getConstructor(new Class[] {
nsidCls
});
Object arrayOfFiles = conNSArray.newInstance(arg1);
int count = ((Number) invoke(arrayOfFiles, "count")).intValue();
String[] files = new String[count];
for (int i = 0; i < count; i++) {
Object fieldId = invoke(nsarrayCls, arrayOfFiles, "objectAtIndex",
new Object[] {
i
});
Object nsstring = conNSString.newInstance(fieldId);
files[i] = (String) invoke(nsstring, "getString");
if (DEBUG) {
System.err.println("OMG GOT OpenFiles " + files[i]);
}
}
OSXFileOpen.fileOpen(files);
} else if (sel == sel_applicationShouldHandleReopen_) {
Event event = new Event ();
event.detail = 1;
if (display != null) {
invoke(Display.class, display, "sendEvent", new Class[] {
int.class,
Event.class
}, new Object[] {
SWT.Activate,
event
});
}
}
return 0;
}
private static Class<?> classForName(String classname) {
try {
Class<?> cls = Class.forName(classname);
return cls;
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
}
}
private static long convertToLong(Object object) {
if (object instanceof Integer) {
Integer i = (Integer) object;
return i.longValue();
}
if (object instanceof Long) {
Long l = (Long) object;
return l.longValue();
}
return 0;
}
public static CocoaUIEnhancer getInstance() {
if (instance == null) {
try {
instance = new CocoaUIEnhancer();
} catch (Throwable e) {
Debug.out(e);
}
}
return instance;
}
private static Object invoke(Class<?> clazz, Object target,
String methodName, Object[] args) {
try {
Class<?>[] signature = new Class<?>[args.length];
for (int i = 0; i < args.length; i++) {
Class<?> thisClass = args[i].getClass();
if (thisClass == Integer.class)
signature[i] = int.class;
else if (thisClass == Long.class)
signature[i] = long.class;
else if (thisClass == Byte.class)
signature[i] = byte.class;
else if (thisClass == Boolean.class)
signature[i] = boolean.class;
else
signature[i] = thisClass;
}
Method method = clazz.getMethod(methodName, signature);
return method.invoke(target, args);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private static Object invoke(Class<?> clazz, Object target,
String methodName, Class[] signature, Object[] args) {
try {
Method method = clazz.getDeclaredMethod(methodName, signature);
method.setAccessible(true);
return method.invoke(target, args);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private static Object invoke(Class<?> clazz, String methodName, Object[] args) {
return invoke(clazz, null, methodName, args);
}
private static Object invoke(Object obj, String methodName) {
return invoke(obj, methodName, (Class<?>[]) null, (Object[]) null);
}
private static Object invoke(Object obj, String methodName,
Class<?>[] paramTypes, Object... arguments) {
try {
Method m = obj.getClass().getMethod(methodName, paramTypes);
return m.invoke(obj, arguments);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private static long registerName(Class<?> osCls, String name)
throws IllegalArgumentException, SecurityException,
IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Object object = invoke(osCls, "sel_registerName", new Object[] {
name
});
return convertToLong(object);
}
////////////////////////////////////////////////////////////
private static Object wrapPointer(long value) {
Class<?> PTR_CLASS = C.PTR_SIZEOF == 8 ? long.class : int.class;
if (PTR_CLASS == long.class)
return new Long(value);
else
return new Integer((int) value);
}
private CocoaUIEnhancer()
throws Throwable {
// Instead of creating a new delegate class in objective-c,
// just use the current SWTApplicationDelegate. An instance of this
// is a field of the Cocoa Display object and is already the target
// for the menuItems. So just get this class and add the new methods
// to it.
Object delegateObjSWTApplication = invoke(osCls, "objc_lookUpClass",
new Object[] {
"SWTApplicationDelegate"
});
delegateIdSWTApplication = convertToLong(delegateObjSWTApplication);
// This doesn't feel right, but it works
Class<?> swtapplicationdelegateCls = classForName("org.eclipse.swt.internal.cocoa.SWTApplicationDelegate");
delegate = swtapplicationdelegateCls.newInstance();
Object delegateAlloc = invoke(delegate, "alloc");
invoke(delegateAlloc, "init");
Object delegateIdObj = nsidCls.getField("id").get(delegate);
delegateJniRef = ((Number) invoke(osCls, "NewGlobalRef", new Class<?>[] {
Object.class
}, new Object[] {
CocoaUIEnhancer.this
})).longValue();
if (delegateJniRef == 0)
SWT.error(SWT.ERROR_NO_HANDLES);
//OS.object_setInstanceVariable(delegate.id, SWT_OBJECT, delegateJniRef);
invoke(osCls, "object_setInstanceVariable", new Object[] {
delegateIdObj,
SWT_OBJECT,
wrapPointer(delegateJniRef)
});
}
/**
* Hook the given Listener to the Mac OS X application Quit menu and the IActions to the About
* and Preferences menus.
*
*/
public void hookApplicationMenu() {
Display display = Display.getCurrent();
try {
// Initialize the menuItems.
initialize();
} catch (Exception e) {
throw new IllegalStateException(e);
}
// Schedule disposal of callback object
display.disposeExec(new Runnable() {
public void run() {
invoke(callBack3, "dispose");
callBack3 = null;
invoke(callBack4, "dispose");
callBack4 = null;
if (delegateJniRef != 0) {
//OS.DeleteGlobalRef(delegateJniRef);
invoke(osCls, "DeleteGlobalRef", new Object[] {
wrapPointer(delegateJniRef)
});
delegateJniRef = 0;
}
if (delegate != null) {
invoke(delegate, "release");
delegate = null;
}
}
});
}
public void hookDocumentOpen()
throws Throwable {
if (alreadyHaveOpenDoc) {
return;
}
if (sel_application_openFile_ == 0) {
sel_application_openFile_ = registerName(osCls, "application:openFile:");
}
invoke(osCls, "class_addMethod", new Object[] {
wrapPointer(delegateIdSWTApplication),
wrapPointer(sel_application_openFile_),
wrapPointer(callBack4Addr),
"@:@:@"
});
if (sel_application_openFiles_ == 0) {
sel_application_openFiles_ = registerName(osCls, "application:openFiles:");
}
invoke(osCls, "class_addMethod", new Object[] {
wrapPointer(delegateIdSWTApplication),
wrapPointer(sel_application_openFiles_),
wrapPointer(callBack4Addr),
"@:@:@"
});
}
static MenuItem getItem(Menu menu, int id) {
MenuItem[] items = menu.getItems();
// for (int i = 0; i < items.length; i++) {
// if (items[i].getID() == id) return items[i];
// }
return null;
}
private void initialize()
throws Exception {
// Get the Mac OS X Application menu.
Object sharedApplication = invoke(nsapplicationCls, "sharedApplication");
Object mainMenu = invoke(sharedApplication, "mainMenu");
Object mainMenuItem = invoke(nsmenuCls, mainMenu, "itemAtIndex",
new Object[] {
wrapPointer(0)
});
Object appMenu = invoke(mainMenuItem, "submenu");
// disable services menu
Object servicesMenuItem = invoke(nsmenuCls, appMenu, "itemAtIndex",
new Object[] {
wrapPointer(kServicesMenuItem)
});
invoke(nsmenuitemCls, servicesMenuItem, "setEnabled", new Object[] {
false
});
// Menu systemMenu = Display.getCurrent().getSystemMenu();
// if (systemMenu != null) {
//MenuItem sysItem = getItem(systemMenu, SWT.ID_ABOUT);
// if (sysItem != null) {
// sysItem.addSelectionListener(new SelectionAdapter() {
// public void widgetSelected(SelectionEvent e) {
// AboutWindow.show();
// };
// });
// }
//
// //sysItem = getItem(systemMenu);
// if (sysItem != null) {
// sysItem.addSelectionListener(new SelectionAdapter() {
// public void widgetSelected(SelectionEvent e) {
// UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
// if (uiFunctions != null) {
// uiFunctions.openView(UIFunctions.VIEW_CONFIG, null);
// }
// };
// });
// }
//
// //int quitIndex = systemMenu.indexOf(getItem(systemMenu, SWT.ID_QUIT));
// MenuItem restartItem = new MenuItem(systemMenu, SWT.CASCADE, quitIndex);
// Messages.setLanguageText(restartItem, "MainWindow.menu.file.restart");
// restartItem.addSelectionListener(new SelectionAdapter() {
// public void widgetSelected(SelectionEvent e) {
// UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
// if (uiFunctions != null) {
// uiFunctions.dispose(true, false);
// }
// }
// });
//
// // Add other menus
// boolean isAZ3 = "az3".equalsIgnoreCase(COConfigurationManager.getStringParameter("ui"));
//
// if (!isAZ3) {
// // add Wizard, NAT Test, Speed Test
//
// int prefIndex = systemMenu.indexOf(getItem(systemMenu,
// SWT.ID_PREFERENCES)) + 1;
// MenuItem wizItem = new MenuItem(systemMenu, SWT.CASCADE, prefIndex);
// Messages.setLanguageText(wizItem, "MainWindow.menu.file.configure");
// wizItem.addSelectionListener(new SelectionAdapter() {
// public void widgetSelected(SelectionEvent e) {
// new ConfigureWizard(false, ConfigureWizard.WIZARD_MODE_FULL);
// }
// });
//
// MenuItem natMenu = new MenuItem(systemMenu, SWT.CASCADE, prefIndex);
// Messages.setLanguageText(natMenu, "MainWindow.menu.tools.nattest");
// natMenu.addSelectionListener(new SelectionAdapter() {
// public void widgetSelected(SelectionEvent e) {
// new NatTestWindow();
// }
// });
//
// MenuItem netstatMenu = new MenuItem(systemMenu, SWT.CASCADE, prefIndex);
// Messages.setLanguageText(netstatMenu, "MainWindow.menu.tools.netstat");
// netstatMenu.addSelectionListener(new SelectionAdapter() {
// public void widgetSelected(SelectionEvent e) {
// UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
// if (uiFunctions != null) {
//
// PluginsMenuHelper.IViewInfo[] views = PluginsMenuHelper.getInstance().getPluginViewsInfo();
//
// for ( PluginsMenuHelper.IViewInfo view: views ){
//
// String viewID = view.viewID;
//
// if ( viewID != null && viewID.equals( "aznetstatus" )){
//
// view.openView( uiFunctions );
// }
// }
// }
// }
// });
//
// MenuItem speedMenu = new MenuItem(systemMenu, SWT.CASCADE, prefIndex);
// Messages.setLanguageText(speedMenu, "MainWindow.menu.tools.speedtest");
// speedMenu.addSelectionListener(new SelectionAdapter() {
// public void widgetSelected(SelectionEvent e) {
// new SpeedTestWizard();
// }
// });
//
// }
// }
//
// // Register names in objective-c.
// if (sel_applicationShouldHandleReopen_ == 0) {
// sel_applicationShouldHandleReopen_ = registerName(osCls, "applicationShouldHandleReopen:hasVisibleWindows:");
// }
//
// // Add the action callbacks for menu items.
// invoke(osCls, "class_addMethod", new Object[] {
// wrapPointer(delegateIdSWTApplication),
// wrapPointer(sel_applicationShouldHandleReopen_),
// wrapPointer(callBack4Addr),
// "@:@c"
// });
//
// initialized = true;
}
private Object invoke(Class<?> cls, String methodName) {
return invoke(cls, methodName, (Class<?>[]) null, (Object[]) null);
}
private Object invoke(Class<?> cls, String methodName, Class<?>[] paramTypes,
Object... arguments) {
try {
Method m = cls.getMethod(methodName, paramTypes);
return m.invoke(null, arguments);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
public void registerToolbarToggle(Shell shell)
throws Throwable {
if (sel_toolbarButtonClicked_ == 0) {
sel_toolbarButtonClicked_ = registerName(osCls, "toolbarButtonClicked:");
}
invoke(osCls, "class_addMethod", new Object[] {
wrapPointer(delegateIdSWTApplication),
wrapPointer(sel_toolbarButtonClicked_),
wrapPointer(callBack3Addr),
"@:@"
});
Class<?> nstoolbarCls = classForName("org.eclipse.swt.internal.cocoa.NSToolbar");
Class<?> nsbuttonCls = classForName("org.eclipse.swt.internal.cocoa.NSButton");
//NSToolbar dummyBar = new NSToolbar();
Object dummyBar = nstoolbarCls.newInstance();
//dummyBar.alloc();
invoke(dummyBar, "alloc");
//dummyBar.initWithIdentifier(NSString.stringWith("SWTToolbar"));
Object nsStrDummyToolbar = invoke(nsstringCls, "stringWith", new Object[] {
"SWTToolbar"
});
invoke(dummyBar, "initWithIdentifier", new Class<?>[] {
nsstringCls
}, new Object[] {
nsStrDummyToolbar
});
//dummyBar.setVisible(false);
invoke(dummyBar, "setVisible", new Class<?>[] {
boolean.class
}, new Object[] {
Boolean.FALSE
});
// reflect me
//NSWindow nsWindow = shell.view.window();
Object view = shell.getClass().getField("view").get(shell);
Object nsWindow = invoke(view, "window");
//nsWindow.setToolbar(dummyBar);
invoke(nsWindow, "setToolbar", new Class<?>[] {
nstoolbarCls
}, new Object[] {
dummyBar
});
//nsWindow.setShowsToolbarButton(true);
invoke(nsWindow, "setShowsToolbarButton", new Class<?>[] {
boolean.class
}, new Object[] {
Boolean.TRUE
});
//NSButton toolbarButton = nsWindow.standardWindowButton(NSWindowToolbarButton);
Object toolbarButton = invoke(nsWindow, "standardWindowButton",
new Class<?>[] {
int.class
}, new Object[] {
new Integer(NSWindowToolbarButton)
});
//toolbarButton.setTarget(delegate);
invoke(toolbarButton, "setTarget", new Class[] {
nsidCls
}, new Object[] {
delegate
});
//OS.objc_msgSend(this.id, OS.sel_setTarget_, anObject != null ? anObject.id : 0);
//invoke(osCls, "objc_msgSend", new Object[] {
// toolbarButton.getClass().getField("id").get(toolbarButton),
// osCls.getField("sel_setTarget_").get(null),
// wrapPointer(delegateIdSWTApplication)
//});
//toolbarButton.setAction((int) sel_toolbarButtonClicked_);
invoke(nsbuttonCls, toolbarButton, "setAction", new Object[] {
wrapPointer(sel_toolbarButtonClicked_)
});
}
// from Program.getImageData, except returns bigger images
public static Image getFileIcon (String path, int imageWidthHeight) {
Object pool = null;
try {
//NSAutoreleasePool pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
pool = nsautoreleasepoolCls.newInstance();
Object delegateAlloc = invoke(pool, "alloc");
invoke(delegateAlloc, "init");
//NSWorkspace workspace = NSWorkspace.sharedWorkspace();
Object workspace = invoke(nsworkspaceCls, "sharedWorkspace", new Object[] {});
//NSString fullPath = NSString.stringWith(path);
Object fullPath = invoke(nsstringCls, "stringWith", new Object[] {
path
});
if (fullPath != null) {
// SWT also had a :
// fullPath = workspace.fullPathForApplication(NSString.stringWith(name));
// which might be handy someday, but for now, full path works
//NSImage nsImage = workspace.iconForFile(fullPath);
Object nsImage = invoke(workspace, "iconForFile", new Class[] {
nsstringCls
}, new Object[] {
fullPath
});
if (nsImage != null) {
//NSSize size = new NSSize();
Object size = nssizeCls.newInstance();
//size.width = size.height = imageWidthHeight;
nssizeCls.getField("width").set(size, imageWidthHeight);
nssizeCls.getField("height").set(size, imageWidthHeight);
//nsImage.setSize(size);
invoke(nsImage, "setSize", new Class[] {
nssizeCls
}, new Object[] {
size
});
//nsImage.retain();
invoke(nsImage, "retain");
//Image image = Image.cocoa_new(Display.getCurrent(), SWT.BITMAP, nsImage);
Image image = (Image) invoke(Image.class, null, "cocoa_new",
new Class[] {
Device.class,
int.class,
nsimageCls
}, new Object[] {
Display.getCurrent(),
SWT.BITMAP,
nsImage
});
return image;
}
}
} catch (Throwable t) {
Debug.printStackTrace(t);
} finally {
if (pool != null) {
invoke(pool, "release");
}
}
return null;
}
public static boolean isInitialized() {
return initialized;
}
}