1 /* 2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #ifdef HEADLESS 27 #error This file should not be included in headless library 28 #endif 29 30 #include "awt_p.h" 31 #include "java_awt_Component.h" 32 33 #include "awt_Component.h" 34 35 #include <jni.h> 36 #include <jni_util.h> 37 #include <jawt_md.h> 38 39 extern struct ComponentIDs componentIDs; 40 41 #include "awt_GraphicsEnv.h" 42 extern jfieldID windowID; 43 extern jfieldID targetID; 44 extern jfieldID graphicsConfigID; 45 extern jfieldID drawStateID; 46 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs; 47 48 /* 49 * Lock the surface of the target component for native rendering. 50 * When finished drawing, the surface must be unlocked with 51 * Unlock(). This function returns a bitmask with one or more of the 52 * following values: 53 * 54 * JAWT_LOCK_ERROR - When an error has occurred and the surface could not 55 * be locked. 56 * 57 * JAWT_LOCK_CLIP_CHANGED - When the clip region has changed. 58 * 59 * JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed. 60 * 61 * JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed 62 */ 63 JNIEXPORT jint JNICALL awt_DrawingSurface_Lock(JAWT_DrawingSurface* ds) 64 { 65 JNIEnv* env; 66 jobject target, peer; 67 jclass componentClass; 68 jint drawState; 69 70 if (ds == NULL) { 71 #ifdef DEBUG 72 fprintf(stderr, "Drawing Surface is NULL\n"); 73 #endif 74 return (jint)JAWT_LOCK_ERROR; 75 } 76 env = ds->env; 77 target = ds->target; 78 79 /* Make sure the target is a java.awt.Component */ 80 componentClass = (*env)->FindClass(env, "java/awt/Component"); 81 if (!(*env)->IsInstanceOf(env, target, componentClass)) { 82 #ifdef DEBUG 83 fprintf(stderr, "Target is not a component\n"); 84 #endif 85 return (jint)JAWT_LOCK_ERROR; 86 } 87 88 if (!awtLockInited) { 89 return (jint)JAWT_LOCK_ERROR; 90 } 91 AWT_LOCK(); 92 93 /* Get the peer of the target component */ 94 peer = (*env)->GetObjectField(env, target, componentIDs.peer); 95 if (JNU_IsNull(env, peer)) { 96 #ifdef DEBUG 97 fprintf(stderr, "Component peer is NULL\n"); 98 #endif 99 AWT_FLUSH_UNLOCK(); 100 return (jint)JAWT_LOCK_ERROR; 101 } 102 103 drawState = (*env)->GetIntField(env, peer, drawStateID); 104 (*env)->SetIntField(env, peer, drawStateID, 0); 105 return drawState; 106 } 107 108 JNIEXPORT int32_t JNICALL 109 awt_GetColor(JAWT_DrawingSurface* ds, int32_t r, int32_t g, int32_t b) 110 { 111 JNIEnv* env; 112 jobject target, peer; 113 jclass componentClass; 114 AwtGraphicsConfigDataPtr adata; 115 int32_t result; 116 jobject gc_object; 117 if (ds == NULL) { 118 #ifdef DEBUG 119 fprintf(stderr, "Drawing Surface is NULL\n"); 120 #endif 121 return (int32_t) 0; 122 } 123 124 env = ds->env; 125 target = ds->target; 126 127 /* Make sure the target is a java.awt.Component */ 128 componentClass = (*env)->FindClass(env, "java/awt/Component"); 129 if (!(*env)->IsInstanceOf(env, target, componentClass)) { 130 #ifdef DEBUG 131 fprintf(stderr, "DrawingSurface target must be a component\n"); 132 #endif 133 return (int32_t) 0; 134 } 135 136 if (!awtLockInited) { 137 return (int32_t) 0; 138 } 139 140 AWT_LOCK(); 141 142 /* Get the peer of the target component */ 143 peer = (*env)->GetObjectField(env, target, componentIDs.peer); 144 if (JNU_IsNull(env, peer)) { 145 #ifdef DEBUG 146 fprintf(stderr, "Component peer is NULL\n"); 147 #endif 148 AWT_UNLOCK(); 149 return (int32_t) 0; 150 } 151 /* GraphicsConfiguration object of MComponentPeer */ 152 gc_object = (*env)->GetObjectField(env, peer, graphicsConfigID); 153 154 if (gc_object != NULL) { 155 adata = (AwtGraphicsConfigDataPtr) 156 JNU_GetLongFieldAsPtr(env, gc_object, 157 x11GraphicsConfigIDs.aData); 158 } else { 159 adata = getDefaultConfig(DefaultScreen(awt_display)); 160 } 161 162 result = adata->AwtColorMatch(r, g, b, adata); 163 AWT_UNLOCK(); 164 return result; 165 } 166 167 /* 168 * Get the drawing surface info. 169 * The value returned may be cached, but the values may change if 170 * additional calls to Lock() or Unlock() are made. 171 * Lock() must be called before this can return a valid value. 172 * Returns NULL if an error has occurred. 173 * When finished with the returned value, FreeDrawingSurfaceInfo must be 174 * called. 175 */ 176 JNIEXPORT JAWT_DrawingSurfaceInfo* JNICALL 177 awt_DrawingSurface_GetDrawingSurfaceInfo(JAWT_DrawingSurface* ds) 178 { 179 JNIEnv* env; 180 jobject target, peer; 181 jclass componentClass; 182 JAWT_X11DrawingSurfaceInfo* px; 183 JAWT_DrawingSurfaceInfo* p; 184 XWindowAttributes attrs; 185 186 if (ds == NULL) { 187 #ifdef DEBUG 188 fprintf(stderr, "Drawing Surface is NULL\n"); 189 #endif 190 return NULL; 191 } 192 193 env = ds->env; 194 target = ds->target; 195 196 /* Make sure the target is a java.awt.Component */ 197 componentClass = (*env)->FindClass(env, "java/awt/Component"); 198 if (!(*env)->IsInstanceOf(env, target, componentClass)) { 199 #ifdef DEBUG 200 fprintf(stderr, "DrawingSurface target must be a component\n"); 201 #endif 202 return NULL; 203 } 204 205 if (!awtLockInited) { 206 return NULL; 207 } 208 209 AWT_LOCK(); 210 211 /* Get the peer of the target component */ 212 peer = (*env)->GetObjectField(env, target, componentIDs.peer); 213 if (JNU_IsNull(env, peer)) { 214 #ifdef DEBUG 215 fprintf(stderr, "Component peer is NULL\n"); 216 #endif 217 AWT_UNLOCK(); 218 return NULL; 219 } 220 221 AWT_UNLOCK(); 222 223 /* Allocate platform-specific data */ 224 px = (JAWT_X11DrawingSurfaceInfo*) 225 malloc(sizeof(JAWT_X11DrawingSurfaceInfo)); 226 227 /* Set drawable and display */ 228 px->drawable = (*env)->GetLongField(env, peer, windowID); 229 px->display = awt_display; 230 231 /* Get window attributes to set other values */ 232 XGetWindowAttributes(awt_display, (Window)(px->drawable), &attrs); 233 234 /* Set the other values */ 235 px->visualID = XVisualIDFromVisual(attrs.visual); 236 px->colormapID = attrs.colormap; 237 px->depth = attrs.depth; 238 px->GetAWTColor = awt_GetColor; 239 240 /* Allocate and initialize platform-independent data */ 241 p = (JAWT_DrawingSurfaceInfo*)malloc(sizeof(JAWT_DrawingSurfaceInfo)); 242 p->platformInfo = px; 243 p->ds = ds; 244 p->bounds.x = (*env)->GetIntField(env, target, componentIDs.x); 245 p->bounds.y = (*env)->GetIntField(env, target, componentIDs.y); 246 p->bounds.width = (*env)->GetIntField(env, target, componentIDs.width); 247 p->bounds.height = (*env)->GetIntField(env, target, componentIDs.height); 248 p->clipSize = 1; 249 p->clip = &(p->bounds); 250 251 /* Return our new structure */ 252 return p; 253 } 254 255 /* 256 * Free the drawing surface info. 257 */ 258 JNIEXPORT void JNICALL 259 awt_DrawingSurface_FreeDrawingSurfaceInfo(JAWT_DrawingSurfaceInfo* dsi) 260 { 261 if (dsi == NULL ) { 262 #ifdef DEBUG 263 fprintf(stderr, "Drawing Surface Info is NULL\n"); 264 #endif 265 return; 266 } 267 free(dsi->platformInfo); 268 free(dsi); 269 } 270 271 /* 272 * Unlock the drawing surface of the target component for native rendering. 273 */ 274 JNIEXPORT void JNICALL awt_DrawingSurface_Unlock(JAWT_DrawingSurface* ds) 275 { 276 JNIEnv* env; 277 if (ds == NULL) { 278 #ifdef DEBUG 279 fprintf(stderr, "Drawing Surface is NULL\n"); 280 #endif 281 return; 282 } 283 env = ds->env; 284 AWT_FLUSH_UNLOCK(); 285 } 286 287 JNIEXPORT JAWT_DrawingSurface* JNICALL 288 awt_GetDrawingSurface(JNIEnv* env, jobject target) 289 { 290 jclass componentClass; 291 JAWT_DrawingSurface* p; 292 293 /* Make sure the target component is a java.awt.Component */ 294 componentClass = (*env)->FindClass(env, "java/awt/Component"); 295 if (!(*env)->IsInstanceOf(env, target, componentClass)) { 296 #ifdef DEBUG 297 fprintf(stderr, 298 "GetDrawingSurface target must be a java.awt.Component\n"); 299 #endif 300 return NULL; 301 } 302 303 p = (JAWT_DrawingSurface*)malloc(sizeof(JAWT_DrawingSurface)); 304 p->env = env; 305 p->target = (*env)->NewGlobalRef(env, target); 306 p->Lock = awt_DrawingSurface_Lock; 307 p->GetDrawingSurfaceInfo = awt_DrawingSurface_GetDrawingSurfaceInfo; 308 p->FreeDrawingSurfaceInfo = awt_DrawingSurface_FreeDrawingSurfaceInfo; 309 p->Unlock = awt_DrawingSurface_Unlock; 310 return p; 311 } 312 313 JNIEXPORT void JNICALL 314 awt_FreeDrawingSurface(JAWT_DrawingSurface* ds) 315 { 316 JNIEnv* env; 317 318 if (ds == NULL ) { 319 #ifdef DEBUG 320 fprintf(stderr, "Drawing Surface is NULL\n"); 321 #endif 322 return; 323 } 324 env = ds->env; 325 (*env)->DeleteGlobalRef(env, ds->target); 326 free(ds); 327 } 328 329 JNIEXPORT void JNICALL 330 awt_Lock(JNIEnv* env) 331 { 332 if (awtLockInited) { 333 AWT_LOCK(); 334 } 335 } 336 337 JNIEXPORT void JNICALL 338 awt_Unlock(JNIEnv* env) 339 { 340 if (awtLockInited) { 341 AWT_FLUSH_UNLOCK(); 342 } 343 } 344 345 JNIEXPORT jobject JNICALL 346 awt_GetComponent(JNIEnv* env, void* platformInfo) 347 { 348 Window window = (Window)platformInfo; 349 Widget widget = NULL; 350 jobject peer = NULL; 351 jobject target = NULL; 352 353 AWT_LOCK(); 354 355 target = (*env)->GetObjectField(env, peer, targetID); 356 357 if (target == NULL) { 358 JNU_ThrowNullPointerException(env, "NullPointerException"); 359 AWT_UNLOCK(); 360 return (jobject)NULL; 361 } 362 363 364 AWT_UNLOCK(); 365 366 return target; 367 }