/* * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #ifdef HEADLESS #error This file should not be included in headless library #endif #include "awt_p.h" #include "java_awt_Component.h" #include "awt_Component.h" #include #include #include extern struct ComponentIDs componentIDs; #include "awt_GraphicsEnv.h" extern jfieldID windowID; extern jfieldID targetID; extern jfieldID graphicsConfigID; extern jfieldID drawStateID; extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs; /* * Lock the surface of the target component for native rendering. * When finished drawing, the surface must be unlocked with * Unlock(). This function returns a bitmask with one or more of the * following values: * * JAWT_LOCK_ERROR - When an error has occurred and the surface could not * be locked. * * JAWT_LOCK_CLIP_CHANGED - When the clip region has changed. * * JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed. * * JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed */ JNIEXPORT jint JNICALL awt_DrawingSurface_Lock(JAWT_DrawingSurface* ds) { JNIEnv* env; jobject target, peer; jclass componentClass; jint drawState; if (ds == NULL) { #ifdef DEBUG fprintf(stderr, "Drawing Surface is NULL\n"); #endif return (jint)JAWT_LOCK_ERROR; } env = ds->env; target = ds->target; /* Make sure the target is a java.awt.Component */ componentClass = (*env)->FindClass(env, "java/awt/Component"); CHECK_NULL_RETURN(componentClass, (jint)JAWT_LOCK_ERROR); if (!(*env)->IsInstanceOf(env, target, componentClass)) { #ifdef DEBUG fprintf(stderr, "Target is not a component\n"); #endif return (jint)JAWT_LOCK_ERROR; } if (!awtLockInited) { return (jint)JAWT_LOCK_ERROR; } AWT_LOCK(); /* Get the peer of the target component */ peer = (*env)->GetObjectField(env, target, componentIDs.peer); if (JNU_IsNull(env, peer)) { #ifdef DEBUG fprintf(stderr, "Component peer is NULL\n"); #endif AWT_FLUSH_UNLOCK(); return (jint)JAWT_LOCK_ERROR; } drawState = (*env)->GetIntField(env, peer, drawStateID); (*env)->SetIntField(env, peer, drawStateID, 0); return drawState; } JNIEXPORT int32_t JNICALL awt_GetColor(JAWT_DrawingSurface* ds, int32_t r, int32_t g, int32_t b) { JNIEnv* env; jobject target, peer; jclass componentClass; AwtGraphicsConfigDataPtr adata; int32_t result; jobject gc_object; if (ds == NULL) { #ifdef DEBUG fprintf(stderr, "Drawing Surface is NULL\n"); #endif return (int32_t) 0; } env = ds->env; target = ds->target; /* Make sure the target is a java.awt.Component */ componentClass = (*env)->FindClass(env, "java/awt/Component"); CHECK_NULL_RETURN(componentClass, (int32_t) 0); if (!(*env)->IsInstanceOf(env, target, componentClass)) { #ifdef DEBUG fprintf(stderr, "DrawingSurface target must be a component\n"); #endif return (int32_t) 0; } if (!awtLockInited) { return (int32_t) 0; } AWT_LOCK(); /* Get the peer of the target component */ peer = (*env)->GetObjectField(env, target, componentIDs.peer); if (JNU_IsNull(env, peer)) { #ifdef DEBUG fprintf(stderr, "Component peer is NULL\n"); #endif AWT_UNLOCK(); return (int32_t) 0; } /* GraphicsConfiguration object of MComponentPeer */ gc_object = (*env)->GetObjectField(env, peer, graphicsConfigID); if (gc_object != NULL) { adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, gc_object, x11GraphicsConfigIDs.aData); } else { adata = getDefaultConfig(DefaultScreen(awt_display)); } result = adata->AwtColorMatch(r, g, b, adata); AWT_UNLOCK(); return result; } /* * Get the drawing surface info. * The value returned may be cached, but the values may change if * additional calls to Lock() or Unlock() are made. * Lock() must be called before this can return a valid value. * Returns NULL if an error has occurred. * When finished with the returned value, FreeDrawingSurfaceInfo must be * called. */ JNIEXPORT JAWT_DrawingSurfaceInfo* JNICALL awt_DrawingSurface_GetDrawingSurfaceInfo(JAWT_DrawingSurface* ds) { JNIEnv* env; jobject target, peer; jclass componentClass; JAWT_X11DrawingSurfaceInfo* px; JAWT_DrawingSurfaceInfo* p; XWindowAttributes attrs; if (ds == NULL) { #ifdef DEBUG fprintf(stderr, "Drawing Surface is NULL\n"); #endif return NULL; } env = ds->env; target = ds->target; /* Make sure the target is a java.awt.Component */ componentClass = (*env)->FindClass(env, "java/awt/Component"); CHECK_NULL_RETURN(componentClass, NULL); if (!(*env)->IsInstanceOf(env, target, componentClass)) { #ifdef DEBUG fprintf(stderr, "DrawingSurface target must be a component\n"); #endif return NULL; } if (!awtLockInited) { return NULL; } AWT_LOCK(); /* Get the peer of the target component */ peer = (*env)->GetObjectField(env, target, componentIDs.peer); if (JNU_IsNull(env, peer)) { #ifdef DEBUG fprintf(stderr, "Component peer is NULL\n"); #endif AWT_UNLOCK(); return NULL; } AWT_UNLOCK(); /* Allocate platform-specific data */ px = (JAWT_X11DrawingSurfaceInfo*) malloc(sizeof(JAWT_X11DrawingSurfaceInfo)); /* Set drawable and display */ px->drawable = (*env)->GetLongField(env, peer, windowID); px->display = awt_display; /* Get window attributes to set other values */ XGetWindowAttributes(awt_display, (Window)(px->drawable), &attrs); /* Set the other values */ px->visualID = XVisualIDFromVisual(attrs.visual); px->colormapID = attrs.colormap; px->depth = attrs.depth; px->GetAWTColor = awt_GetColor; /* Allocate and initialize platform-independent data */ p = (JAWT_DrawingSurfaceInfo*)malloc(sizeof(JAWT_DrawingSurfaceInfo)); p->platformInfo = px; p->ds = ds; p->bounds.x = (*env)->GetIntField(env, target, componentIDs.x); p->bounds.y = (*env)->GetIntField(env, target, componentIDs.y); p->bounds.width = (*env)->GetIntField(env, target, componentIDs.width); p->bounds.height = (*env)->GetIntField(env, target, componentIDs.height); p->clipSize = 1; p->clip = &(p->bounds); /* Return our new structure */ return p; } /* * Free the drawing surface info. */ JNIEXPORT void JNICALL awt_DrawingSurface_FreeDrawingSurfaceInfo(JAWT_DrawingSurfaceInfo* dsi) { if (dsi == NULL ) { #ifdef DEBUG fprintf(stderr, "Drawing Surface Info is NULL\n"); #endif return; } free(dsi->platformInfo); free(dsi); } /* * Unlock the drawing surface of the target component for native rendering. */ JNIEXPORT void JNICALL awt_DrawingSurface_Unlock(JAWT_DrawingSurface* ds) { JNIEnv* env; if (ds == NULL) { #ifdef DEBUG fprintf(stderr, "Drawing Surface is NULL\n"); #endif return; } env = ds->env; AWT_FLUSH_UNLOCK(); } JNIEXPORT JAWT_DrawingSurface* JNICALL awt_GetDrawingSurface(JNIEnv* env, jobject target) { jclass componentClass; JAWT_DrawingSurface* p; /* Make sure the target component is a java.awt.Component */ componentClass = (*env)->FindClass(env, "java/awt/Component"); CHECK_NULL_RETURN(componentClass, NULL); if (!(*env)->IsInstanceOf(env, target, componentClass)) { #ifdef DEBUG fprintf(stderr, "GetDrawingSurface target must be a java.awt.Component\n"); #endif return NULL; } p = (JAWT_DrawingSurface*)malloc(sizeof(JAWT_DrawingSurface)); p->env = env; p->target = (*env)->NewGlobalRef(env, target); p->Lock = awt_DrawingSurface_Lock; p->GetDrawingSurfaceInfo = awt_DrawingSurface_GetDrawingSurfaceInfo; p->FreeDrawingSurfaceInfo = awt_DrawingSurface_FreeDrawingSurfaceInfo; p->Unlock = awt_DrawingSurface_Unlock; return p; } JNIEXPORT void JNICALL awt_FreeDrawingSurface(JAWT_DrawingSurface* ds) { JNIEnv* env; if (ds == NULL ) { #ifdef DEBUG fprintf(stderr, "Drawing Surface is NULL\n"); #endif return; } env = ds->env; (*env)->DeleteGlobalRef(env, ds->target); free(ds); } JNIEXPORT void JNICALL awt_Lock(JNIEnv* env) { if (awtLockInited) { AWT_LOCK(); } } JNIEXPORT void JNICALL awt_Unlock(JNIEnv* env) { if (awtLockInited) { AWT_FLUSH_UNLOCK(); } } JNIEXPORT jobject JNICALL awt_GetComponent(JNIEnv* env, void* platformInfo) { Window window = (Window)platformInfo; jobject peer = NULL; jobject target = NULL; AWT_LOCK(); if (window != None) { peer = JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit", "windowToXWindow", "(J)Lsun/awt/X11/XBaseWindow;", (jlong)window).l; if ((*env)->ExceptionCheck(env)) { AWT_UNLOCK(); return (jobject)NULL; } } if ((peer != NULL) && (JNU_IsInstanceOfByName(env, peer, "sun/awt/X11/XWindow") == 1)) { target = (*env)->GetObjectField(env, peer, targetID); } if (target == NULL) { (*env)->ExceptionClear(env); JNU_ThrowNullPointerException(env, "NullPointerException"); AWT_UNLOCK(); return (jobject)NULL; } AWT_UNLOCK(); return target; } // EmbeddedFrame support static char *const embeddedClassName = "sun/awt/X11/XEmbeddedFrame"; JNIEXPORT jobject JNICALL awt_CreateEmbeddedFrame (JNIEnv* env, void* platformInfo) { static jmethodID mid = NULL; static jclass cls; if (mid == NULL) { cls = (*env)->FindClass(env, embeddedClassName); CHECK_NULL_RETURN(cls, NULL); mid = (*env)->GetMethodID(env, cls, "", "(JZ)V"); CHECK_NULL_RETURN(mid, NULL); } return (*env)->NewObject(env, cls, mid, platformInfo, JNI_TRUE); } JNIEXPORT void JNICALL awt_SetBounds (JNIEnv *env, jobject embeddedFrame, jint x, jint y, jint w, jint h) { static jmethodID mid = NULL; if (mid == NULL) { jclass cls = (*env)->FindClass(env, embeddedClassName); CHECK_NULL(cls); mid = (*env)->GetMethodID(env, cls, "setBoundsPrivate", "(IIII)V"); CHECK_NULL(mid); } (*env)->CallVoidMethod(env, embeddedFrame, mid, x, y, w, h); } JNIEXPORT void JNICALL awt_SynthesizeWindowActivation (JNIEnv *env, jobject embeddedFrame, jboolean doActivate) { static jmethodID mid = NULL; if (mid == NULL) { jclass cls = (*env)->FindClass(env, embeddedClassName); CHECK_NULL(cls); mid = (*env)->GetMethodID(env, cls, "synthesizeWindowActivation", "(Z)V"); CHECK_NULL(mid); } (*env)->CallVoidMethod(env, embeddedFrame, mid, doActivate); }