1 /*
   2  * Copyright (c) 2011, 2014, 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 #import "common.h"
  27 #import "com_sun_glass_ui_View.h"
  28 #import "com_sun_glass_ui_mac_MacView.h"
  29 #import "com_sun_glass_ui_View_Capability.h"
  30 #import "com_sun_glass_ui_Clipboard.h"
  31 #import "com_sun_glass_events_ViewEvent.h"
  32 
  33 #import "GlassMacros.h"
  34 #import "GlassWindow.h"
  35 #import "GlassView3D.h"
  36 #import "GlassHelper.h"
  37 #import "GlassLayer3D.h"
  38 
  39 //#define VERBOSE
  40 #ifndef VERBOSE
  41     #define LOG(MSG, ...)
  42 #else
  43     #define LOG(MSG, ...) GLASS_LOG(MSG, ## __VA_ARGS__);
  44 #endif
  45 
  46 //#define FORCE_NOISE
  47 #ifdef FORCE_NOISE
  48 static inline void *_GenerateNoise(int width, int height)
  49 {
  50     static int *pixels = NULL;
  51     pixels = realloc(pixels, width*height*4);
  52     
  53     int *src = pixels;
  54     for (int i=0; i<width*height; i++)
  55     {
  56         *src++ = random();
  57     }
  58     
  59     return (void*)pixels;
  60 }
  61 #endif
  62 
  63 static inline NSView<GlassView>* getGlassView(JNIEnv *env, jlong jPtr)
  64 {
  65     assert(jPtr != 0L);
  66 
  67     return (NSView<GlassView>*)jlong_to_ptr(jPtr);
  68 }
  69 
  70 #pragma mark --- JNI
  71 
  72 /*
  73  * Class:     com_sun_glass_ui_mac_MacView
  74  * Method:    _initIDs
  75  * Signature: ()V
  76  */
  77 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1initIDs
  78 (JNIEnv *env, jclass jClass)
  79 {
  80     LOG("Java_com_sun_glass_ui_mac_MacView__1initIDs");
  81     
  82     if (jViewClass == NULL)
  83     {
  84         jViewClass = (*env)->NewGlobalRef(env, jClass);
  85     }
  86     
  87     if (jIntegerClass == NULL)
  88     {
  89         jclass jcls = (*env)->FindClass(env, "java/lang/Integer");
  90         if ((*env)->ExceptionCheck(env)) return;
  91         jIntegerClass = (*env)->NewGlobalRef(env, jcls);
  92     }
  93     
  94     if (jMapClass == NULL)
  95     {
  96         jclass jcls = (*env)->FindClass(env, "java/util/Map");
  97         if ((*env)->ExceptionCheck(env)) return;
  98         jMapClass = (*env)->NewGlobalRef(env, jcls);
  99     }
 100     
 101     if (jBooleanClass == NULL)
 102     {
 103         jclass jcls = (*env)->FindClass(env, "java/lang/Boolean");
 104         if ((*env)->ExceptionCheck(env)) return;
 105         jBooleanClass = (*env)->NewGlobalRef(env, jcls);
 106     }
 107     
 108     if (jViewNotifyEvent == NULL)
 109     {
 110         jViewNotifyEvent = (*env)->GetMethodID(env, jViewClass, "notifyView", "(I)V");
 111         if ((*env)->ExceptionCheck(env)) return;
 112     }
 113     
 114     if (jViewNotifyRepaint == NULL)
 115     {
 116         jViewNotifyRepaint = (*env)->GetMethodID(env, jViewClass, "notifyRepaint", "(IIII)V");
 117         if ((*env)->ExceptionCheck(env)) return;
 118     }
 119     
 120     if (jViewNotifyResize == NULL)
 121     {
 122         jViewNotifyResize = (*env)->GetMethodID(env, jViewClass, "notifyResize", "(II)V");
 123         if ((*env)->ExceptionCheck(env)) return;
 124     }
 125     
 126     if (jViewNotifyKey == NULL)
 127     {
 128         jViewNotifyKey = (*env)->GetMethodID(env, jViewClass, "notifyKey", "(II[CI)V");
 129         if ((*env)->ExceptionCheck(env)) return;
 130     }
 131     
 132     if (jViewNotifyMenu == NULL)
 133     {
 134         jViewNotifyMenu = (*env)->GetMethodID(env, jViewClass, "notifyMenu", "(IIIIZ)V");
 135         if ((*env)->ExceptionCheck(env)) return;
 136     }
 137     
 138     if (jViewNotifyMouse == NULL)
 139     {
 140         jViewNotifyMouse = (*env)->GetMethodID(env, jViewClass, "notifyMouse", "(IIIIIIIZZ)V");
 141         if ((*env)->ExceptionCheck(env)) return;
 142     }
 143     
 144     if (jViewNotifyInputMethod == NULL)
 145     {
 146         jViewNotifyInputMethod = (*env)->GetMethodID(env, jViewClass, "notifyInputMethod", "(Ljava/lang/String;[I[I[BIII)V");
 147         if ((*env)->ExceptionCheck(env)) return;
 148     }
 149     
 150     if (jViewNotifyInputMethodMac == NULL)
 151     {
 152         jclass jMacViewClass = [GlassHelper ClassForName:"com.sun.glass.ui.mac.MacView" withEnv:env];
 153         jViewNotifyInputMethodMac = (*env)->GetMethodID(env, jMacViewClass, "notifyInputMethodMac", "(Ljava/lang/String;IIIII)V");
 154         if ((*env)->ExceptionCheck(env)) return;
 155     }
 156     
 157     if(jViewNotifyInputMethodCandidatePosRequest == NULL)
 158     {
 159         jViewNotifyInputMethodCandidatePosRequest = (*env)->GetMethodID(env, jViewClass, "notifyInputMethodCandidatePosRequest", "(I)[D");
 160         if ((*env)->ExceptionCheck(env)) return;
 161     }
 162     
 163     if (jViewNotifyDragEnter == NULL)
 164     {
 165         jViewNotifyDragEnter = (*env)->GetMethodID(env, jViewClass, "notifyDragEnter", "(IIIII)I");
 166         if ((*env)->ExceptionCheck(env)) return;
 167     }
 168     
 169     if (jViewNotifyDragOver == NULL)
 170     {
 171         jViewNotifyDragOver = (*env)->GetMethodID(env, jViewClass, "notifyDragOver", "(IIIII)I");
 172         if ((*env)->ExceptionCheck(env)) return;
 173     }
 174     
 175     if (jViewNotifyDragLeave == NULL)
 176     {
 177         jViewNotifyDragLeave = (*env)->GetMethodID(env, jViewClass, "notifyDragLeave", "()V");
 178         if ((*env)->ExceptionCheck(env)) return;
 179     }
 180     
 181     if (jViewNotifyDragDrop == NULL)
 182     {
 183         jViewNotifyDragDrop = (*env)->GetMethodID(env, jViewClass, "notifyDragDrop", "(IIIII)I");
 184         if ((*env)->ExceptionCheck(env)) return;
 185     }
 186     
 187     if (jViewNotifyDragEnd == NULL)
 188     {
 189         jViewNotifyDragEnd = (*env)->GetMethodID(env, jViewClass, "notifyDragEnd", "(I)V");
 190         if ((*env)->ExceptionCheck(env)) return;
 191     }
 192 
 193     if (jViewGetAccessible == NULL)
 194     {
 195         jViewGetAccessible = (*env)->GetMethodID(env, jViewClass, "getAccessible", "()J");
 196         if ((*env)->ExceptionCheck(env)) return;
 197     }
 198     
 199     if (jMapGetMethod == NULL)
 200     {
 201         jMapGetMethod = (*env)->GetMethodID(env, jMapClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
 202         if ((*env)->ExceptionCheck(env)) return;
 203     }
 204     
 205     if (jBooleanValueMethod == NULL)
 206     {
 207         jBooleanValueMethod = (*env)->GetMethodID(env, jBooleanClass, "booleanValue", "()Z");
 208         if ((*env)->ExceptionCheck(env)) return;
 209     }
 210     
 211     if (jIntegerInitMethod == NULL)
 212     {
 213         jIntegerInitMethod = (*env)->GetMethodID(env, jIntegerClass, "<init>", "(I)V");
 214         if ((*env)->ExceptionCheck(env)) return;
 215     }
 216     
 217     if (jIntegerValueMethod == NULL)
 218     {
 219         jIntegerValueMethod = (*env)->GetMethodID(env, jIntegerClass, "intValue", "()I");
 220         if ((*env)->ExceptionCheck(env)) return;
 221     }
 222         
 223     if (jLongClass == NULL)
 224     {
 225         jclass jcls = (*env)->FindClass(env, "java/lang/Long");
 226         if ((*env)->ExceptionCheck(env)) return;
 227         jLongClass = (*env)->NewGlobalRef(env, jcls);
 228     }
 229     
 230     if (jLongValueMethod == NULL)
 231     {
 232         jLongValueMethod = (*env)->GetMethodID(env, jLongClass, "longValue", "()J");
 233     }
 234 }
 235 
 236 /*
 237  * Class:     com_sun_glass_ui_mac_MacView
 238  * Method:    _getMultiClickTime_impl
 239  * Signature: ()J
 240  */
 241 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_mac_MacView__1getMultiClickTime_1impl
 242 (JNIEnv *env, jclass cls)
 243 {
 244     LOG("Java_com_sun_glass_ui_mac_MacView__1getMultiClickTime_1impl");
 245     
 246     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 247     
 248     // 10.6 API
 249     return (jlong)([NSEvent doubleClickInterval]*1000.0f);
 250 }
 251 
 252 /*
 253  * Class:     com_sun_glass_ui_mac_MacView
 254  * Method:    _getMultiClickMaxX_impl
 255  * Signature: ()I
 256  */
 257 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacView__1getMultiClickMaxX_1impl
 258 (JNIEnv *env, jclass cls)
 259 {
 260     LOG("Java_com_sun_glass_ui_mac_MacView__1getMultiClickMaxX_1impl");
 261     
 262     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 263     
 264     // gznote: there is no way to get this value out of the system
 265     // Most of the Mac machines use the value 3, so we hardcode this value
 266     return (jint)3;
 267 }
 268 
 269 /*
 270  * Class:     com_sun_glass_ui_mac_MacView
 271  * Method:    _getMultiClickMaxY_impl
 272  * Signature: ()I
 273  */
 274 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacView__1getMultiClickMaxY_1impl
 275 (JNIEnv *env, jclass cls)
 276 {
 277     LOG("Java_com_sun_glass_ui_mac_MacView__1getMultiClickMaxY_1impl");
 278     
 279     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 280     
 281     // gznote: there is no way to get this value out of the system
 282     // Most of the Mac machines use the value 3, so we hardcode this value
 283     return (jint)3;
 284 }
 285 
 286 /*
 287  * Class:     com_sun_glass_ui_mac_MacView
 288  * Method:    _create
 289  * Signature: (Ljava/util/Map;)J
 290  */
 291 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_mac_MacView__1create
 292 (JNIEnv *env, jobject jView, jobject jCapabilities)
 293 {
 294     LOG("Java_com_sun_glass_ui_mac_MacView__1create");
 295     
 296     jlong value = 0L;
 297     
 298     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 299     GLASS_POOL_ENTER;
 300     {
 301         jobject jViewRef = (*env)->NewGlobalRef(env, jView);
 302         jobject jCapabilitiesRef = NULL;
 303         if (jCapabilities != NULL)
 304         {
 305             jCapabilitiesRef = (*env)->NewGlobalRef(env, jCapabilities);
 306         }
 307 
 308         // embed ourselves into GlassHostView, so we can later swap our view between windows (ex. fullscreen mode)
 309         NSView *hostView = [[GlassHostView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]; // alloc creates ref count of 1
 310         [hostView setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)];
 311         [hostView setAutoresizesSubviews:YES];
 312         
 313         NSView* view = [[GlassView3D alloc] initWithFrame:[hostView bounds] withJview:jView withJproperties:jCapabilities];
 314         [view setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)];
 315         
 316         [hostView addSubview:view];
 317         jfieldID jfID = (*env)->GetFieldID(env, jViewClass, "ptr", "J");
 318         GLASS_CHECK_EXCEPTION(env);
 319         (*env)->SetLongField(env, jView, jfID, ptr_to_jlong(view));
 320         
 321         value = ptr_to_jlong(view);
 322 
 323         if (jCapabilities != NULL)
 324         {
 325             (*env)->DeleteGlobalRef(env, jCapabilitiesRef);
 326         }
 327         (*env)->DeleteGlobalRef(env, jViewRef);
 328     }
 329     GLASS_POOL_EXIT;
 330     GLASS_CHECK_EXCEPTION(env);
 331     
 332     LOG("   view: %p", value);
 333     return value;
 334 }
 335 
 336 /*
 337  * Class:     com_sun_glass_ui_mac_MacView
 338  * Method:    _getNativeFrameBuffer
 339  * Signature: (J)I
 340  */
 341 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacView__1getNativeFrameBuffer
 342 (JNIEnv *env, jobject jView, jlong jPtr)
 343 {
 344     LOG("Java_com_sun_glass_ui_mac_MacView__1_getNativeFrameBuffer");
 345     LOG("   view: %p", jPtr);
 346     if (!jPtr) return 0L;
 347     
 348     jint fb = 0;
 349     
 350     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 351     GLASS_POOL_ENTER;
 352     {
 353         NSView<GlassView> *view = getGlassView(env, jPtr);
 354         GlassLayer3D *layer = (GlassLayer3D*)[view layer];
 355         fb = (jint) [[layer getPainterOffscreen] fbo];
 356     }
 357     GLASS_POOL_EXIT;
 358     GLASS_CHECK_EXCEPTION(env);
 359 
 360     return fb;
 361 }
 362 
 363 /*
 364  * Class:     com_sun_glass_ui_mac_MacView
 365  * Method:    _getNativeLayer
 366  * Signature: (J)J
 367  */
 368 JNIEXPORT jlong JNICALL Java_com_sun_glass_ui_mac_MacView__1getNativeLayer
 369 (JNIEnv *env, jobject jView, jlong jPtr)
 370 {
 371     LOG("Java_com_sun_glass_ui_mac_MacView__1_getNativeLayer");
 372     LOG("   view: %p", jPtr);
 373     if (!jPtr) return 0L;
 374     
 375     jlong ptr = 0L;
 376     
 377     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 378     GLASS_POOL_ENTER;
 379     {
 380         NSView<GlassView> *view = getGlassView(env, jPtr);
 381         ptr = ptr_to_jlong([view layer]);
 382     }
 383     GLASS_POOL_EXIT;
 384     GLASS_CHECK_EXCEPTION(env);
 385     
 386     return ptr;
 387 }
 388 
 389 /*
 390  * Class:     com_sun_glass_ui_mac_MacView
 391  * Method:    _getNativeRemoteLayerId
 392  * Signature: (JLjava/lang/String;)I
 393  */
 394 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacView__1getNativeRemoteLayerId
 395 (JNIEnv *env, jobject jView, jlong jPtr, jstring jServerString)
 396 {
 397     LOG("Java_com_sun_glass_ui_mac_MacView__1_getNativeLayerId");
 398     LOG("   layer: %p", jPtr);
 399     if (!jPtr) return 0;
 400     
 401     jint layerId = 0;
 402     
 403     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 404     GLASS_POOL_ENTER;
 405     {
 406         NSView<GlassView> *view = getGlassView(env, jPtr);
 407         layerId = (jint)[view getRemoteLayerIdForServer:[GlassHelper nsStringWithJavaString:jServerString withEnv:env]];
 408     }
 409     GLASS_POOL_EXIT;
 410     GLASS_CHECK_EXCEPTION(env);
 411     
 412     LOG("   layerId: %d", layerId);
 413     return layerId;
 414 }
 415 
 416 /*
 417  * Class:     com_sun_glass_ui_mac_MacView
 418  * Method:    _hostRemoteLayerId
 419  * Signature: (JI)V
 420  */
 421 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1hostRemoteLayerId
 422 (JNIEnv *env, jobject jView, jlong jPtr, jint jRemoteLayerId)
 423 {
 424     LOG("Java_com_sun_glass_ui_mac_MacView__1hostRemoteLayerId");
 425     if (!jPtr) return;
 426     
 427     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 428     GLASS_POOL_ENTER;
 429     {
 430         if (jRemoteLayerId > 0)
 431         {
 432             NSView<GlassView> *view = getGlassView(env, jPtr);
 433             [view hostRemoteLayerId:(uint32_t)jRemoteLayerId];
 434         }
 435     }
 436     GLASS_POOL_EXIT;
 437     GLASS_CHECK_EXCEPTION(env);
 438 }
 439 
 440 /*
 441  * Class:     com_sun_glass_ui_mac_MacView
 442  * Method:    _getX
 443  * Signature: ()I
 444  */
 445 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacView__1getX
 446 (JNIEnv *env, jobject jView, jlong jPtr)
 447 {
 448     LOG("Java_com_sun_glass_ui_mac_MacView__1getX");
 449     if (!jPtr) return 0;
 450     
 451     jint x = 0;
 452     
 453     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 454     GLASS_POOL_ENTER;
 455     {
 456         NSView<GlassView> *view = getGlassView(env, jPtr);
 457         NSWindow *window = [view window];
 458         if (window != nil)
 459         {
 460             NSRect frame = [window frame];
 461             NSRect contentRect = [window contentRectForFrameRect:frame];
 462             x = (jint)(contentRect.origin.x - frame.origin.x);
 463         }
 464     }
 465     GLASS_POOL_EXIT;
 466     GLASS_CHECK_EXCEPTION(env);
 467     
 468     return x;
 469 }
 470 
 471 /*
 472  * Class:     com_sun_glass_ui_mac_MacView
 473  * Method:    _getY
 474  * Signature: ()I
 475  */
 476 JNIEXPORT jint JNICALL Java_com_sun_glass_ui_mac_MacView__1getY
 477 (JNIEnv *env, jobject jView, jlong jPtr)
 478 {
 479     LOG("Java_com_sun_glass_ui_mac_MacView__1getY");
 480     if (!jPtr) return 0;
 481     
 482     jint y = 0;
 483     
 484     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 485     GLASS_POOL_ENTER;
 486     {
 487         NSView<GlassView> *view = getGlassView(env, jPtr);
 488         NSWindow * window = [view window];
 489         if (window != nil)
 490         {
 491             NSRect frame = [window frame];
 492             NSRect contentRect = [window contentRectForFrameRect:frame];
 493             
 494             // Assume that the border in the bottom is zero-sized
 495             y = (jint)(frame.size.height - contentRect.size.height);
 496         }
 497     }
 498     GLASS_POOL_EXIT;
 499     GLASS_CHECK_EXCEPTION(env);
 500     
 501     return y;
 502 }
 503 
 504 /*
 505  * Class:     com_sun_glass_ui_mac_MacView
 506  * Method:    _setParent
 507  * Signature: (JJ)V
 508  */
 509 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1setParent
 510 (JNIEnv *env, jobject jView, jlong jPtr, jlong parentPtr)
 511 {
 512     LOG("Java_com_sun_glass_ui_mac_MacView__1setParent");
 513     LOG("   view: %p", jPtr);
 514     LOG("   parent: %p", parentPtr);
 515     if (!jPtr) return;
 516     
 517     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 518     // TODO: Java_com_sun_glass_ui_mac_MacView__1setParent
 519 }
 520 
 521 /*
 522  * Class:     com_sun_glass_ui_mac_MacView
 523  * Method:    _close
 524  * Signature: (J)Z
 525  */
 526 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacView__1close
 527 (JNIEnv *env, jobject jView, jlong jPtr)
 528 {
 529     LOG("Java_com_sun_glass_ui_mac_MacView__1close");
 530     if (!jPtr) return JNI_FALSE;
 531 
 532     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 533     GLASS_POOL_ENTER;
 534     {
 535         NSView<GlassView> *view = getGlassView(env, jPtr);
 536         NSView * host = [view superview];
 537         if (host != nil) {
 538             [view removeFromSuperview];
 539             [host release];
 540         }
 541         [view release];
 542     }
 543     GLASS_POOL_EXIT;
 544     GLASS_CHECK_EXCEPTION(env);
 545 
 546     return JNI_TRUE;
 547 }
 548 
 549 /*
 550  * Class:     com_sun_glass_ui_mac_MacView
 551  * Method:    _begin
 552  * Signature: ()V
 553  */
 554 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1begin
 555 (JNIEnv *env, jobject jView, jlong jPtr)
 556 {
 557     LOG("Java_com_sun_glass_ui_mac_MacView__1begin");
 558     if (!jPtr) return;
 559     
 560     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 561     NSView<GlassView> *view = getGlassView(env, jPtr);
 562     GLASS_POOL_PUSH; // it will be popped by "_end"
 563     {
 564         [view retain];
 565 //        [view lockFocus];
 566         [view begin];
 567     }
 568 }
 569 
 570 /*
 571  * Class:     com_sun_glass_ui_mac_MacView
 572  * Method:    _end
 573  * Signature: (Z)V
 574  */
 575 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1end
 576 (JNIEnv *env, jobject jView, jlong jPtr)
 577 {
 578     LOG("Java_com_sun_glass_ui_mac_MacView__1end");
 579     if (!jPtr) return;
 580     
 581     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 582     NSView<GlassView> *view = getGlassView(env, jPtr);
 583     {
 584         [view end];
 585 //        [view unlockFocus];
 586         [view release];
 587     }
 588     GLASS_POOL_POP; // it was pushed by "_begin"
 589 }
 590 
 591 /*
 592  * Class:     com_sun_glass_ui_mac_MacView
 593  * Method:    _scheduleRepaint
 594  * Signature: ()V
 595  */
 596 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1scheduleRepaint
 597 (JNIEnv *env, jobject jView, jlong jPtr)
 598 {
 599     LOG("Java_com_sun_glass_ui_mac_MacView__1scheduleRepaint");
 600     if (!jPtr) return;
 601     
 602     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 603     GLASS_POOL_ENTER;
 604     {
 605         NSView<GlassView> *view = getGlassView(env, jPtr);
 606         [view setNeedsDisplay:YES];
 607     }
 608     GLASS_POOL_EXIT;
 609     GLASS_CHECK_EXCEPTION(env);
 610 }
 611 
 612 /*
 613  * Class:     com_sun_glass_ui_mac_MacView
 614  * Method:    _enterFullscreen
 615  * Signature: (ZZZ)V
 616  */
 617 JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_mac_MacView__1enterFullscreen
 618 (JNIEnv *env, jobject jView, jlong jPtr, jboolean jAnimate, jboolean jKeepRatio, jboolean jHideCursor)
 619 {
 620     LOG("Java_com_sun_glass_ui_mac_MacView__1enterFullscreen");
 621     if (!jPtr) return JNI_FALSE;
 622     
 623     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 624     GLASS_POOL_ENTER;
 625     {
 626         NSView<GlassView> *view = getGlassView(env, jPtr);
 627         [view enterFullscreenWithAnimate:(jAnimate==JNI_TRUE) withKeepRatio:(jKeepRatio==JNI_TRUE) withHideCursor:(jHideCursor==JNI_TRUE)];
 628     }
 629     GLASS_POOL_EXIT;
 630     GLASS_CHECK_EXCEPTION(env);
 631     
 632     return JNI_TRUE; // gznote: remove this return value
 633 }
 634 
 635 /*
 636  * Class:     com_sun_glass_ui_mac_MacView
 637  * Method:    _exitFullscreen
 638  * Signature: (Z)V
 639  */
 640 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1exitFullscreen
 641 (JNIEnv *env, jobject jView, jlong jPtr, jboolean jAnimate)
 642 {
 643     LOG("Java_com_sun_glass_ui_mac_MacView__1exitFullscreen");
 644     if (!jPtr) return;
 645     
 646     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 647     GLASS_POOL_ENTER;
 648     {
 649         NSView<GlassView> *view = getGlassView(env, jPtr);
 650         [view exitFullscreenWithAnimate:(jAnimate==JNI_TRUE)];
 651     }
 652     GLASS_POOL_EXIT;
 653     GLASS_CHECK_EXCEPTION(env);
 654 }
 655 
 656 /*
 657  * Class:     com_sun_glass_ui_mac_MacView
 658  * Method:    _uploadPixelsDirect
 659  * Signature: (JLjava/nio/Buffer;II)V
 660  */
 661 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1uploadPixelsDirect
 662 (JNIEnv *env, jobject jView, jlong jPtr, jobject jBuffer, jint jWidth, jint jHeight)
 663 {
 664     LOG("Java_com_sun_glass_ui_mac_MacView__1uploadPixelsDirect");
 665     if (!jPtr) return;
 666     
 667     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 668     NSView<GlassView> *view = getGlassView(env, jPtr);
 669     
 670 #ifndef FORCE_NOISE
 671     void *pixels = (*env)->GetDirectBufferAddress(env, jBuffer);
 672 #else
 673     void *pixels = _GenerateNoise(jWidth, jHeight);
 674 #endif
 675     
 676     // must be in the middle of begin/end
 677     if ((jWidth > 0) && (jHeight > 0))
 678     {
 679         [view pushPixels:pixels withWidth:(GLuint)jWidth withHeight:(GLuint)jHeight withEnv:env];
 680     }
 681 }
 682 
 683 /*
 684  * Class:     com_sun_glass_ui_mac_MacView
 685  * Method:    _uploadPixelsByteArray
 686  * Signature: (J[BIII)V
 687  */
 688 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1uploadPixelsByteArray
 689 (JNIEnv *env, jobject jView, jlong jPtr, jbyteArray jArray, jint jOffset, jint jWidth, jint jHeight)
 690 {
 691     LOG("Java_com_sun_glass_ui_mac_MacView__1uploadPixelsByteArray");
 692     if (!jPtr) return;
 693     
 694     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 695     
 696     jboolean isCopy = JNI_FALSE;
 697     u_int8_t *data = (*env)->GetPrimitiveArrayCritical(env, jArray, &isCopy);
 698     {
 699         assert((4*jWidth*jHeight + jOffset) == (*env)->GetArrayLength(env, jArray));
 700         
 701         NSView<GlassView> *view = getGlassView(env, jPtr);
 702         
 703 #ifndef FORCE_NOISE
 704         void *pixels = (data+jOffset);
 705 #else
 706         void *pixels = _GenerateNoise(jWidth, jHeight);
 707 #endif
 708         
 709         // must be in the middle of begin/end
 710         if ((jWidth > 0) && (jHeight > 0))
 711         {
 712             [view pushPixels:pixels withWidth:(GLuint)jWidth withHeight:(GLuint)jHeight withEnv:env];
 713         }
 714     }
 715     (*env)->ReleasePrimitiveArrayCritical(env, jArray, data, JNI_ABORT);
 716 }
 717 
 718 /*
 719  * Class:     com_sun_glass_ui_mac_MacView
 720  * Method:    _uploadPixelsIntArray
 721  * Signature: (J[IIII)V
 722  */
 723 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1uploadPixelsIntArray
 724 (JNIEnv *env, jobject jView, jlong jPtr, jintArray jArray, jint jOffset, jint jWidth, jint jHeight)
 725 {
 726     LOG("Java_com_sun_glass_ui_mac_MacView__1uploadPixelsIntArray");
 727     if (!jPtr) return;
 728     
 729     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 730     
 731     jboolean isCopy = JNI_FALSE;
 732     u_int32_t *data = (*env)->GetPrimitiveArrayCritical(env, jArray, &isCopy);
 733     {
 734         assert((jWidth*jHeight + jOffset) == (*env)->GetArrayLength(env, jArray));
 735         
 736         NSView<GlassView> *view = getGlassView(env, jPtr);
 737         
 738 #ifndef FORCE_NOISE
 739         void *pixels = (data+jOffset);
 740 #else
 741         void *pixels = _GenerateNoise(jWidth, jHeight);
 742 #endif
 743         
 744         // must be in the middle of begin/end
 745         if ((jWidth > 0) && (jHeight > 0))
 746         {
 747             [view pushPixels:pixels withWidth:(GLuint)jWidth withHeight:(GLuint)jHeight withEnv:env];
 748         }
 749     }
 750     (*env)->ReleasePrimitiveArrayCritical(env, jArray, data, JNI_ABORT);
 751 }
 752 
 753 /*
 754  * Input methods callback
 755  */
 756 
 757 /*
 758  * Class:     com_sun_glass_ui_mac_MacView
 759  * Method:    _enableInputMethodEvents
 760  * Signature: (JZ)V
 761  */
 762 JNIEXPORT void JNICALL Java_com_sun_glass_ui_mac_MacView__1enableInputMethodEvents
 763 (JNIEnv *env, jobject jView, jlong ptr, jboolean enable)
 764 {
 765     LOG("Java_com_sun_glass_ui_mac_MacView__1enableInputMethodEvents");
 766     if (!ptr) return;
 767 
 768     GLASS_ASSERT_MAIN_JAVA_THREAD(env);
 769     GLASS_POOL_ENTER;
 770     {
 771         NSView<GlassView> *view = getGlassView(env, ptr);
 772         [view setInputMethodEnabled:(enable==JNI_TRUE)];
 773     }
 774     GLASS_POOL_EXIT;
 775     GLASS_CHECK_EXCEPTION(env);
 776 }