text: /*
   * Copyright (c) 1996, 2013, 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 <jni.h>
  #include <jni_util.h>
  #include <jawt_md.h>
  
  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");
      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");
      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");
      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");
      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 ((peer != NULL) &&
          (JNU_IsInstanceOfByName(env, peer, "sun/awt/X11/XWindow") == 1)) {
          target = (*env)->GetObjectField(env, peer, targetID);
      }
  
      if (target == NULL) {
          JNU_ThrowNullPointerException(env, "NullPointerException");
          AWT_UNLOCK();
          return (jobject)NULL;
      }
  
      AWT_UNLOCK();
  
      return target;
  }
  