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    }