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 */ 050public class JAWTUtils { 051 052 public static JNIEnv getJNIEnv() { 053 return new JNIEnv(JNI.getEnv()); 054 } 055 056 public static JAWT getJAWT(JNIEnv env) { 057 if (GraphicsEnvironment.isHeadless()) { 058 throw new HeadlessException("No native peers in headless mode."); 059 } 060 061 JAWT awt = new JAWT().version(JAWT_VERSION_1_4); 062 Pointer<JAWT> pAwt = getPointer(awt); 063 if (!JAWT_GetAWT(env, pAwt)) { 064 throw new RuntimeException("Failed to get JAWT pointer !"); 065 } 066 067 return pAwt.get(); 068 } 069 070 public interface LockedComponentRunnable { 071 072 void run(Component component, long peer); 073 } 074 075 public static void withLockedSurface(JNIEnv env, JAWT awt, Component component, LockedComponentRunnable runnable) { 076 if (component.isLightweight()) { 077 throw new IllegalArgumentException("Lightweight components do not have native peers."); 078 } 079 080 if (!component.isDisplayable()) { 081 throw new IllegalArgumentException("Component that are not displayable do not have native peers."); 082 } 083 084 Pointer<?> componentPointer = JNI.getGlobalPointer(component); 085 086 Pointer<JAWT_DrawingSurface> pSurface = awt.GetDrawingSurface().get().invoke(env, componentPointer).as(JAWT_DrawingSurface.class); 087 if (pSurface == null) { 088 throw new RuntimeException("Cannot get drawing surface from " + component); 089 } 090 091 JAWT_DrawingSurface surface = pSurface.get(); 092 093 try { 094 int lock = surface.Lock().get().invoke(pSurface); 095 if ((lock & JAWT_LOCK_ERROR) != 0) { 096 throw new RuntimeException("Cannot lock drawing surface of " + component); 097 } 098 try { 099 Pointer<JAWT_DrawingSurface.GetDrawingSurfaceInfo_callback> cb = surface.GetDrawingSurfaceInfo().as(JAWT_DrawingSurface.GetDrawingSurfaceInfo_callback.class); 100 Pointer<org.bridj.jawt.JAWT_DrawingSurfaceInfo> pInfo = cb.get().invoke(pSurface); 101 if (pInfo != null) { 102 pInfo = pInfo.as(JAWT_DrawingSurfaceInfo.class); 103 } 104 Pointer<?> platformInfo = pInfo.get().platformInfo(); 105 long peer = platformInfo.getSizeT(); // on win, mac, x11 platforms, the relevant field is the first in the struct ! 106 runnable.run(component, peer); 107 } finally { 108 surface.Unlock().get().invoke(pSurface); 109 } 110 } finally { 111 awt.FreeDrawingSurface().get().invoke(pSurface); 112 } 113 } 114 115 /** 116 * 117 */ 118 public static long getNativePeerHandle(Component component) { 119 try { 120 JNIEnv env = getJNIEnv(); 121 JAWT awt = getJAWT(env); 122 final long ret[] = new long[1]; 123 withLockedSurface(env, awt, component, new LockedComponentRunnable() { 124 public void run(Component component, long peer) { 125 ret[0] = peer; 126 } 127 }); 128 return ret[0]; 129 } catch (Throwable ex) { 130 ex.printStackTrace(); 131 return 0; 132 } 133 } 134}