jdk/src/solaris/native/sun/awt/awt_Cursor.c
changeset 1211 b659a7cee935
parent 1210 7798f9e88bf9
parent 1203 3e5496df0d2b
child 1212 d718a4419361
equal deleted inserted replaced
1210:7798f9e88bf9 1211:b659a7cee935
     1 /*
       
     2  * Copyright 1998-2005 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 #ifdef HEADLESS
       
    27     #error This file should not be included in headless library
       
    28 #endif
       
    29 
       
    30 #include <Xm/Display.h>
       
    31 #include "awt_Component.h"
       
    32 #include "awt_Cursor.h"
       
    33 #include "java_awt_Cursor.h"
       
    34 #include <X11/cursorfont.h>
       
    35 
       
    36 #include "jni.h"
       
    37 #include "jni_util.h"
       
    38 
       
    39 /* fieldIDs for Cursor fields that may be accessed from C */
       
    40 struct CursorIDs cursorIDs;
       
    41 extern struct MComponentPeerIDs mComponentPeerIDs;
       
    42 
       
    43 static jweak curComp = 0;
       
    44 
       
    45 /*
       
    46  * Class:     java_awt_Cursor
       
    47  * Method:    initIDs
       
    48  * Signature: ()V
       
    49  */
       
    50 /*
       
    51  * This function gets called from the static initializer for Cursor.java
       
    52  * to initialize the fieldIDs for fields that may be accessed from C
       
    53  */
       
    54 JNIEXPORT void JNICALL
       
    55 Java_java_awt_Cursor_initIDs(JNIEnv *env, jclass cls)
       
    56 {
       
    57     cursorIDs.type = (*env)->GetFieldID(env, cls, "type", "I");
       
    58     cursorIDs.mSetPData = (*env)->GetMethodID(env, cls, "setPData", "(J)V");
       
    59     cursorIDs.pData = (*env)->GetFieldID(env, cls, "pData", "J");
       
    60 }
       
    61 
       
    62 /*
       
    63  * A utility to retrieve cursor from java.awt.Cursor
       
    64  * Create and save the cursor first if it is not yet
       
    65  */
       
    66 Cursor getCursor(JNIEnv *env, jobject jCur)
       
    67 {
       
    68     int32_t cursorType = 0;
       
    69     Cursor  xcursor;
       
    70 
       
    71     xcursor = (Cursor)(*env)->GetLongField(env, jCur, cursorIDs.pData);
       
    72 
       
    73     if (xcursor != None) {
       
    74         return xcursor;
       
    75     }
       
    76 
       
    77     cursorType = (*env)->GetIntField(env, jCur, cursorIDs.type);
       
    78 
       
    79     DASSERT(cursorType != java_awt_Cursor_CUSTOM_CURSOR);
       
    80 
       
    81     switch (cursorType) {
       
    82     case java_awt_Cursor_DEFAULT_CURSOR:
       
    83         cursorType = XC_left_ptr;
       
    84         break;
       
    85     case java_awt_Cursor_CROSSHAIR_CURSOR:
       
    86         cursorType = XC_crosshair;
       
    87         break;
       
    88     case java_awt_Cursor_TEXT_CURSOR:
       
    89         cursorType = XC_xterm;
       
    90         break;
       
    91     case java_awt_Cursor_WAIT_CURSOR:
       
    92         cursorType = XC_watch;
       
    93         break;
       
    94     case java_awt_Cursor_SW_RESIZE_CURSOR:
       
    95         cursorType = XC_bottom_left_corner;
       
    96         break;
       
    97     case java_awt_Cursor_NW_RESIZE_CURSOR:
       
    98         cursorType = XC_top_left_corner;
       
    99         break;
       
   100     case java_awt_Cursor_SE_RESIZE_CURSOR:
       
   101         cursorType = XC_bottom_right_corner;
       
   102         break;
       
   103     case java_awt_Cursor_NE_RESIZE_CURSOR:
       
   104         cursorType = XC_top_right_corner;
       
   105         break;
       
   106     case java_awt_Cursor_S_RESIZE_CURSOR:
       
   107         cursorType = XC_bottom_side;
       
   108         break;
       
   109     case java_awt_Cursor_N_RESIZE_CURSOR:
       
   110         cursorType = XC_top_side;
       
   111         break;
       
   112     case java_awt_Cursor_W_RESIZE_CURSOR:
       
   113         cursorType = XC_left_side;
       
   114         break;
       
   115     case java_awt_Cursor_E_RESIZE_CURSOR:
       
   116         cursorType = XC_right_side;
       
   117         break;
       
   118     case java_awt_Cursor_HAND_CURSOR:
       
   119         cursorType = XC_hand2;
       
   120         break;
       
   121     case java_awt_Cursor_MOVE_CURSOR:
       
   122         cursorType = XC_fleur;
       
   123         break;
       
   124     }
       
   125     xcursor = XCreateFontCursor(awt_display, cursorType);
       
   126 
       
   127     (*env)->CallVoidMethod(env, jCur, cursorIDs.mSetPData, xcursor);
       
   128     return xcursor;
       
   129 }
       
   130 
       
   131 /*
       
   132  * Class:     java_awt_Cursor
       
   133  * Method:    finalizeImpl
       
   134  * Signature: ()V
       
   135  */
       
   136 JNIEXPORT void JNICALL
       
   137 Java_java_awt_Cursor_finalizeImpl(JNIEnv *env, jclass clazz, jlong pData)
       
   138 {
       
   139     Cursor xcursor;
       
   140 
       
   141     xcursor = (Cursor)pData;
       
   142     if (xcursor != None) {
       
   143         AWT_LOCK();
       
   144         XFreeCursor(awt_display, xcursor);
       
   145         AWT_UNLOCK();
       
   146     }
       
   147 }
       
   148 
       
   149 /*
       
   150  *  normal replace : CACHE_UDPATE  => update curComp and updateCursor
       
   151  *  not replace    : UPDATE_ONLY   => intact curComp but updateCursor
       
   152  *  only replace   : CACHE_ONLY    => update curComp only, not updateCursor
       
   153  *
       
   154  *  This function should only be called under AWT_LOCK(). Otherwise
       
   155  *  multithreaded access can corrupt the value of curComp variable.
       
   156  */
       
   157 void updateCursor(XPointer client_data, int32_t replace) {
       
   158 
       
   159     static jclass globalCursorManagerClass = NULL;
       
   160     static jmethodID updateCursorID = NULL;
       
   161 
       
   162     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   163     jobject peer = (jobject) client_data;
       
   164     jobject target;
       
   165 
       
   166     if ((*env)->PushLocalFrame(env, 16) < 0)
       
   167         return;
       
   168 
       
   169     target = (*env)->GetObjectField(env, peer, mComponentPeerIDs.target);
       
   170     if (replace != UPDATE_ONLY) {
       
   171         if (!JNU_IsNull(env, curComp)) {
       
   172             (*env)->DeleteWeakGlobalRef(env, curComp);
       
   173         }
       
   174         curComp = (*env)->NewWeakGlobalRef(env, target);
       
   175         if (replace == CACHE_ONLY) {
       
   176             (*env)->PopLocalFrame(env, 0);
       
   177             return;
       
   178         }
       
   179     }
       
   180 
       
   181     /* Initialize our java identifiers once. Checking before locking
       
   182      * is a huge performance win.
       
   183      */
       
   184     if (globalCursorManagerClass == NULL) {
       
   185         jobject sysClass = (*env)->FindClass(env, "sun/awt/motif/MGlobalCursorManager");
       
   186         if (sysClass != NULL) {
       
   187             /* Make this class 'sticky', we don't want it GC'd */
       
   188             globalCursorManagerClass = (*env)->NewGlobalRef(env, sysClass);
       
   189 
       
   190             updateCursorID = (*env)->GetStaticMethodID(env,
       
   191                                                        globalCursorManagerClass,
       
   192                                                        "nativeUpdateCursor",
       
   193                                                        "(Ljava/awt/Component;)V"
       
   194                                                        );
       
   195         }
       
   196         if (JNU_IsNull(env, globalCursorManagerClass) || updateCursorID == NULL) {
       
   197             JNU_ThrowClassNotFoundException(env, "sun/awt/motif/MGlobalCursorManager");
       
   198             (*env)->PopLocalFrame(env, 0);
       
   199             return;
       
   200         }
       
   201     } /* globalCursorManagerClass == NULL*/
       
   202 
       
   203     (*env)->CallStaticVoidMethod(env, globalCursorManagerClass,
       
   204                                  updateCursorID, target);
       
   205     DASSERT(!((*env)->ExceptionOccurred(env)));
       
   206     (*env)->PopLocalFrame(env, 0);
       
   207 }
       
   208 
       
   209 /*
       
   210  * Only call this function under AWT_LOCK(). Otherwise multithreaded
       
   211  * access can corrupt the value of curComp variable.
       
   212  */
       
   213 jobject getCurComponent() {
       
   214     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   215     return (*env)->NewLocalRef(env, curComp);
       
   216 }