001 package org.bridj.jawt;
002 import static org.bridj.jawt.JawtLibrary.*;
003 import org.bridj.BridJ;
004 import org.bridj.JNI;
005 import org.bridj.NativeLibrary;
006 import org.bridj.Pointer;
007 import static org.bridj.Pointer.*;
008 import java.awt.*;
009 import java.io.File;
010 import org.bridj.Platform;
011
012 import org.bridj.ann.Convention;
013 /**
014 * Contains a method that returns the native peer handle of an AWT component : BridJ JAWT utilities {@link org.bridj.jawt.JAWTUtils#getNativePeerHandle(java.awt.Component)}
015 */
016 public class JAWTUtils {
017
018 public static JNIEnv getJNIEnv() {
019 return new JNIEnv(JNI.getEnv());
020 }
021
022 public static JAWT getJAWT(JNIEnv env) {
023 if (GraphicsEnvironment.isHeadless())
024 throw new HeadlessException("No native peers in headless mode.");
025
026 JAWT awt = new JAWT().version(JAWT_VERSION_1_4);
027 Pointer<JAWT> pAwt = pointerTo(awt);
028 if (!JAWT_GetAWT(env, pAwt))
029 throw new RuntimeException("Failed to get JAWT pointer !");
030
031 return pAwt.get();
032 }
033
034 public interface LockedComponentRunnable {
035 void run(Component component, long peer);
036 }
037
038 public static void withLockedSurface(JNIEnv env, JAWT awt, Component component, LockedComponentRunnable runnable) {
039 if (component.isLightweight())
040 throw new IllegalArgumentException("Lightweight components do not have native peers.");
041
042 if (!component.isDisplayable())
043 throw new IllegalArgumentException("Component that are not displayable do not have native peers.");
044
045 Pointer<?> componentPointer = JNI.getGlobalPointer(component);
046
047 Pointer<JAWT_DrawingSurface> pSurface = awt.GetDrawingSurface().get().invoke(env, componentPointer).as(JAWT_DrawingSurface.class);
048 if (pSurface == null)
049 throw new RuntimeException("Cannot get drawing surface from " + component);
050
051 JAWT_DrawingSurface surface = pSurface.get();
052
053 try {
054 int lock = surface.Lock().get().invoke(pSurface);
055 if ((lock & JAWT_LOCK_ERROR) != 0)
056 throw new RuntimeException("Cannot lock drawing surface of " + component);
057 try {
058 Pointer<JAWT_DrawingSurface.GetDrawingSurfaceInfo_callback> cb = surface.GetDrawingSurfaceInfo().as(JAWT_DrawingSurface.GetDrawingSurfaceInfo_callback.class);
059 Pointer<org.bridj.jawt.JAWT_DrawingSurfaceInfo > pInfo = cb.get().invoke(pSurface);
060 if (pInfo != null)
061 pInfo = pInfo.as(JAWT_DrawingSurfaceInfo.class);
062 Pointer<?> platformInfo = pInfo.get().platformInfo();
063 long peer = platformInfo.getSizeT(); // on win, mac, x11 platforms, the relevant field is the first in the struct !
064 runnable.run(component, peer);
065 } finally {
066 surface.Unlock().get().invoke(pSurface);
067 }
068 } finally {
069 awt.FreeDrawingSurface().get().invoke(pSurface);
070 }
071 }
072 /**
073 *
074 */
075 public static long getNativePeerHandle(Component component) {
076 try {
077 JNIEnv env = getJNIEnv();
078 JAWT awt = getJAWT(env);
079 final long ret[] = new long[1];
080 withLockedSurface(env, awt, component, new LockedComponentRunnable() {
081 public void run(Component component, long peer) {
082 ret[0] = peer;
083 }
084 });
085 return ret[0];
086 } catch (Throwable ex) {
087 ex.printStackTrace();
088 return 0;
089 }
090 }
091
092 }