Path: blob/master/src/java.desktop/unix/native/libawt_xawt/awt/awt_DrawingSurface.c
41154 views
/*1* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#ifdef HEADLESS26#error This file should not be included in headless library27#endif2829#include "awt_p.h"30#include "java_awt_Component.h"3132#include "awt_Component.h"3334#include <jni.h>35#include <jni_util.h>36#include <jawt_md.h>3738extern struct ComponentIDs componentIDs;3940#include "awt_GraphicsEnv.h"41extern jfieldID windowID;42extern jfieldID targetID;43extern jfieldID graphicsConfigID;44extern jfieldID drawStateID;45extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;4647/*48* Lock the surface of the target component for native rendering.49* When finished drawing, the surface must be unlocked with50* Unlock(). This function returns a bitmask with one or more of the51* following values:52*53* JAWT_LOCK_ERROR - When an error has occurred and the surface could not54* be locked.55*56* JAWT_LOCK_CLIP_CHANGED - When the clip region has changed.57*58* JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed.59*60* JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed61*/62JNIEXPORT jint JNICALL awt_DrawingSurface_Lock(JAWT_DrawingSurface* ds)63{64JNIEnv* env;65jobject target, peer;66jclass componentClass;67jint drawState;6869if (ds == NULL) {70#ifdef DEBUG71fprintf(stderr, "Drawing Surface is NULL\n");72#endif73return (jint)JAWT_LOCK_ERROR;74}75env = ds->env;76target = ds->target;7778/* Make sure the target is a java.awt.Component */79componentClass = (*env)->FindClass(env, "java/awt/Component");80CHECK_NULL_RETURN(componentClass, (jint)JAWT_LOCK_ERROR);8182if (!(*env)->IsInstanceOf(env, target, componentClass)) {83#ifdef DEBUG84fprintf(stderr, "Target is not a component\n");85#endif86return (jint)JAWT_LOCK_ERROR;87}8889if (!awtLockInited) {90return (jint)JAWT_LOCK_ERROR;91}92AWT_LOCK();9394/* Get the peer of the target component */95peer = (*env)->GetObjectField(env, target, componentIDs.peer);96if (JNU_IsNull(env, peer)) {97#ifdef DEBUG98fprintf(stderr, "Component peer is NULL\n");99#endif100AWT_FLUSH_UNLOCK();101return (jint)JAWT_LOCK_ERROR;102}103104drawState = (*env)->GetIntField(env, peer, drawStateID);105(*env)->SetIntField(env, peer, drawStateID, 0);106return drawState;107}108109JNIEXPORT int32_t JNICALL110awt_GetColor(JAWT_DrawingSurface* ds, int32_t r, int32_t g, int32_t b)111{112JNIEnv* env;113jobject target, peer;114jclass componentClass;115AwtGraphicsConfigDataPtr adata;116int32_t result;117jobject gc_object;118if (ds == NULL) {119#ifdef DEBUG120fprintf(stderr, "Drawing Surface is NULL\n");121#endif122return (int32_t) 0;123}124125env = ds->env;126target = ds->target;127128/* Make sure the target is a java.awt.Component */129componentClass = (*env)->FindClass(env, "java/awt/Component");130CHECK_NULL_RETURN(componentClass, (int32_t) 0);131132if (!(*env)->IsInstanceOf(env, target, componentClass)) {133#ifdef DEBUG134fprintf(stderr, "DrawingSurface target must be a component\n");135#endif136return (int32_t) 0;137}138139if (!awtLockInited) {140return (int32_t) 0;141}142143AWT_LOCK();144145/* Get the peer of the target component */146peer = (*env)->GetObjectField(env, target, componentIDs.peer);147if (JNU_IsNull(env, peer)) {148#ifdef DEBUG149fprintf(stderr, "Component peer is NULL\n");150#endif151AWT_UNLOCK();152return (int32_t) 0;153}154/* GraphicsConfiguration object of MComponentPeer */155gc_object = (*env)->GetObjectField(env, peer, graphicsConfigID);156157if (gc_object != NULL) {158adata = (AwtGraphicsConfigDataPtr)159JNU_GetLongFieldAsPtr(env, gc_object,160x11GraphicsConfigIDs.aData);161} else {162adata = getDefaultConfig(DefaultScreen(awt_display));163}164165result = adata->AwtColorMatch(r, g, b, adata);166AWT_UNLOCK();167return result;168}169170/*171* Get the drawing surface info.172* The value returned may be cached, but the values may change if173* additional calls to Lock() or Unlock() are made.174* Lock() must be called before this can return a valid value.175* Returns NULL if an error has occurred.176* When finished with the returned value, FreeDrawingSurfaceInfo must be177* called.178*/179JNIEXPORT JAWT_DrawingSurfaceInfo* JNICALL180awt_DrawingSurface_GetDrawingSurfaceInfo(JAWT_DrawingSurface* ds)181{182JNIEnv* env;183jobject target, peer;184jclass componentClass;185JAWT_X11DrawingSurfaceInfo* px;186JAWT_DrawingSurfaceInfo* p;187XWindowAttributes attrs;188189if (ds == NULL) {190#ifdef DEBUG191fprintf(stderr, "Drawing Surface is NULL\n");192#endif193return NULL;194}195196env = ds->env;197target = ds->target;198199/* Make sure the target is a java.awt.Component */200componentClass = (*env)->FindClass(env, "java/awt/Component");201CHECK_NULL_RETURN(componentClass, NULL);202203if (!(*env)->IsInstanceOf(env, target, componentClass)) {204#ifdef DEBUG205fprintf(stderr, "DrawingSurface target must be a component\n");206#endif207return NULL;208}209210if (!awtLockInited) {211return NULL;212}213214AWT_LOCK();215216/* Get the peer of the target component */217peer = (*env)->GetObjectField(env, target, componentIDs.peer);218if (JNU_IsNull(env, peer)) {219#ifdef DEBUG220fprintf(stderr, "Component peer is NULL\n");221#endif222AWT_UNLOCK();223return NULL;224}225226AWT_UNLOCK();227228/* Allocate platform-specific data */229px = (JAWT_X11DrawingSurfaceInfo*)230malloc(sizeof(JAWT_X11DrawingSurfaceInfo));231232/* Set drawable and display */233px->drawable = (*env)->GetLongField(env, peer, windowID);234px->display = awt_display;235236/* Get window attributes to set other values */237XGetWindowAttributes(awt_display, (Window)(px->drawable), &attrs);238239/* Set the other values */240px->visualID = XVisualIDFromVisual(attrs.visual);241px->colormapID = attrs.colormap;242px->depth = attrs.depth;243px->GetAWTColor = awt_GetColor;244245/* Allocate and initialize platform-independent data */246p = (JAWT_DrawingSurfaceInfo*)malloc(sizeof(JAWT_DrawingSurfaceInfo));247p->platformInfo = px;248p->ds = ds;249p->bounds.x = (*env)->GetIntField(env, target, componentIDs.x);250p->bounds.y = (*env)->GetIntField(env, target, componentIDs.y);251p->bounds.width = (*env)->GetIntField(env, target, componentIDs.width);252p->bounds.height = (*env)->GetIntField(env, target, componentIDs.height);253p->clipSize = 1;254p->clip = &(p->bounds);255256/* Return our new structure */257return p;258}259260/*261* Free the drawing surface info.262*/263JNIEXPORT void JNICALL264awt_DrawingSurface_FreeDrawingSurfaceInfo(JAWT_DrawingSurfaceInfo* dsi)265{266if (dsi == NULL ) {267#ifdef DEBUG268fprintf(stderr, "Drawing Surface Info is NULL\n");269#endif270return;271}272free(dsi->platformInfo);273free(dsi);274}275276/*277* Unlock the drawing surface of the target component for native rendering.278*/279JNIEXPORT void JNICALL awt_DrawingSurface_Unlock(JAWT_DrawingSurface* ds)280{281JNIEnv* env;282if (ds == NULL) {283#ifdef DEBUG284fprintf(stderr, "Drawing Surface is NULL\n");285#endif286return;287}288env = ds->env;289AWT_FLUSH_UNLOCK();290}291292JNIEXPORT JAWT_DrawingSurface* JNICALL293awt_GetDrawingSurface(JNIEnv* env, jobject target)294{295jclass componentClass;296JAWT_DrawingSurface* p;297298/* Make sure the target component is a java.awt.Component */299componentClass = (*env)->FindClass(env, "java/awt/Component");300CHECK_NULL_RETURN(componentClass, NULL);301302if (!(*env)->IsInstanceOf(env, target, componentClass)) {303#ifdef DEBUG304fprintf(stderr,305"GetDrawingSurface target must be a java.awt.Component\n");306#endif307return NULL;308}309310p = (JAWT_DrawingSurface*)malloc(sizeof(JAWT_DrawingSurface));311p->env = env;312p->target = (*env)->NewGlobalRef(env, target);313p->Lock = awt_DrawingSurface_Lock;314p->GetDrawingSurfaceInfo = awt_DrawingSurface_GetDrawingSurfaceInfo;315p->FreeDrawingSurfaceInfo = awt_DrawingSurface_FreeDrawingSurfaceInfo;316p->Unlock = awt_DrawingSurface_Unlock;317return p;318}319320JNIEXPORT void JNICALL321awt_FreeDrawingSurface(JAWT_DrawingSurface* ds)322{323JNIEnv* env;324325if (ds == NULL ) {326#ifdef DEBUG327fprintf(stderr, "Drawing Surface is NULL\n");328#endif329return;330}331env = ds->env;332(*env)->DeleteGlobalRef(env, ds->target);333free(ds);334}335336JNIEXPORT void JNICALL337awt_Lock(JNIEnv* env)338{339if (awtLockInited) {340AWT_LOCK();341}342}343344JNIEXPORT void JNICALL345awt_Unlock(JNIEnv* env)346{347if (awtLockInited) {348AWT_FLUSH_UNLOCK();349}350}351352JNIEXPORT jobject JNICALL353awt_GetComponent(JNIEnv* env, void* platformInfo)354{355Window window = (Window)platformInfo;356jobject peer = NULL;357jobject target = NULL;358359AWT_LOCK();360361if (window != None) {362peer = JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit",363"windowToXWindow", "(J)Lsun/awt/X11/XBaseWindow;", (jlong)window).l;364if ((*env)->ExceptionCheck(env)) {365AWT_UNLOCK();366return (jobject)NULL;367}368}369if ((peer != NULL) &&370(JNU_IsInstanceOfByName(env, peer, "sun/awt/X11/XWindow") == 1)) {371target = (*env)->GetObjectField(env, peer, targetID);372}373374if (target == NULL) {375(*env)->ExceptionClear(env);376JNU_ThrowNullPointerException(env, "NullPointerException");377AWT_UNLOCK();378return (jobject)NULL;379}380381AWT_UNLOCK();382383return target;384}385386// EmbeddedFrame support387388static char *const embeddedClassName = "sun/awt/X11/XEmbeddedFrame";389390JNIEXPORT jobject JNICALL awt_CreateEmbeddedFrame391(JNIEnv* env, void* platformInfo)392{393static jmethodID mid = NULL;394static jclass cls;395if (mid == NULL) {396cls = (*env)->FindClass(env, embeddedClassName);397CHECK_NULL_RETURN(cls, NULL);398mid = (*env)->GetMethodID(env, cls, "<init>", "(JZ)V");399CHECK_NULL_RETURN(mid, NULL);400}401return (*env)->NewObject(env, cls, mid, platformInfo, JNI_TRUE);402}403404405JNIEXPORT void JNICALL awt_SetBounds406(JNIEnv *env, jobject embeddedFrame, jint x, jint y, jint w, jint h)407{408static jmethodID mid = NULL;409if (mid == NULL) {410jclass cls = (*env)->FindClass(env, embeddedClassName);411CHECK_NULL(cls);412mid = (*env)->GetMethodID(env, cls, "setBoundsPrivate", "(IIII)V");413CHECK_NULL(mid);414}415(*env)->CallVoidMethod(env, embeddedFrame, mid, x, y, w, h);416}417418JNIEXPORT void JNICALL awt_SynthesizeWindowActivation419(JNIEnv *env, jobject embeddedFrame, jboolean doActivate)420{421static jmethodID mid = NULL;422if (mid == NULL) {423jclass cls = (*env)->FindClass(env, embeddedClassName);424CHECK_NULL(cls);425mid = (*env)->GetMethodID(env, cls, "synthesizeWindowActivation", "(Z)V");426CHECK_NULL(mid);427}428(*env)->CallVoidMethod(env, embeddedFrame, mid, doActivate);429}430431432