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 } |
|