blob: 4b7586edf79ee7baf65009e98921c3598333f71e [file] [log] [blame]
/*
* Copyright 1995-2004 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#ifdef HEADLESS
#error This file should not be included in headless library
#endif
#include "awt_p.h"
#include "java_awt_Scrollbar.h"
#include "java_awt_event_MouseEvent.h"
#include "sun_awt_motif_MScrollbarPeer.h"
#include "sun_awt_motif_MComponentPeer.h"
#include "awt_Component.h"
#include "canvas.h"
#include <jni.h>
#include <jni_util.h>
#include "multi_font.h"
extern struct MComponentPeerIDs mComponentPeerIDs;
extern AwtGraphicsConfigDataPtr
copyGraphicsConfigToPeer(JNIEnv *env, jobject this);
/* fieldIDs for java.awt.Scrollbar fields that may be accessed from C */
static struct ScrollbarIDs {
jfieldID orientation;
jfieldID visibleAmount;
jfieldID lineIncrement;
jfieldID pageIncrement;
jfieldID value;
jfieldID minimum;
jfieldID maximum;
} targetIDs;
/* MScrollbarPeer callback methods */
static struct {
jmethodID lineUp;
jmethodID lineDown;
jmethodID pageUp;
jmethodID pageDown;
jmethodID drag;
jmethodID dragEnd;
jmethodID warp;
} peerIDs;
/*
* Class: java_awt_ScrollBar
* Method: initIDs
* Signature: ()V
*/
/* This function gets called from the static initializer for
Scrollbar.java to initialize the fieldIDs for fields that may
be accessed from C */
JNIEXPORT void JNICALL
Java_java_awt_Scrollbar_initIDs(JNIEnv *env, jclass cls)
{
targetIDs.orientation =
(*env)->GetFieldID(env, cls, "orientation", "I");
targetIDs.visibleAmount =
(*env)->GetFieldID(env, cls, "visibleAmount", "I");
targetIDs.lineIncrement =
(*env)->GetFieldID(env, cls, "lineIncrement", "I");
targetIDs.pageIncrement =
(*env)->GetFieldID(env, cls, "pageIncrement", "I");
targetIDs.value =
(*env)->GetFieldID(env, cls, "value", "I");
targetIDs.minimum =
(*env)->GetFieldID(env, cls, "minimum", "I");
targetIDs.maximum =
(*env)->GetFieldID(env, cls, "maximum", "I");
}
/*
* Class: sun_awt_motif_MComponentPeer
* Method: initIDs
* Signature: ()V
*/
/* This function gets called from the static initializer for
MScrollbarPeer to initialize the JNI ids for fields and methods
that may be accessed from C */
JNIEXPORT void JNICALL
Java_sun_awt_motif_MScrollbarPeer_initIDs(JNIEnv *env, jclass cls)
{
peerIDs.lineUp =
(*env)->GetMethodID(env, cls, "lineUp", "(I)V");
peerIDs.lineDown =
(*env)->GetMethodID(env, cls, "lineDown", "(I)V");
peerIDs.pageUp =
(*env)->GetMethodID(env, cls, "pageUp", "(I)V");
peerIDs.pageDown =
(*env)->GetMethodID(env, cls, "pageDown", "(I)V");
peerIDs.drag =
(*env)->GetMethodID(env, cls, "drag", "(I)V");
peerIDs.dragEnd =
(*env)->GetMethodID(env, cls, "dragEnd", "(I)V");
peerIDs.warp =
(*env)->GetMethodID(env, cls, "warp", "(I)V");
}
/*
* Call peer.jcallback(value)
*/
static void
DoJavaCallback(jobject peer, jmethodID jcallback, jint value)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
(*env)->CallVoidMethod(env, peer, jcallback, value);
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
}
static void /* XtCallbackProc */
decrementCallback(Widget w, jobject peer,
XmScrollBarCallbackStruct *scroll)
{
DASSERT(scroll->reason == XmCR_DECREMENT);
DoJavaCallback(peer, peerIDs.lineUp, scroll->value);
}
static void /* XtCallbackProc */
incrementCallback(Widget w, jobject peer,
XmScrollBarCallbackStruct *scroll)
{
DASSERT(scroll->reason == XmCR_INCREMENT);
DoJavaCallback(peer, peerIDs.lineDown, scroll->value);
}
static void /* XtCallbackProc */
pageDecrementCallback(Widget w, jobject peer,
XmScrollBarCallbackStruct *scroll)
{
DASSERT(scroll->reason == XmCR_PAGE_DECREMENT);
DoJavaCallback(peer, peerIDs.pageUp, scroll->value);
}
static void /* XtCallbackProc */
pageIncrementCallback(Widget w, jobject peer,
XmScrollBarCallbackStruct *scroll)
{
DASSERT(scroll->reason == XmCR_PAGE_INCREMENT);
DoJavaCallback(peer, peerIDs.pageDown, scroll->value);
}
static void /* XtCallbackProc */
dragCallback(Widget w, jobject peer,
XmScrollBarCallbackStruct *scroll)
{
DASSERT(scroll->reason == XmCR_DRAG);
DoJavaCallback(peer, peerIDs.drag, scroll->value);
}
static void /* XtCallbackProc */
dragEndCallback(Widget w, jobject peer,
XmScrollBarCallbackStruct *scroll)
{
DASSERT(scroll->reason == XmCR_VALUE_CHANGED);
DoJavaCallback(peer, peerIDs.dragEnd, scroll->value);
}
static void /* XtCallbackProc */
toTopCallback(Widget w, jobject peer,
XmScrollBarCallbackStruct *scroll)
{
DASSERT(scroll->reason == XmCR_TO_TOP);
DoJavaCallback(peer, peerIDs.warp, scroll->value);
}
static void /* XtCallbackProc */
toBottomCallback(Widget w, jobject peer,
XmScrollBarCallbackStruct *scroll)
{
DASSERT(scroll->reason == XmCR_TO_BOTTOM);
DoJavaCallback(peer, peerIDs.warp, scroll->value);
}
/*
* Class: sun_awt_motif_MScrollbarPeer
* Method: create
* Signature: (Lsun/awt/motif/MComponentPeer;)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_motif_MScrollbarPeer_create(JNIEnv *env, jobject this,
jobject parent)
{
Widget w;
jobject target;
XtPointer globalRef = (XtPointer) /* jobject */
awtJNI_CreateAndSetGlobalRef(env, this);
struct ComponentData *pdata; /* for parent */
struct ComponentData *sdata; /* for scrollbar */
AwtGraphicsConfigDataPtr adata;
int32_t value, visible, minimum, maximum;
int32_t lineIncrement, pageIncrement;
Pixel bg;
#define MAX_ARGC 20
Arg args[MAX_ARGC];
int32_t argc = 0;
AWT_LOCK();
if (JNU_IsNull(env, parent)) {
JNU_ThrowNullPointerException(env, "NullPointerException");
AWT_UNLOCK();
return;
}
pdata = (struct ComponentData *)
JNU_GetLongFieldAsPtr(env, parent, mComponentPeerIDs.pData);
target = (*env)->GetObjectField(env, this, mComponentPeerIDs.target);
if (JNU_IsNull(env, target) || pdata == NULL) {
JNU_ThrowNullPointerException(env, "NullPointerException");
AWT_UNLOCK();
return;
}
switch ((*env)->GetIntField(env, target, targetIDs.orientation)) {
case java_awt_Scrollbar_HORIZONTAL:
XtSetArg(args[argc], XmNorientation, XmHORIZONTAL);
argc++;
break;
case java_awt_Scrollbar_VERTICAL:
XtSetArg(args[argc], XmNorientation, XmVERTICAL);
argc++;
break;
default:
JNU_ThrowIllegalArgumentException(env, "bad scrollbar orientation");
AWT_UNLOCK();
return;
}
adata = copyGraphicsConfigToPeer(env, this);
XtVaGetValues(pdata->widget, XmNbackground, &bg, NULL);
visible = (int32_t) (*env)->GetIntField(env, target, targetIDs.visibleAmount);
value = (int32_t) (*env)->GetIntField(env, target, targetIDs.value);
minimum = (int32_t) (*env)->GetIntField(env, target, targetIDs.minimum);
maximum = (int32_t) (*env)->GetIntField(env, target, targetIDs.maximum);
lineIncrement =
(int32_t) (*env)->GetIntField(env, target, targetIDs.lineIncrement);
pageIncrement =
(int32_t) (*env)->GetIntField(env, target, targetIDs.pageIncrement);
/*
* Sanity check. Scrollbar.setValues should have taken care.
*/
DASSERT(maximum > minimum);
DASSERT(visible <= maximum - minimum);
DASSERT(visible >= 1);
DASSERT(value >= minimum);
DASSERT(value <= maximum - visible);
XtSetArg(args[argc], XmNx, 0); argc++;
XtSetArg(args[argc], XmNy, 0); argc++;
XtSetArg(args[argc], XmNvalue, value); argc++;
XtSetArg(args[argc], XmNsliderSize, visible); argc++;
XtSetArg(args[argc], XmNminimum, minimum); argc++;
XtSetArg(args[argc], XmNmaximum, maximum); argc++;
XtSetArg(args[argc], XmNincrement, lineIncrement); argc++;
XtSetArg(args[argc], XmNpageIncrement, pageIncrement); argc++;
XtSetArg(args[argc], XmNbackground, bg); argc++;
XtSetArg(args[argc], XmNrecomputeSize, False); argc++;
XtSetArg(args[argc], XmNuserData, globalRef); argc++;
XtSetArg(args[argc], XmNscreen,
ScreenOfDisplay(awt_display,
adata->awt_visInfo.screen)); argc++;
DASSERT(argc <= MAX_ARGC); /* sanity check */
sdata = ZALLOC(ComponentData);
if (sdata == NULL) {
JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
AWT_UNLOCK();
return;
}
JNU_SetLongFieldFromPtr(env, this, mComponentPeerIDs.pData, sdata);
sdata->widget = w =
XmCreateScrollBar(pdata->widget, "scrollbar", args, argc);
XtAddCallback(w, XmNdecrementCallback,
(XtCallbackProc)decrementCallback, globalRef);
XtAddCallback(w, XmNincrementCallback,
(XtCallbackProc)incrementCallback, globalRef);
XtAddCallback(w, XmNpageDecrementCallback,
(XtCallbackProc)pageDecrementCallback, globalRef);
XtAddCallback(w, XmNpageIncrementCallback,
(XtCallbackProc)pageIncrementCallback, globalRef);
XtAddCallback(w, XmNtoTopCallback,
(XtCallbackProc)toTopCallback, globalRef);
XtAddCallback(w, XmNtoBottomCallback,
(XtCallbackProc)toBottomCallback, globalRef);
XtAddCallback(w, XmNdragCallback,
(XtCallbackProc)dragCallback, globalRef);
XtAddCallback(w, XmNvalueChangedCallback,
(XtCallbackProc)dragEndCallback, globalRef);
/* Set up workaround for the continuous scrolling bug */
XtAddEventHandler(w, ButtonReleaseMask, False,
awt_motif_Scrollbar_ButtonReleaseHandler, NULL);
/* Fix for 4955950. ButtonRelease & MotionNotify should be handled as well */
XtAddEventHandler(w, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
False, awt_canvas_event_handler, globalRef);
XtSetMappedWhenManaged(w, False);
XtManageChild(w);
AWT_UNLOCK();
}
/*
* Class: sun_awt_motif_MScrollbarPeer
* Method: pSetValues
* Signature: (IIII)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_motif_MScrollbarPeer_pSetValues(JNIEnv *env, jobject this,
jint value, jint visible, jint minimum, jint maximum)
{
struct ComponentData *sdata;
AWT_LOCK();
sdata = (struct ComponentData *)
JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
if (sdata == NULL) {
JNU_ThrowNullPointerException(env, "NullPointerException");
AWT_UNLOCK();
return;
}
/* pass in visible for sliderSize since Motif will calculate the */
/* slider's size for us. */
XtVaSetValues(sdata->widget,
XmNminimum, minimum,
XmNmaximum, maximum,
XmNvalue, value,
XmNsliderSize, visible,
NULL);
AWT_FLUSH_UNLOCK();
}
/*
* Class: sun_awt_motif_MScrollbarPeer
* Method: setLineIncrement
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_motif_MScrollbarPeer_setLineIncrement(JNIEnv *env, jobject this,
jint value)
{
struct ComponentData *sdata;
AWT_LOCK();
sdata = (struct ComponentData *)
JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
if (sdata == NULL) {
JNU_ThrowNullPointerException(env, "NullPointerException");
AWT_UNLOCK();
return;
}
XtVaSetValues(sdata->widget,
XmNincrement, value,
NULL);
AWT_FLUSH_UNLOCK();
}
/*
* Class: sun_awt_motif_MScrollbarPeer
* Method: setPageIncrement
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_motif_MScrollbarPeer_setPageIncrement(JNIEnv *env, jobject this,
jint value)
{
struct ComponentData *sdata;
AWT_LOCK();
sdata = (struct ComponentData *)
JNU_GetLongFieldAsPtr(env, this, mComponentPeerIDs.pData);
if (sdata == NULL) {
JNU_ThrowNullPointerException(env, "NullPointerException");
AWT_UNLOCK();
return;
}
XtVaSetValues(sdata->widget,
XmNpageIncrement, value,
NULL);
AWT_FLUSH_UNLOCK();
}