1 /* 2 * Copyright (c) 1996, 2010, 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 } 306 free(dsi->platformInfo); 307 free(dsi); 308 } 309 310 /* 311 * Unlock the drawing surface of the target component for native rendering. 312 */ 313 JNIEXPORT void JNICALL awt_DrawingSurface_Unlock(JAWT_DrawingSurface* ds) 314 { 315 JNIEnv* env; 316 if (ds == NULL) { 317 #ifdef DEBUG 318 fprintf(stderr, "Drawing Surface is NULL\n"); 319 #endif 320 return; 321 } 322 env = ds->env; 323 AWT_FLUSH_UNLOCK(); 324 } 325 326 JNIEXPORT JAWT_DrawingSurface* JNICALL 327 awt_GetDrawingSurface(JNIEnv* env, jobject target) 328 { 329 jclass componentClass; 330 JAWT_DrawingSurface* p; 331 332 /* Make sure the target component is a java.awt.Component */ 333 componentClass = (*env)->FindClass(env, "java/awt/Component"); 334 if (!(*env)->IsInstanceOf(env, target, componentClass)) { 335 #ifdef DEBUG 336 fprintf(stderr, 337 "GetDrawingSurface target must be a java.awt.Component\n"); 338 #endif 339 return NULL; 340 } 341 342 p = (JAWT_DrawingSurface*)malloc(sizeof(JAWT_DrawingSurface)); 343 p->env = env; 344 p->target = (*env)->NewGlobalRef(env, target); 345 p->Lock = awt_DrawingSurface_Lock; 346 p->GetDrawingSurfaceInfo = awt_DrawingSurface_GetDrawingSurfaceInfo; 347 p->FreeDrawingSurfaceInfo = awt_DrawingSurface_FreeDrawingSurfaceInfo; 348 p->Unlock = awt_DrawingSurface_Unlock; 349 return p; 350 } 351 352 JNIEXPORT void JNICALL 353 awt_FreeDrawingSurface(JAWT_DrawingSurface* ds) 354 { 355 JNIEnv* env; 356 357 if (ds == NULL ) { 358 #ifdef DEBUG 359 fprintf(stderr, "Drawing Surface is NULL\n"); 360 #endif 361 return; 362 } 363 env = ds->env; 364 (*env)->DeleteGlobalRef(env, ds->target); 365 free(ds); 366 } 367 368 JNIEXPORT void JNICALL 369 awt_Lock(JNIEnv* env) 370 { 371 if (awtLockInited) { 372 AWT_LOCK(); 373 } 374 } 375 376 JNIEXPORT void JNICALL 377 awt_Unlock(JNIEnv* env) 378 { 379 if (awtLockInited) { 380 AWT_FLUSH_UNLOCK(); 381 } 382 } 383 384 JNIEXPORT jobject JNICALL 385 awt_GetComponent(JNIEnv* env, void* platformInfo) 386 { 387 Window window = (Window)platformInfo; 388 Widget widget = NULL; 389 jobject peer = NULL; 390 jobject target = NULL; 391 392 AWT_LOCK(); 393 394 #ifndef XAWT 395 if (window != None) { 396 widget = XtWindowToWidget(awt_display, window); 397 } 398 399 if (widget != NULL) { 400 XtVaGetValues (widget, XmNuserData, &peer, NULL); 401 } 402 403 if (peer != NULL) { 404 target = (*env)->GetObjectField(env, peer, mComponentPeerIDs.target); 405 } 406 #else 407 target = (*env)->GetObjectField(env, peer, targetID); 408 #endif 409 410 if (target == NULL) { 411 JNU_ThrowNullPointerException(env, "NullPointerException"); 412 AWT_UNLOCK(); 413 return (jobject)NULL; 414 } 415 416 417 AWT_UNLOCK(); 418 419 return target; 420 }