001/* 002 * BridJ - Dynamic and blazing-fast native interop for Java. 003 * http://bridj.googlecode.com/ 004 * 005 * Copyright (c) 2010-2013, Olivier Chafik (http://ochafik.com/) 006 * All rights reserved. 007 * 008 * Redistribution and use in source and binary forms, with or without 009 * modification, are permitted provided that the following conditions are met: 010 * 011 * * Redistributions of source code must retain the above copyright 012 * notice, this list of conditions and the following disclaimer. 013 * * Redistributions in binary form must reproduce the above copyright 014 * notice, this list of conditions and the following disclaimer in the 015 * documentation and/or other materials provided with the distribution. 016 * * Neither the name of Olivier Chafik nor the 017 * names of its contributors may be used to endorse or promote products 018 * derived from this software without specific prior written permission. 019 * 020 * THIS SOFTWARE IS PROVIDED BY OLIVIER CHAFIK AND CONTRIBUTORS ``AS IS'' AND ANY 021 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 023 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 024 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 027 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 030 */ 031package org.bridj.jawt; 032 033import static org.bridj.jawt.JawtLibrary.*; 034import org.bridj.BridJ; 035import org.bridj.JNI; 036import org.bridj.NativeLibrary; 037import org.bridj.Pointer; 038import static org.bridj.Pointer.*; 039import java.awt.*; 040import java.io.File; 041import org.bridj.Platform; 042 043import org.bridj.ann.Convention; 044 045/** 046 * Contains a method that returns the native peer handle of an AWT component : 047 * BridJ JAWT utilities 048 * {@link org.bridj.jawt.JAWTUtils#getNativePeerHandle(java.awt.Component)} 049 * 050 * <p>Note that this does not work anymore on Mac OS X 051 * (<a href="http://forum.lwjgl.org/index.php?topic=4326.0">see this thread</a>). 052 */ 053public class JAWTUtils { 054 055 public static JNIEnv getJNIEnv() { 056 return new JNIEnv(JNI.getEnv()); 057 } 058 059 public static JAWT getJAWT(JNIEnv env) { 060 if (GraphicsEnvironment.isHeadless()) { 061 throw new HeadlessException("No native peers in headless mode."); 062 } 063 064 JAWT awt = new JAWT().version(JAWT_VERSION_1_4); 065 Pointer<JAWT> pAwt = getPointer(awt); 066 if (!JAWT_GetAWT(env, pAwt)) { 067 throw new RuntimeException("Failed to get JAWT pointer !"); 068 } 069 070 return pAwt.get(); 071 } 072 073 public interface LockedComponentRunnable { 074 075 void run(Component component, long peer); 076 } 077 078 public static void withLockedSurface(JNIEnv env, JAWT awt, Component component, LockedComponentRunnable runnable) { 079 if (component.isLightweight()) { 080 throw new IllegalArgumentException("Lightweight components do not have native peers."); 081 } 082 083 if (!component.isDisplayable()) { 084 throw new IllegalArgumentException("Component that are not displayable do not have native peers."); 085 } 086 087 Pointer<?> componentPointer = JNI.getGlobalPointer(component); 088 089 Pointer<JAWT_DrawingSurface> pSurface = awt.GetDrawingSurface().get().invoke(env, componentPointer).as(JAWT_DrawingSurface.class); 090 if (pSurface == null) { 091 throw new RuntimeException("Cannot get drawing surface from " + component); 092 } 093 094 JAWT_DrawingSurface surface = pSurface.get(); 095 096 try { 097 int lock = surface.Lock().get().invoke(pSurface); 098 if ((lock & JAWT_LOCK_ERROR) != 0) { 099 throw new RuntimeException("Cannot lock drawing surface of " + component); 100 } 101 try { 102 Pointer<JAWT_DrawingSurface.GetDrawingSurfaceInfo_callback> cb = surface.GetDrawingSurfaceInfo().as(JAWT_DrawingSurface.GetDrawingSurfaceInfo_callback.class); 103 Pointer<org.bridj.jawt.JAWT_DrawingSurfaceInfo> pInfo = cb.get().invoke(pSurface); 104 if (pInfo != null) { 105 pInfo = pInfo.as(JAWT_DrawingSurfaceInfo.class); 106 } 107 Pointer<?> platformInfo = pInfo.get().platformInfo(); 108 long peer; 109 if (Platform.isMacOSX()) { 110 peer = platformInfo.getPeer(); 111 } else { 112 peer = platformInfo.getSizeT(); // on win, mac, x11 platforms, the relevant field is the first in the struct ! 113 } 114 runnable.run(component, peer); 115 } finally { 116 surface.Unlock().get().invoke(pSurface); 117 } 118 } finally { 119 awt.FreeDrawingSurface().get().invoke(pSurface); 120 } 121 } 122 123 /** 124 * 125 */ 126 public static long getNativePeerHandle(Component component) { 127 try { 128 JNIEnv env = getJNIEnv(); 129 JAWT awt = getJAWT(env); 130 final long ret[] = new long[1]; 131 withLockedSurface(env, awt, component, new LockedComponentRunnable() { 132 public void run(Component component, long peer) { 133 ret[0] = peer; 134 } 135 }); 136 return ret[0]; 137 } catch (Throwable ex) { 138 ex.printStackTrace(); 139 return 0; 140 } 141 } 142}