jdk/src/solaris/native/sun/awt/awt_Scrollbar.c
changeset 1192 715cf9378c53
parent 1051 90cf935adb35
parent 1191 f142c1da78c2
child 1193 41afb8ee8f45
equal deleted inserted replaced
1051:90cf935adb35 1192:715cf9378c53
     1 /*
       
     2  * Copyright 1995-2004 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 "awt_p.h"
       
    31 #include "java_awt_Scrollbar.h"
       
    32 #include "java_awt_event_MouseEvent.h"
       
    33 #include "sun_awt_motif_MScrollbarPeer.h"
       
    34 #include "sun_awt_motif_MComponentPeer.h"
       
    35 
       
    36 #include "awt_Component.h"
       
    37 #include "canvas.h"
       
    38 
       
    39 #include <jni.h>
       
    40 #include <jni_util.h>
       
    41 #include "multi_font.h"
       
    42 
       
    43 
       
    44 extern struct MComponentPeerIDs mComponentPeerIDs;
       
    45 extern AwtGraphicsConfigDataPtr
       
    46     copyGraphicsConfigToPeer(JNIEnv *env, jobject this);
       
    47 
       
    48 /* fieldIDs for java.awt.Scrollbar fields that may be accessed from C */
       
    49 static struct ScrollbarIDs {
       
    50     jfieldID orientation;
       
    51     jfieldID visibleAmount;
       
    52     jfieldID lineIncrement;
       
    53     jfieldID pageIncrement;
       
    54     jfieldID value;
       
    55     jfieldID minimum;
       
    56     jfieldID maximum;
       
    57 } targetIDs;
       
    58 
       
    59 /* MScrollbarPeer callback methods */
       
    60 static struct {
       
    61     jmethodID lineUp;
       
    62     jmethodID lineDown;
       
    63     jmethodID pageUp;
       
    64     jmethodID pageDown;
       
    65     jmethodID drag;
       
    66     jmethodID dragEnd;
       
    67     jmethodID warp;
       
    68 } peerIDs;
       
    69 
       
    70 
       
    71 
       
    72 /*
       
    73  * Class:     java_awt_ScrollBar
       
    74  * Method:    initIDs
       
    75  * Signature: ()V
       
    76  */
       
    77 
       
    78 /* This function gets called from the static initializer for
       
    79    Scrollbar.java to initialize the fieldIDs for fields that may
       
    80    be accessed from C */
       
    81 
       
    82 JNIEXPORT void JNICALL
       
    83 Java_java_awt_Scrollbar_initIDs(JNIEnv *env, jclass cls)
       
    84 {
       
    85     targetIDs.orientation =
       
    86       (*env)->GetFieldID(env, cls, "orientation", "I");
       
    87     targetIDs.visibleAmount =
       
    88       (*env)->GetFieldID(env, cls, "visibleAmount", "I");
       
    89     targetIDs.lineIncrement =
       
    90       (*env)->GetFieldID(env, cls, "lineIncrement", "I");
       
    91     targetIDs.pageIncrement =
       
    92       (*env)->GetFieldID(env, cls, "pageIncrement", "I");
       
    93     targetIDs.value =
       
    94       (*env)->GetFieldID(env, cls, "value", "I");
       
    95     targetIDs.minimum =
       
    96       (*env)->GetFieldID(env, cls, "minimum", "I");
       
    97     targetIDs.maximum =
       
    98       (*env)->GetFieldID(env, cls, "maximum", "I");
       
    99 }
       
   100 
       
   101 
       
   102 /*
       
   103  * Class:     sun_awt_motif_MComponentPeer
       
   104  * Method:    initIDs
       
   105  * Signature: ()V
       
   106  */
       
   107 
       
   108 /* This function gets called from the static initializer for
       
   109    MScrollbarPeer to initialize the JNI ids for fields and methods
       
   110    that may be accessed from C */
       
   111 
       
   112 JNIEXPORT void JNICALL
       
   113 Java_sun_awt_motif_MScrollbarPeer_initIDs(JNIEnv *env, jclass cls)
       
   114 {
       
   115     peerIDs.lineUp =
       
   116         (*env)->GetMethodID(env, cls, "lineUp",   "(I)V");
       
   117     peerIDs.lineDown =
       
   118         (*env)->GetMethodID(env, cls, "lineDown", "(I)V");
       
   119     peerIDs.pageUp =
       
   120         (*env)->GetMethodID(env, cls, "pageUp",   "(I)V");
       
   121     peerIDs.pageDown =
       
   122         (*env)->GetMethodID(env, cls, "pageDown", "(I)V");
       
   123     peerIDs.drag =
       
   124         (*env)->GetMethodID(env, cls, "drag",     "(I)V");
       
   125     peerIDs.dragEnd =
       
   126         (*env)->GetMethodID(env, cls, "dragEnd",  "(I)V");
       
   127     peerIDs.warp =
       
   128         (*env)->GetMethodID(env, cls, "warp",     "(I)V");
       
   129 }
       
   130 
       
   131 /*
       
   132  * Call peer.jcallback(value)
       
   133  */
       
   134 static void
       
   135 DoJavaCallback(jobject peer, jmethodID jcallback, jint value)
       
   136 {
       
   137     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
       
   138     (*env)->CallVoidMethod(env, peer, jcallback, value);
       
   139     if ((*env)->ExceptionOccurred(env)) {
       
   140         (*env)->ExceptionDescribe(env);
       
   141         (*env)->ExceptionClear(env);
       
   142     }
       
   143 }
       
   144 
       
   145 
       
   146 static void /* XtCallbackProc */
       
   147 decrementCallback(Widget w, jobject peer,
       
   148     XmScrollBarCallbackStruct *scroll)
       
   149 {
       
   150     DASSERT(scroll->reason == XmCR_DECREMENT);
       
   151     DoJavaCallback(peer, peerIDs.lineUp, scroll->value);
       
   152 }
       
   153 
       
   154 static void /* XtCallbackProc */
       
   155 incrementCallback(Widget w, jobject peer,
       
   156     XmScrollBarCallbackStruct *scroll)
       
   157 {
       
   158     DASSERT(scroll->reason == XmCR_INCREMENT);
       
   159     DoJavaCallback(peer, peerIDs.lineDown, scroll->value);
       
   160 }
       
   161 
       
   162 static void /* XtCallbackProc */
       
   163 pageDecrementCallback(Widget w, jobject peer,
       
   164     XmScrollBarCallbackStruct *scroll)
       
   165 {
       
   166     DASSERT(scroll->reason == XmCR_PAGE_DECREMENT);
       
   167     DoJavaCallback(peer, peerIDs.pageUp, scroll->value);
       
   168 }
       
   169 
       
   170 static void /* XtCallbackProc */
       
   171 pageIncrementCallback(Widget w, jobject peer,
       
   172     XmScrollBarCallbackStruct *scroll)
       
   173 {
       
   174     DASSERT(scroll->reason == XmCR_PAGE_INCREMENT);
       
   175     DoJavaCallback(peer, peerIDs.pageDown, scroll->value);
       
   176 }
       
   177 
       
   178 static void /* XtCallbackProc */
       
   179 dragCallback(Widget w, jobject peer,
       
   180     XmScrollBarCallbackStruct *scroll)
       
   181 {
       
   182     DASSERT(scroll->reason == XmCR_DRAG);
       
   183     DoJavaCallback(peer, peerIDs.drag, scroll->value);
       
   184 }
       
   185 
       
   186 static void /* XtCallbackProc */
       
   187 dragEndCallback(Widget w, jobject peer,
       
   188     XmScrollBarCallbackStruct *scroll)
       
   189 {
       
   190     DASSERT(scroll->reason == XmCR_VALUE_CHANGED);
       
   191     DoJavaCallback(peer, peerIDs.dragEnd, scroll->value);
       
   192 }
       
   193 
       
   194 static void /* XtCallbackProc */
       
   195 toTopCallback(Widget w, jobject peer,
       
   196     XmScrollBarCallbackStruct *scroll)
       
   197 {
       
   198     DASSERT(scroll->reason == XmCR_TO_TOP);
       
   199     DoJavaCallback(peer, peerIDs.warp, scroll->value);
       
   200 }
       
   201 
       
   202 static void /* XtCallbackProc */
       
   203 toBottomCallback(Widget w, jobject peer,
       
   204     XmScrollBarCallbackStruct *scroll)
       
   205 {
       
   206     DASSERT(scroll->reason == XmCR_TO_BOTTOM);
       
   207     DoJavaCallback(peer, peerIDs.warp, scroll->value);
       
   208 }
       
   209 
       
   210 
       
   211 /*
       
   212  * Class:     sun_awt_motif_MScrollbarPeer
       
   213  * Method:    create
       
   214  * Signature: (Lsun/awt/motif/MComponentPeer;)V
       
   215  */
       
   216 JNIEXPORT void JNICALL
       
   217 Java_sun_awt_motif_MScrollbarPeer_create(JNIEnv *env, jobject this,
       
   218     jobject parent)
       
   219 {
       
   220     Widget w;
       
   221 
       
   222     jobject target;
       
   223     XtPointer globalRef = (XtPointer) /* jobject */
       
   224         awtJNI_CreateAndSetGlobalRef(env, this);
       
   225 
       
   226     struct ComponentData *pdata; /* for parent     */
       
   227     struct ComponentData *sdata; /* for scrollbar */
       
   228     AwtGraphicsConfigDataPtr adata;
       
   229 
       
   230     int32_t value, visible, minimum, maximum;
       
   231     int32_t lineIncrement, pageIncrement;
       
   232     Pixel bg;
       
   233 
       
   234 #define MAX_ARGC 20
       
   235     Arg args[MAX_ARGC];
       
   236     int32_t argc = 0;
       
   237 
       
   238 
       
   239     AWT_LOCK();
       
   240 
       
   241     if (JNU_IsNull(env, parent)) {
       
   242         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   243         AWT_UNLOCK();
       
   244         return;
       
   245     }
       
   246 
       
   247     pdata = (struct ComponentData *)
       
   248         JNU_GetLongFieldAsPtr(env, parent, mComponentPeerIDs.pData);
       
   249 
       
   250     target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
       
   251 
       
   252     if (JNU_IsNull(env, target) || pdata == NULL) {
       
   253         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   254         AWT_UNLOCK();
       
   255         return;
       
   256     }
       
   257 
       
   258 
       
   259     switch ((*env)->GetIntField(env, target, targetIDs.orientation)) {
       
   260       case java_awt_Scrollbar_HORIZONTAL:
       
   261           XtSetArg(args[argc], XmNorientation, XmHORIZONTAL);
       
   262           argc++;
       
   263           break;
       
   264 
       
   265       case java_awt_Scrollbar_VERTICAL:
       
   266           XtSetArg(args[argc], XmNorientation, XmVERTICAL);
       
   267           argc++;
       
   268           break;
       
   269 
       
   270       default:
       
   271           JNU_ThrowIllegalArgumentException(env, "bad scrollbar orientation");
       
   272           AWT_UNLOCK();
       
   273           return;
       
   274     }
       
   275 
       
   276     adata = copyGraphicsConfigToPeer(env, this);
       
   277     XtVaGetValues(pdata->widget, XmNbackground, &bg, NULL);
       
   278 
       
   279     visible = (int32_t) (*env)->GetIntField(env, target, targetIDs.visibleAmount);
       
   280     value   = (int32_t) (*env)->GetIntField(env, target, targetIDs.value);
       
   281     minimum = (int32_t) (*env)->GetIntField(env, target, targetIDs.minimum);
       
   282     maximum = (int32_t) (*env)->GetIntField(env, target, targetIDs.maximum);
       
   283     lineIncrement =
       
   284               (int32_t) (*env)->GetIntField(env, target, targetIDs.lineIncrement);
       
   285     pageIncrement =
       
   286               (int32_t) (*env)->GetIntField(env, target, targetIDs.pageIncrement);
       
   287 
       
   288     /*
       
   289      * Sanity check.  Scrollbar.setValues should have taken care.
       
   290      */
       
   291     DASSERT(maximum > minimum);
       
   292     DASSERT(visible <= maximum - minimum);
       
   293     DASSERT(visible >= 1);
       
   294     DASSERT(value >= minimum);
       
   295     DASSERT(value <= maximum - visible);
       
   296 
       
   297     XtSetArg(args[argc], XmNx,             0);                  argc++;
       
   298     XtSetArg(args[argc], XmNy,             0);                  argc++;
       
   299     XtSetArg(args[argc], XmNvalue,         value);              argc++;
       
   300     XtSetArg(args[argc], XmNsliderSize,    visible);            argc++;
       
   301     XtSetArg(args[argc], XmNminimum,       minimum);            argc++;
       
   302     XtSetArg(args[argc], XmNmaximum,       maximum);            argc++;
       
   303     XtSetArg(args[argc], XmNincrement,     lineIncrement);      argc++;
       
   304     XtSetArg(args[argc], XmNpageIncrement, pageIncrement);      argc++;
       
   305     XtSetArg(args[argc], XmNbackground,    bg);                 argc++;
       
   306     XtSetArg(args[argc], XmNrecomputeSize, False);              argc++;
       
   307     XtSetArg(args[argc], XmNuserData,      globalRef);          argc++;
       
   308     XtSetArg(args[argc], XmNscreen,
       
   309                              ScreenOfDisplay(awt_display,
       
   310                                  adata->awt_visInfo.screen));   argc++;
       
   311 
       
   312     DASSERT(argc <= MAX_ARGC);  /* sanity check */
       
   313 
       
   314     sdata = ZALLOC(ComponentData);
       
   315     if (sdata == NULL) {
       
   316         JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
       
   317         AWT_UNLOCK();
       
   318         return;
       
   319     }
       
   320 
       
   321     JNU_SetLongFieldFromPtr(env, this, mComponentPeerIDs.pData, sdata);
       
   322 
       
   323     sdata->widget = w =
       
   324         XmCreateScrollBar(pdata->widget, "scrollbar", args, argc);
       
   325 
       
   326     XtAddCallback(w, XmNdecrementCallback,
       
   327         (XtCallbackProc)decrementCallback, globalRef);
       
   328     XtAddCallback(w, XmNincrementCallback,
       
   329         (XtCallbackProc)incrementCallback, globalRef);
       
   330     XtAddCallback(w, XmNpageDecrementCallback,
       
   331         (XtCallbackProc)pageDecrementCallback, globalRef);
       
   332     XtAddCallback(w, XmNpageIncrementCallback,
       
   333         (XtCallbackProc)pageIncrementCallback, globalRef);
       
   334     XtAddCallback(w, XmNtoTopCallback,
       
   335         (XtCallbackProc)toTopCallback, globalRef);
       
   336     XtAddCallback(w, XmNtoBottomCallback,
       
   337         (XtCallbackProc)toBottomCallback, globalRef);
       
   338     XtAddCallback(w, XmNdragCallback,
       
   339         (XtCallbackProc)dragCallback, globalRef);
       
   340     XtAddCallback(w, XmNvalueChangedCallback,
       
   341         (XtCallbackProc)dragEndCallback, globalRef);
       
   342 
       
   343     /* Set up workaround for the continuous scrolling bug */
       
   344     XtAddEventHandler(w, ButtonReleaseMask, False,
       
   345         awt_motif_Scrollbar_ButtonReleaseHandler, NULL);
       
   346 
       
   347     /* Fix for 4955950. ButtonRelease & MotionNotify should be handled as well */
       
   348     XtAddEventHandler(w, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
       
   349                       False, awt_canvas_event_handler, globalRef);
       
   350 
       
   351     XtSetMappedWhenManaged(w, False);
       
   352     XtManageChild(w);
       
   353 
       
   354     AWT_UNLOCK();
       
   355 }
       
   356 
       
   357 /*
       
   358  * Class:     sun_awt_motif_MScrollbarPeer
       
   359  * Method:    pSetValues
       
   360  * Signature: (IIII)V
       
   361  */
       
   362 JNIEXPORT void JNICALL
       
   363 Java_sun_awt_motif_MScrollbarPeer_pSetValues(JNIEnv *env, jobject this,
       
   364     jint value, jint visible, jint minimum, jint maximum)
       
   365 {
       
   366     struct ComponentData *sdata;
       
   367 
       
   368     AWT_LOCK();
       
   369 
       
   370     sdata = (struct ComponentData *)
       
   371         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
   372     if (sdata == NULL) {
       
   373         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   374         AWT_UNLOCK();
       
   375         return;
       
   376     }
       
   377     /* pass in visible for sliderSize since Motif will calculate the */
       
   378     /* slider's size for us. */
       
   379     XtVaSetValues(sdata->widget,
       
   380                   XmNminimum, minimum,
       
   381                   XmNmaximum, maximum,
       
   382                   XmNvalue, value,
       
   383                   XmNsliderSize, visible,
       
   384                   NULL);
       
   385     AWT_FLUSH_UNLOCK();
       
   386 }
       
   387 
       
   388 
       
   389 /*
       
   390  * Class:     sun_awt_motif_MScrollbarPeer
       
   391  * Method:    setLineIncrement
       
   392  * Signature: (I)V
       
   393  */
       
   394 JNIEXPORT void JNICALL
       
   395 Java_sun_awt_motif_MScrollbarPeer_setLineIncrement(JNIEnv *env, jobject this,
       
   396     jint value)
       
   397 {
       
   398     struct ComponentData *sdata;
       
   399 
       
   400     AWT_LOCK();
       
   401 
       
   402     sdata = (struct ComponentData *)
       
   403         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
   404     if (sdata == NULL) {
       
   405         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   406         AWT_UNLOCK();
       
   407         return;
       
   408     }
       
   409     XtVaSetValues(sdata->widget,
       
   410                   XmNincrement, value,
       
   411                   NULL);
       
   412     AWT_FLUSH_UNLOCK();
       
   413 }
       
   414 
       
   415 
       
   416 /*
       
   417  * Class:     sun_awt_motif_MScrollbarPeer
       
   418  * Method:    setPageIncrement
       
   419  * Signature: (I)V
       
   420  */
       
   421 JNIEXPORT void JNICALL
       
   422 Java_sun_awt_motif_MScrollbarPeer_setPageIncrement(JNIEnv *env, jobject this,
       
   423     jint value)
       
   424 {
       
   425     struct ComponentData *sdata;
       
   426 
       
   427     AWT_LOCK();
       
   428 
       
   429     sdata = (struct ComponentData *)
       
   430         JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
       
   431     if (sdata == NULL) {
       
   432         JNU_ThrowNullPointerException(env, "NullPointerException");
       
   433         AWT_UNLOCK();
       
   434         return;
       
   435     }
       
   436     XtVaSetValues(sdata->widget,
       
   437                   XmNpageIncrement, value,
       
   438                   NULL);
       
   439     AWT_FLUSH_UNLOCK();
       
   440 }