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 //#include "sun_awt_motif_MComponentPeer.h" 33 34 #include "awt_Component.h" 35 36 37 #include <jni.h> 38 #include <jni_util.h> 39 #include <jawt_md.h> 40 41 extern struct MComponentPeerIDs mComponentPeerIDs; 42 extern struct ComponentIDs componentIDs; 43 #ifndef XAWT 44 extern AwtGraphicsConfigDataPtr 45 getGraphicsConfigFromComponentPeer(JNIEnv *env, jobject this); 46 #endif 47 48 #ifdef XAWT 49 #include "awt_GraphicsEnv.h" 50 extern jfieldID windowID; 51 extern jfieldID targetID; 52 extern jfieldID graphicsConfigID; 53 extern jfieldID drawStateID; 54 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs; 55 #endif 56 57 /* 58 * Lock the surface of the target component for native rendering. 59 * When finished drawing, the surface must be unlocked with 60 * Unlock(). This function returns a bitmask with one or more of the 61 * following values: 62 * 63 * JAWT_LOCK_ERROR - When an error has occurred and the surface could not 64 * be locked. 65 * 66 * JAWT_LOCK_CLIP_CHANGED - When the clip region has changed. 67 * 68 * JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed. 69 * 70 * JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed 71 */ 72 JNIEXPORT jint JNICALL awt_DrawingSurface_Lock(JAWT_DrawingSurface* ds) 73 { 74 JNIEnv* env; 75 jobject target, peer; 76 jclass componentClass; 77 jint drawState; 78 79 if (ds == NULL) { 80 #ifdef DEBUG 81 fprintf(stderr, "Drawing Surface is NULL\n"); 82 #endif 83 return (jint)JAWT_LOCK_ERROR; 84 } 85 env = ds->env; 86 target = ds->target; 87 88 /* Make sure the target is a java.awt.Component */ 89 componentClass = (*env)->FindClass(env, "java/awt/Component"); 90 if (!(*env)->IsInstanceOf(env, target, componentClass)) { 91 #ifdef DEBUG 92 fprintf(stderr, "Target is not a component\n"); 93 #endif 94 return (jint)JAWT_LOCK_ERROR; 95 } 96 97 if (!awtLockInited) { 98 return (jint)JAWT_LOCK_ERROR; 99 } 100 AWT_LOCK(); 101 102 /* Get the peer of the target component */ 103 peer = (*env)->GetObjectField(env, target, componentIDs.peer); 104 if (JNU_IsNull(env, peer)) { 105 #ifdef DEBUG 106 fprintf(stderr, "Component peer is NULL\n"); 107 #endif 108 AWT_FLUSH_UNLOCK(); 109 return (jint)JAWT_LOCK_ERROR; 110 } 111 112 #ifndef XAWT 113 drawState = (*env)->GetIntField(env, peer, mComponentPeerIDs.drawState); 114 (*env)->SetIntField(env, peer, mComponentPeerIDs.drawState, 0); 115 #else 116 drawState = (*env)->GetIntField(env, peer, drawStateID); 117 (*env)->SetIntField(env, peer, drawStateID, 0); 118 #endif 119 return drawState; 120 } 121 122 JNIEXPORT int32_t JNICALL 123 awt_GetColor(JAWT_DrawingSurface* ds, int32_t r, int32_t g, int32_t b) 124 { 125 JNIEnv* env; 126 jobject target, peer; 127 jclass componentClass; 128 AwtGraphicsConfigDataPtr adata; 129 int32_t result; 130 #ifdef XAWT 131 jobject gc_object; 132 #endif 133 if (ds == NULL) { 134 #ifdef DEBUG 135 fprintf(stderr, "Drawing Surface is NULL\n"); 136 #endif 137 return (int32_t) 0; 138 } 139 140 env = ds->env; 141 target = ds->target; 142 143 /* Make sure the target is a java.awt.Component */ 144 componentClass = (*env)->FindClass(env, "java/awt/Component"); 145 if (!(*env)->IsInstanceOf(env, target, componentClass)) { 146 #ifdef DEBUG 147 fprintf(stderr, "DrawingSurface target must be a component\n"); 148 #endif 149 return (int32_t) 0; 150 } 151 152 if (!awtLockInited) { 153 return (int32_t) 0; 154 } 155 156 AWT_LOCK(); 157 158 /* Get the peer of the target component */ 159 peer = (*env)->GetObjectField(env, target, componentIDs.peer); 160 if (JNU_IsNull(env, peer)) { 161 #ifdef DEBUG 162 fprintf(stderr, "Component peer is NULL\n"); 163 #endif 164 AWT_UNLOCK(); 165 return (int32_t) 0; 166 } 167 #ifndef XAWT 168 adata = getGraphicsConfigFromComponentPeer(env, peer); 169 #else 170 /* GraphicsConfiguration object of MComponentPeer */ 171 gc_object = (*env)->GetObjectField(env, peer, graphicsConfigID); 172 173 if (gc_object != NULL) { 174 adata = (AwtGraphicsConfigDataPtr) 175 JNU_GetLongFieldAsPtr(env, gc_object, 176 x11GraphicsConfigIDs.aData); 177 } else { 178 adata = getDefaultConfig(DefaultScreen(awt_display)); 179 } 180 #endif 181 182 result = adata->AwtColorMatch(r, g, b, adata); 183 AWT_UNLOCK(); 184 return result; 185 } 186 187 /* 188 * Get the drawing surface info. 189 * The value returned may be cached, but the values may change if 190 * additional calls to Lock() or Unlock() are made. 191 * Lock() must be called before this can return a valid value. 192 * Returns NULL if an error has occurred. 193 * When finished with the returned value, FreeDrawingSurfaceInfo must be 194 * called. 195 */ 196 JNIEXPORT JAWT_DrawingSurfaceInfo* JNICALL 197 awt_DrawingSurface_GetDrawingSurfaceInfo(JAWT_DrawingSurface* ds) 198 { 199 JNIEnv* env; 200 jobject target, peer; 201 jclass componentClass; 202 JAWT_X11DrawingSurfaceInfo* px; 203 JAWT_DrawingSurfaceInfo* p; 204 #ifndef XAWT 205 struct ComponentData *cdata; 206 #endif 207 XWindowAttributes attrs; 208 209 if (ds == NULL) { 210 #ifdef DEBUG 211 fprintf(stderr, "Drawing Surface is NULL\n"); 212 #endif 213 return NULL; 214 } 215 216 env = ds->env; 217 target = ds->target; 218 219 /* Make sure the target is a java.awt.Component */ 220 componentClass = (*env)->FindClass(env, "java/awt/Component"); 221 if (!(*env)->IsInstanceOf(env, target, componentClass)) { 222 #ifdef DEBUG 223 fprintf(stderr, "DrawingSurface target must be a component\n"); 224 #endif 225 return NULL; 226 } 227 228 if (!awtLockInited) { 229 return NULL; 230 } 231 232 AWT_LOCK(); 233 234 /* Get the peer of the target component */ 235 peer = (*env)->GetObjectField(env, target, componentIDs.peer); 236 if (JNU_IsNull(env, peer)) { 237 #ifdef DEBUG 238 fprintf(stderr, "Component peer is NULL\n"); 239 #endif 240 AWT_UNLOCK(); 241 return NULL; 242 } 243 244 #ifndef XAWT 245 /* Get the component data from the peer */ 246 cdata = (struct ComponentData *) 247 JNU_GetLongFieldAsPtr(env, peer, mComponentPeerIDs.pData); 248 if (cdata == NULL) { 249 #ifdef DEBUG 250 fprintf(stderr, "Component data is NULL\n"); 251 #endif 252 AWT_UNLOCK(); 253 return NULL; 254 } 255 #endif 256 257 AWT_UNLOCK(); 258 259 /* Allocate platform-specific data */ 260 px = (JAWT_X11DrawingSurfaceInfo*) 261 malloc(sizeof(JAWT_X11DrawingSurfaceInfo)); 262 263 /* Set drawable and display */ 264 #ifndef XAWT 265 px->drawable = XtWindow(cdata->widget); 266 #else 267 px->drawable = (*env)->GetLongField(env, peer, windowID); 268 #endif 269 px->display = awt_display; 270 271 /* Get window attributes to set other values */ 272 XGetWindowAttributes(awt_display, (Window)(px->drawable), &attrs); 273 274 /* Set the other values */ 275 px->visualID = XVisualIDFromVisual(attrs.visual); 276 px->colormapID = attrs.colormap; 277 px->depth = attrs.depth; 278 px->GetAWTColor = awt_GetColor; 279 280 /* Allocate and initialize platform-independent data */ 281 p = (JAWT_DrawingSurfaceInfo*)malloc(sizeof(JAWT_DrawingSurfaceInfo)); 282 p->platformInfo = px; 283 p->ds = ds; 284 p->bounds.x = (*env)->GetIntField(env, target, componentIDs.x); 285 p->bounds.y = (*env)->GetIntField(env, target, componentIDs.y); 286 p->bounds.width = (*env)->GetIntField(env, target, componentIDs.width); 287 p->bounds.height = (*env)->GetIntField(env, target, componentIDs.height); 288 p->clipSize = 1; 289 p->clip = &(p->bounds); 290 291 /* Return our new structure */ 292 return p; 293 } 294 295 /* 296 * Free the drawing surface info. 297 */ 298 JNIEXPORT void JNICALL 299 awt_DrawingSurface_FreeDrawingSurfaceInfo(JAWT_DrawingSurfaceInfo* dsi) 300 { 301 if (dsi == NULL ) { 302 #ifdef DEBUG 303 fprintf(stderr, "Drawing Surface Info is NULL\n"); 304 #endif 305 return; 306 } 307 free(dsi->platformInfo); 308 free(dsi); 309 } 310 311 /* 312 * Unlock the drawing surface of the target component for native rendering. 313 */ 314 JNIEXPORT void JNICALL awt_DrawingSurface_Unlock(JAWT_DrawingSurface* ds) 315 { 316 JNIEnv* env; 317 if (ds == NULL) { 318 #ifdef DEBUG 319 fprintf(stderr, "Drawing Surface is NULL\n"); 320 #endif 321 return; 322 } 323 env = ds->env; 324 AWT_FLUSH_UNLOCK(); 325 } 326 327 JNIEXPORT JAWT_DrawingSurface* JNICALL 328 awt_GetDrawingSurface(JNIEnv* env, jobject target) 329 { 330 jclass componentClass; 331 JAWT_DrawingSurface* p; 332 333 /* Make sure the target component is a java.awt.Component */ 334 componentClass = (*env)->FindClass(env, "java/awt/Component"); 335 if (!(*env)->IsInstanceOf(env, target, componentClass)) { 336 #ifdef DEBUG 337 fprintf(stderr, 338 "GetDrawingSurface target must be a java.awt.Component\n"); 339 #endif 340 return NULL; 341 } 342 343 p = (JAWT_DrawingSurface*)malloc(sizeof(JAWT_DrawingSurface)); 344 p->env = env; 345 p->target = (*env)->NewGlobalRef(env, target); 346 p->Lock = awt_DrawingSurface_Lock; 347 p->GetDrawingSurfaceInfo = awt_DrawingSurface_GetDrawingSurfaceInfo; 348 p->FreeDrawingSurfaceInfo = awt_DrawingSurface_FreeDrawingSurfaceInfo; 349 p->Unlock = awt_DrawingSurface_Unlock; 350 return p; 351 } 352 353 JNIEXPORT void JNICALL 354 awt_FreeDrawingSurface(JAWT_DrawingSurface* ds) 355 { 356 JNIEnv* env; 357 358 if (ds == NULL ) { 359 #ifdef DEBUG 360 fprintf(stderr, "Drawing Surface is NULL\n"); 361 #endif 362 return; 363 } 364 env = ds->env; 365 (*env)->DeleteGlobalRef(env, ds->target); 366 free(ds); 367 } 368 369 JNIEXPORT void JNICALL 370 awt_Lock(JNIEnv* env) 371 { 372 if (awtLockInited) { 373 AWT_LOCK(); 374 } 375 } 376 377 JNIEXPORT void JNICALL 378 awt_Unlock(JNIEnv* env) 379 { 380 if (awtLockInited) { 381 AWT_FLUSH_UNLOCK(); 382 } 383 } 384 385 JNIEXPORT jobject JNICALL 386 awt_GetComponent(JNIEnv* env, void* platformInfo) 387 { 388 Window window = (Window)platformInfo; 389 Widget widget = NULL; 390 jobject peer = NULL; 391 jobject target = NULL; 392 393 AWT_LOCK(); 394 395 #ifndef XAWT 396 if (window != None) { 397 widget = XtWindowToWidget(awt_display, window); 398 } 399 400 if (widget != NULL) { 401 XtVaGetValues (widget, XmNuserData, &peer, NULL); 402 } 403 404 if (peer != NULL) { 405 target = (*env)->GetObjectField(env, peer, mComponentPeerIDs.target); 406 } 407 #else 408 target = (*env)->GetObjectField(env, peer, targetID); 409 #endif 410 411 if (target == NULL) { 412 JNU_ThrowNullPointerException(env, "NullPointerException"); 413 AWT_UNLOCK(); 414 return (jobject)NULL; 415 } 416 417 418 AWT_UNLOCK(); 419 420 return target; 421 }