1 /*
2  * Copyright (c) 1996, 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 #include "awt_ScrollPane.h"
27 
28 #include "awt_Container.h"
29 #include "awt_Insets.h"
30 #include "awt_Panel.h"
31 #include "awt_Scrollbar.h"   // static #defines
32 #include "awt_Toolkit.h"
33 #include "awt_Window.h"
34 
35 #include <java_awt_Adjustable.h>
36 #include <java_awt_ScrollPane.h>
37 #include <java_awt_ScrollPaneAdjustable.h>
38 #include <java_awt_event_AdjustmentEvent.h>
39 
40 
41 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
42  */
43 
44 /***********************************************************************/
45 // struct for _GetOffset() method
46 struct GetOffsetStruct {
47     jobject scrollpane;
48     jint orient;
49 };
50 // struct for _SetScrollPos() method
51 struct SetScrollPosStruct {
52     jobject scrollpane;
53     jint x, y;
54 };
55 // struct for _SetSpans() method
56 struct SetSpansStruct {
57     jobject scrollpane;
58     jint parentWidth;
59     jint parentHeight;
60     jint childWidth;
61     jint childHeight;
62 };
63 /************************************************************************
64  * AwtScrollPane fields
65  */
66 
67 jfieldID AwtScrollPane::scrollbarDisplayPolicyID;
68 jfieldID AwtScrollPane::hAdjustableID;
69 jfieldID AwtScrollPane::vAdjustableID;
70 jfieldID AwtScrollPane::unitIncrementID;
71 jfieldID AwtScrollPane::blockIncrementID;
72 jmethodID AwtScrollPane::postScrollEventID;
73 
74 /************************************************************************
75  * AwtScrollPane methods
76  */
77 
AwtScrollPane()78 AwtScrollPane::AwtScrollPane() {
79 }
80 
GetClassName()81 LPCTSTR AwtScrollPane::GetClassName() {
82     return TEXT("SunAwtScrollPane");
83 }
84 
85 /* Create a new AwtScrollPane object and window.   */
Create(jobject self,jobject parent)86 AwtScrollPane* AwtScrollPane::Create(jobject self, jobject parent)
87 {
88     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
89     jobject target = NULL;
90     AwtScrollPane* c = NULL;
91 
92     try {
93         if (env->EnsureLocalCapacity(1) < 0) {
94             return NULL;
95         }
96 
97         PDATA pData;
98         AwtComponent* awtParent;
99 
100         JNI_CHECK_PEER_GOTO(parent, done);
101         awtParent = (AwtComponent*)pData;
102 
103         target = env->GetObjectField(self, AwtObject::targetID);
104         JNI_CHECK_NULL_GOTO(target, "null target", done);
105 
106         c = new AwtScrollPane();
107 
108         {
109             DWORD style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
110             jint scrollbarDisplayPolicy =
111                 env->GetIntField(target, scrollbarDisplayPolicyID);
112 
113             if (scrollbarDisplayPolicy
114                     == java_awt_ScrollPane_SCROLLBARS_ALWAYS) {
115                 style |= WS_HSCROLL | WS_VSCROLL;
116             }
117             DWORD exStyle = WS_EX_CLIENTEDGE;
118 
119             if (GetRTL()) {
120                 exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
121                 if (GetRTLReadingOrder())
122                     exStyle |= WS_EX_RTLREADING;
123             }
124 
125             jint x = env->GetIntField(target, AwtComponent::xID);
126             jint y = env->GetIntField(target, AwtComponent::yID);
127             jint width = env->GetIntField(target, AwtComponent::widthID);
128             jint height = env->GetIntField(target, AwtComponent::heightID);
129             c->CreateHWnd(env, L"", style, exStyle,
130                           x, y, width, height,
131                           awtParent->GetHWnd(),
132                           reinterpret_cast<HMENU>(static_cast<INT_PTR>(
133                 awtParent->CreateControlID())),
134                           ::GetSysColor(COLOR_WINDOWTEXT),
135                           ::GetSysColor(COLOR_WINDOW),
136                           self);
137         }
138     } catch (...) {
139         env->DeleteLocalRef(target);
140         throw;
141     }
142 
143 done:
144     env->DeleteLocalRef(target);
145     return c;
146 }
147 
SetInsets(JNIEnv * env)148 void AwtScrollPane::SetInsets(JNIEnv *env)
149 {
150     RECT outside;
151     RECT inside;
152     ::GetWindowRect(GetHWnd(), &outside);
153     ::GetClientRect(GetHWnd(), &inside);
154     ::MapWindowPoints(GetHWnd(), 0, (LPPOINT)&inside, 2);
155 
156     if (env->EnsureLocalCapacity(1) < 0) {
157         return;
158     }
159     jobject insets =
160       (env)->GetObjectField(GetPeer(env), AwtPanel::insets_ID);
161 
162     DASSERT(!safe_ExceptionOccurred(env));
163 
164     if (insets != NULL && (inside.top-outside.top) != 0) {
165         (env)->SetIntField(insets, AwtInsets::topID, inside.top - outside.top);
166         (env)->SetIntField(insets, AwtInsets::leftID, inside.left - outside.left);
167         (env)->SetIntField(insets, AwtInsets::bottomID, outside.bottom - inside.bottom);
168         (env)->SetIntField(insets, AwtInsets::rightID, outside.right - inside.right);
169     }
170 
171     env->DeleteLocalRef(insets);
172 }
173 
SetScrollInfo(int orient,int max,int page,BOOL disableNoScroll)174 void AwtScrollPane::SetScrollInfo(int orient, int max, int page,
175                                   BOOL disableNoScroll)
176 {
177     DTRACE_PRINTLN4("AwtScrollPane::SetScrollInfo %d, %d, %d, %d", orient, max, page, disableNoScroll);
178     SCROLLINFO si;
179     int posBefore;
180     int posAfter;
181 
182     posBefore = GetScrollPos(orient);
183     si.cbSize = sizeof(SCROLLINFO);
184     si.nMin = 0;
185     si.nMax = max;
186     si.fMask = SIF_RANGE;
187     if (disableNoScroll) {
188         si.fMask |= SIF_DISABLENOSCROLL;
189     }
190     if (page > 0) {
191         si.fMask |= SIF_PAGE;
192         si.nPage = page;
193     }
194     ::SetScrollInfo(GetHWnd(), orient, &si, TRUE);
195     // scroll position may have changed when thumb is at the end of the bar
196     // and the page size changes
197     posAfter = GetScrollPos(orient);
198     if (posBefore != posAfter) {
199         PostScrollEvent(orient, SB_THUMBPOSITION, posAfter);
200     }
201 }
202 
RecalcSizes(int parentWidth,int parentHeight,int childWidth,int childHeight)203 void AwtScrollPane::RecalcSizes(int parentWidth, int parentHeight,
204                                 int childWidth, int childHeight)
205 {
206     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
207     if (env->EnsureLocalCapacity(2) < 0) {
208         return;
209     }
210 
211     /* Determine border width without scrollbars. */
212     int horzBorder = ::GetSystemMetrics(SM_CXEDGE);;
213     int vertBorder = ::GetSystemMetrics(SM_CYEDGE);;
214 
215     parentWidth -= (horzBorder * 2);
216     parentHeight -= (vertBorder * 2);
217 
218     /* Enable each scrollbar as needed. */
219     jobject target = AwtObject::GetTarget(env);
220     jint policy = env->GetIntField(target,
221                                    AwtScrollPane::scrollbarDisplayPolicyID);
222 
223     BOOL needsHorz=(policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS ||
224                     (policy == java_awt_ScrollPane_SCROLLBARS_AS_NEEDED &&
225                      childWidth > parentWidth));
226     if (needsHorz) {
227         parentHeight -= ::GetSystemMetrics(SM_CYHSCROLL);
228     }
229     BOOL needsVert=(policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS ||
230                     (policy ==java_awt_ScrollPane_SCROLLBARS_AS_NEEDED &&
231                      childHeight > parentHeight));
232     if (needsVert) {
233         parentWidth -= ::GetSystemMetrics(SM_CXVSCROLL);
234     }
235     /*
236      * Since the vertical scrollbar may have reduced the parent width
237      * enough to now require a horizontal scrollbar, we need to
238      * recalculate the horizontal metrics and scrollbar boolean.
239      */
240     if (!needsHorz) {
241         needsHorz = (policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS ||
242                      (policy == java_awt_ScrollPane_SCROLLBARS_AS_NEEDED &&
243                       childWidth > parentWidth));
244         if (needsHorz) {
245             parentHeight -= ::GetSystemMetrics(SM_CYHSCROLL);
246         }
247     }
248 
249     /* Now set ranges -- setting the min and max the same disables them. */
250     if (needsHorz) {
251         jobject hAdj =
252             env->GetObjectField(target, AwtScrollPane::hAdjustableID);
253         env->SetIntField(hAdj, AwtScrollPane::blockIncrementID, parentWidth);
254         SetScrollInfo(SB_HORZ, childWidth - 1, parentWidth,
255                       (policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS));
256         env->DeleteLocalRef(hAdj);
257     } else {
258         /* Set scroll info to imitate the behaviour and since we don't
259             need to display it, explicitly don't show the bar */
260         SetScrollInfo(SB_HORZ, childWidth - 1, parentWidth,
261                       (policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS));
262         ::ShowScrollBar(GetHWnd(), SB_HORZ, false);
263     }
264 
265     if (needsVert) {
266         jobject vAdj =
267             env->GetObjectField(target, AwtScrollPane::vAdjustableID);
268         env->SetIntField(vAdj, AwtScrollPane::blockIncrementID, parentHeight);
269         SetScrollInfo(SB_VERT, childHeight - 1, parentHeight,
270                       (policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS));
271         env->DeleteLocalRef(vAdj);
272     } else {
273         /* Set scroll info to imitate the behaviour and since we don't
274             need to display it, explicitly don't show the bar */
275         SetScrollInfo(SB_VERT, childHeight - 1, parentHeight,
276                       (policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS));
277         ::ShowScrollBar(GetHWnd(), SB_VERT, false);
278     }
279 
280     env->DeleteLocalRef(target);
281 }
282 
Reshape(int x,int y,int w,int h)283 void AwtScrollPane::Reshape(int x, int y, int w, int h)
284 {
285     AwtComponent::Reshape(x, y, w, h);
286 }
287 
Show(JNIEnv * env)288 void AwtScrollPane::Show(JNIEnv *env)
289 {
290     SetInsets(env);
291     SendMessage(WM_AWT_COMPONENT_SHOW);
292 }
293 
PostScrollEvent(int orient,int scrollCode,int pos)294 void AwtScrollPane::PostScrollEvent(int orient, int scrollCode, int pos) {
295     if (scrollCode == SB_ENDSCROLL) {
296         return;
297     }
298 
299     // convert Windows scroll bar ident to peer ident
300     jint jorient;
301     if (orient == SB_VERT) {
302         jorient = java_awt_Adjustable_VERTICAL;
303     } else if (orient == SB_HORZ) {
304         jorient = java_awt_Adjustable_HORIZONTAL;
305     } else {
306         DASSERT(FALSE);
307         return;
308     }
309 
310     // convert Windows scroll code to adjustment type and isAdjusting status
311     jint jscrollcode;
312     jboolean jadjusting = JNI_FALSE;
313     SCROLLINFO si;
314     switch (scrollCode) {
315       case SB_LINEUP:
316           jscrollcode = java_awt_event_AdjustmentEvent_UNIT_DECREMENT;
317           break;
318       case SB_LINEDOWN:
319           jscrollcode = java_awt_event_AdjustmentEvent_UNIT_INCREMENT;
320           break;
321       case SB_PAGEUP:
322           jscrollcode = java_awt_event_AdjustmentEvent_BLOCK_DECREMENT;
323           break;
324       case SB_PAGEDOWN:
325           jscrollcode = java_awt_event_AdjustmentEvent_BLOCK_INCREMENT;
326           break;
327       case SB_TOP:
328           jscrollcode = java_awt_event_AdjustmentEvent_TRACK;
329           ZeroMemory(&si, sizeof(si));
330           si.cbSize = sizeof(si);
331           si.fMask = SIF_RANGE;
332           ::GetScrollInfo(GetHWnd(), orient, &si);
333           pos = si.nMin;
334           break;
335       case SB_BOTTOM:
336           jscrollcode = java_awt_event_AdjustmentEvent_TRACK;
337           ZeroMemory(&si, sizeof(si));
338           si.cbSize = sizeof(si);
339           si.fMask = SIF_RANGE;
340           ::GetScrollInfo(GetHWnd(), orient, &si);
341           pos = si.nMax;
342           break;
343       case SB_THUMBTRACK:
344           jscrollcode = java_awt_event_AdjustmentEvent_TRACK;
345           jadjusting = JNI_TRUE;
346           break;
347       case SB_THUMBPOSITION:
348           jscrollcode = java_awt_event_AdjustmentEvent_TRACK;
349           break;
350       default:
351           DASSERT(FALSE);
352           return;
353     }
354 
355     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
356     env->CallVoidMethod(GetPeer(env), AwtScrollPane::postScrollEventID,
357                         jorient, jscrollcode, (jint)pos, jadjusting);
358     DASSERT(!safe_ExceptionOccurred(env));
359 }
360 
361 MsgRouting
WmNcHitTest(UINT x,UINT y,LRESULT & retVal)362 AwtScrollPane::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
363 {
364     if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd())))) {
365         retVal = HTCLIENT;
366         return mrConsume;
367     }
368     return AwtCanvas::WmNcHitTest(x, y, retVal);
369 }
370 
WmVScroll(UINT scrollCode,UINT pos,HWND hScrollPane)371 MsgRouting AwtScrollPane::WmVScroll(UINT scrollCode, UINT pos, HWND hScrollPane)
372 {
373     // While user scrolls using tracker, SCROLLINFO.nPos is not changed, SCROLLINFO.nTrackPos is changed instead.
374     int dragP = scrollCode == SB_THUMBPOSITION || scrollCode == SB_THUMBTRACK;
375     int newPos = GetScrollPos(SB_VERT);
376     if ( dragP ) {
377         SCROLLINFO si;
378         ZeroMemory(&si, sizeof(si));
379         si.cbSize = sizeof(si);
380         si.fMask = SIF_TRACKPOS;
381         ::GetScrollInfo(GetHWnd(), SB_VERT, &si);
382         newPos = si.nTrackPos;
383     }
384     PostScrollEvent(SB_VERT, scrollCode, newPos);
385     return mrConsume;
386 }
387 
WmHScroll(UINT scrollCode,UINT pos,HWND hScrollPane)388 MsgRouting AwtScrollPane::WmHScroll(UINT scrollCode, UINT pos, HWND hScrollPane)
389 {
390     // While user scrolls using tracker, SCROLLINFO.nPos is not changed, SCROLLINFO.nTrackPos is changed instead.
391     int dragP = scrollCode == SB_THUMBPOSITION || scrollCode == SB_THUMBTRACK;
392     int newPos = GetScrollPos(SB_HORZ);
393     if ( dragP ) {
394         SCROLLINFO si;
395         ZeroMemory(&si, sizeof(si));
396         si.cbSize = sizeof(si);
397         si.fMask = SIF_TRACKPOS;
398         ::GetScrollInfo(GetHWnd(), SB_HORZ, &si);
399         newPos = si.nTrackPos;
400     }
401     PostScrollEvent(SB_HORZ, scrollCode, newPos);
402     return mrConsume;
403 }
404 
HandleEvent(MSG * msg,BOOL synthetic)405 MsgRouting AwtScrollPane::HandleEvent(MSG *msg, BOOL synthetic)
406 {
407     // SunAwtScrollPane control doesn't cause activation on mouse/key events,
408     // so we can safely (for synthetic focus) pass them to the system proc.
409     return AwtComponent::HandleEvent(msg, synthetic);
410 }
411 
GetScrollPos(int orient)412 int AwtScrollPane::GetScrollPos(int orient)
413 {
414     SCROLLINFO si;
415     ZeroMemory(&si, sizeof(si));
416     si.cbSize = sizeof(si);
417     si.fMask = SIF_POS;
418     ::GetScrollInfo(GetHWnd(), orient, &si);
419     return si.nPos;
420 }
421 
_GetOffset(void * param)422 jint AwtScrollPane::_GetOffset(void *param)
423 {
424     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
425 
426     GetOffsetStruct *gos = (GetOffsetStruct *)param;
427     jobject self = gos->scrollpane;
428     jint orient = gos->orient;
429 
430     jint result = 0;
431     AwtScrollPane *s = NULL;
432 
433     PDATA pData;
434     JNI_CHECK_PEER_GOTO(self, ret);
435     s = (AwtScrollPane *)pData;
436     if (::IsWindow(s->GetHWnd()))
437     {
438         DTRACE_PRINTLN2("%x: WScrollPanePeer.getOffset(%d)", self, orient);
439         s->VerifyState();
440         int nBar = (orient == java_awt_Adjustable_HORIZONTAL) ? SB_HORZ : SB_VERT;
441         result = s->GetScrollPos(nBar);
442     }
443 ret:
444    env->DeleteGlobalRef(self);
445 
446    delete gos;
447 
448    return result;
449 }
450 
_SetInsets(void * param)451 void AwtScrollPane::_SetInsets(void *param)
452 {
453     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
454 
455     jobject self = (jobject)param;
456 
457     AwtScrollPane *s = NULL;
458 
459     PDATA pData;
460     JNI_CHECK_PEER_GOTO(self, ret);
461     s = (AwtScrollPane *)pData;
462     if (::IsWindow(s->GetHWnd()))
463     {
464         DTRACE_PRINTLN1("%x: WScrollPanePeer.setInsets()", self);
465         s->SetInsets(env);
466         s->VerifyState();
467     }
468 ret:
469    env->DeleteGlobalRef(self);
470 }
471 
_SetScrollPos(void * param)472 void AwtScrollPane::_SetScrollPos(void *param)
473 {
474     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
475 
476     SetScrollPosStruct *spss = (SetScrollPosStruct *)param;
477     jobject self = spss->scrollpane;
478     jint x = spss->x;
479     jint y = spss->y;
480 
481     AwtScrollPane *s = NULL;
482 
483     PDATA pData;
484     JNI_CHECK_PEER_GOTO(self, ret);
485     s = (AwtScrollPane *)pData;
486     if (::IsWindow(s->GetHWnd()))
487     {
488         DTRACE_PRINTLN3("%x: WScrollPanePeer.setScrollPosition(%d, %d)", self, x, y);
489         SCROLLINFO si;
490         ZeroMemory(&si, sizeof(si));
491         si.fMask = SIF_POS;
492         si.cbSize = sizeof(si);
493         // set x
494         si.nPos = x;
495         ::SetScrollInfo(s->GetHWnd(), SB_HORZ, &si, TRUE);
496         // set y
497         si.nPos = y;
498         ::SetScrollInfo(s->GetHWnd(), SB_VERT, &si, TRUE);
499     }
500 ret:
501    env->DeleteGlobalRef(self);
502 
503    delete spss;
504 }
505 
_SetSpans(void * param)506 void AwtScrollPane::_SetSpans(void *param)
507 {
508     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
509 
510     SetSpansStruct *sss = (SetSpansStruct *)param;
511     jobject self = sss->scrollpane;
512     jint parentWidth = sss->parentWidth;
513     jint parentHeight = sss->parentHeight;
514     jint childWidth = sss->childWidth;
515     jint childHeight = sss->childHeight;
516 
517     AwtScrollPane *s = NULL;
518 
519     PDATA pData;
520     JNI_CHECK_PEER_GOTO(self, ret);
521     s = (AwtScrollPane *)pData;
522     if (::IsWindow(s->GetHWnd()))
523     {
524         DTRACE_PRINTLN5("%x: WScrollPanePeer.setSpans(%d, %d, %d, %d)", self,
525             parentWidth, parentHeight, childWidth, childHeight);
526         s->RecalcSizes(parentWidth, parentHeight, childWidth, childHeight);
527         s->VerifyState();
528     }
529 ret:
530    env->DeleteGlobalRef(self);
531 
532    delete sss;
533 }
534 
535 #ifdef DEBUG
VerifyState()536 void AwtScrollPane::VerifyState()
537 {
538     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
539     if (env->EnsureLocalCapacity(3) < 0) {
540         return;
541     }
542 
543     if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) {
544         return;
545     }
546 
547     if (m_callbacksEnabled == FALSE) {
548         /* Component is not fully setup yet. */
549         return;
550     }
551 
552     AwtComponent::VerifyState();
553 
554     jobject target = AwtObject::GetTarget(env);
555     jobject child = JNU_CallMethodByName(env, NULL, GetPeer(env),
556                                          "getScrollSchild",
557                                          "()Ljava/awt/Component;").l;
558 
559     DASSERT(!safe_ExceptionOccurred(env));
560 
561     if (child != NULL) {
562         jobject childPeer =
563             (env)->GetObjectField(child, AwtComponent::peerID);
564         PDATA pData;
565         JNI_CHECK_PEER_RETURN(childPeer);
566         AwtComponent* awtChild = (AwtComponent *)pData;
567 
568         /* Verify child window is positioned correctly. */
569         RECT rect, childRect;
570         ::GetClientRect(GetHWnd(), &rect);
571         ::MapWindowPoints(GetHWnd(), 0, (LPPOINT)&rect, 2);
572         ::GetWindowRect(awtChild->GetHWnd(), &childRect);
573         DASSERT(childRect.left <= rect.left && childRect.top <= rect.top);
574 
575         env->DeleteLocalRef(childPeer);
576     }
577     env->DeleteLocalRef(target);
578     env->DeleteLocalRef(child);
579 }
580 #endif
581 
582 /************************************************************************
583  * ScrollPane native methods
584  */
585 
586 extern "C" {
587 
588 /*
589  * Class:     java_awt_ScrollPane
590  * Method:    initIDs
591  * Signature: ()V
592  */
593 JNIEXPORT void JNICALL
Java_java_awt_ScrollPane_initIDs(JNIEnv * env,jclass cls)594 Java_java_awt_ScrollPane_initIDs(JNIEnv *env, jclass cls)
595 {
596     TRY;
597 
598     AwtScrollPane::scrollbarDisplayPolicyID =
599         env->GetFieldID(cls, "scrollbarDisplayPolicy", "I");
600     DASSERT(AwtScrollPane::scrollbarDisplayPolicyID != NULL);
601     CHECK_NULL(AwtScrollPane::scrollbarDisplayPolicyID);
602 
603     AwtScrollPane::hAdjustableID =
604         env->GetFieldID(cls, "hAdjustable", "Ljava/awt/ScrollPaneAdjustable;");
605     DASSERT(AwtScrollPane::hAdjustableID != NULL);
606     CHECK_NULL(AwtScrollPane::hAdjustableID);
607 
608     AwtScrollPane::vAdjustableID =
609         env->GetFieldID(cls, "vAdjustable", "Ljava/awt/ScrollPaneAdjustable;");
610     DASSERT(AwtScrollPane::vAdjustableID != NULL);
611 
612     CATCH_BAD_ALLOC;
613 }
614 
615 } /* extern "C" */
616 
617 
618 /************************************************************************
619  * ScrollPaneAdjustable native methods
620  */
621 
622 extern "C" {
623 
624 /*
625  * Class:     java_awt_ScrollPaneAdjustable
626  * Method:    initIDs
627  * Signature: ()V
628  */
629 JNIEXPORT void JNICALL
Java_java_awt_ScrollPaneAdjustable_initIDs(JNIEnv * env,jclass cls)630 Java_java_awt_ScrollPaneAdjustable_initIDs(JNIEnv *env, jclass cls)
631 {
632     TRY;
633 
634     AwtScrollPane::unitIncrementID = env->GetFieldID(cls,"unitIncrement", "I");
635     DASSERT(AwtScrollPane::unitIncrementID != NULL);
636     CHECK_NULL(AwtScrollPane::unitIncrementID);
637 
638     AwtScrollPane::blockIncrementID =
639         env->GetFieldID(cls,"blockIncrement", "I");
640     DASSERT(AwtScrollPane::blockIncrementID != NULL);
641 
642     CATCH_BAD_ALLOC;
643 }
644 
645 } /* extern "C" */
646 
647 
648 /************************************************************************
649  * ScrollPanePeer native methods
650  */
651 
652 extern "C" {
653 
654 JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollPanePeer_initIDs(JNIEnv * env,jclass cls)655 Java_sun_awt_windows_WScrollPanePeer_initIDs(JNIEnv *env, jclass cls)
656 {
657     TRY;
658 
659     AwtScrollPane::postScrollEventID =
660         env->GetMethodID(cls, "postScrollEvent", "(IIIZ)V");
661     DASSERT(AwtScrollPane::postScrollEventID != NULL);
662 
663     CATCH_BAD_ALLOC;
664 }
665 
666 /*
667  * Class:     sun_awt_windows_WScrollPanePeer
668  * Method:    create
669  * Signature: (Lsun/awt/windows/WComponentPeer;)V
670  */
671 JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollPanePeer_create(JNIEnv * env,jobject self,jobject parent)672 Java_sun_awt_windows_WScrollPanePeer_create(JNIEnv *env, jobject self,
673                                             jobject parent)
674 {
675     TRY;
676 
677     DTRACE_PRINTLN2("%x: WScrollPanePeer.create(%x)", self, parent);
678 
679     AwtToolkit::CreateComponent(self, parent,
680                                 (AwtToolkit::ComponentFactory)
681                                 AwtScrollPane::Create);
682     PDATA pData;
683     JNI_CHECK_PEER_CREATION_RETURN(self);
684     ((AwtScrollPane*)pData)->VerifyState();
685 
686     CATCH_BAD_ALLOC;
687 }
688 
689 /*
690  * Class:     sun_awt_windows_WScrollPanePeer
691  * Method:    getOffset
692  * Signature: (I)I
693  */
694 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WScrollPanePeer_getOffset(JNIEnv * env,jobject self,jint orient)695 Java_sun_awt_windows_WScrollPanePeer_getOffset(JNIEnv *env, jobject self,
696                                                jint orient)
697 {
698     TRY;
699 
700     GetOffsetStruct *gos = new GetOffsetStruct;
701     gos->scrollpane = env->NewGlobalRef(self);
702     gos->orient = orient;
703 
704     return static_cast<jint>(reinterpret_cast<INT_PTR>(AwtToolkit::GetInstance().SyncCall(
705         (void *(*)(void *))AwtScrollPane::_GetOffset, gos)));
706     // global ref and gos are deleted in _GetOffset()
707 
708     CATCH_BAD_ALLOC_RET(0);
709 }
710 
711 /*
712  * Class:     sun_awt_windows_WScrollPanePeer
713  * Method:    setInsets
714  * Signature: ()V
715  */
716 JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollPanePeer_setInsets(JNIEnv * env,jobject self)717 Java_sun_awt_windows_WScrollPanePeer_setInsets(JNIEnv *env, jobject self)
718 {
719     TRY
720 
721     AwtToolkit::GetInstance().SyncCall(AwtScrollPane::_SetInsets,
722         env->NewGlobalRef(self));
723     // global ref is deleted in _SetInsets()
724 
725     CATCH_BAD_ALLOC;
726 }
727 
728 /*
729  * Class:     sun_awt_windows_WScrollPanePeer
730  * Method:    setScrollPosition
731  * Signature: (II)V
732  */
733 JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollPanePeer_setScrollPosition(JNIEnv * env,jobject self,jint x,jint y)734 Java_sun_awt_windows_WScrollPanePeer_setScrollPosition(JNIEnv *env,
735                                                        jobject self,
736                                                        jint x, jint y)
737 {
738     TRY;
739 
740     SetScrollPosStruct *ssps = new SetScrollPosStruct;
741     ssps->scrollpane = env->NewGlobalRef(self);
742     ssps->x = x;
743     ssps->y = y;
744 
745     AwtToolkit::GetInstance().SyncCall(AwtScrollPane::_SetScrollPos, ssps);
746     // global ref and ssps are deleted in _SetScrollPos()
747 
748     CATCH_BAD_ALLOC;
749 }
750 
751 /*
752  * Class:     sun_awt_windows_WScrollPanePeer
753  * Method:    _getHScrollbarHeight
754  * Signature: ()I
755  */
756 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WScrollPanePeer__1getHScrollbarHeight(JNIEnv * env,jobject self)757 Java_sun_awt_windows_WScrollPanePeer__1getHScrollbarHeight(JNIEnv *env,
758                                                            jobject self)
759 {
760     TRY;
761 
762     DTRACE_PRINTLN1("%x: WScrollPanePeer._getHScrollbarHeight()", self);
763     return ::GetSystemMetrics(SM_CYHSCROLL);
764 
765     CATCH_BAD_ALLOC_RET(0);
766 }
767 
768 /*
769  * Class:     sun_awt_windows_WScrollPanePeer
770  * Method:    _getVScrollbarWidth
771  * Signature: ()I
772  */
773 JNIEXPORT jint JNICALL
Java_sun_awt_windows_WScrollPanePeer__1getVScrollbarWidth(JNIEnv * env,jobject self)774 Java_sun_awt_windows_WScrollPanePeer__1getVScrollbarWidth(JNIEnv *env,
775                                                           jobject self)
776 {
777     TRY;
778 
779     DTRACE_PRINTLN1("%x: WScrollPanePeer._getVScrollbarHeight()", self);
780     return ::GetSystemMetrics(SM_CXVSCROLL);
781 
782     CATCH_BAD_ALLOC_RET(0);
783 }
784 
785 /*
786  * Class:     sun_awt_windows_WScrollPanePeer
787  * Method:    setSpans
788  * Signature: (IIII)V
789  */
790 JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollPanePeer_setSpans(JNIEnv * env,jobject self,jint parentWidth,jint parentHeight,jint childWidth,jint childHeight)791 Java_sun_awt_windows_WScrollPanePeer_setSpans(JNIEnv *env, jobject self,
792                                               jint parentWidth,
793                                               jint parentHeight,
794                                               jint childWidth,
795                                               jint childHeight)
796 {
797     TRY;
798 
799     SetSpansStruct *sss = new SetSpansStruct;
800     sss->scrollpane = env->NewGlobalRef(self);
801     sss->parentWidth = parentWidth;
802     sss->parentHeight = parentHeight;
803     sss->childWidth = childWidth;
804     sss->childHeight = childHeight;
805 
806     AwtToolkit::GetInstance().SyncCall(AwtScrollPane::_SetSpans, sss);
807     // global ref and sss are deleted in _SetSpans
808 
809     CATCH_BAD_ALLOC;
810 }
811 
812 } /* extern "C" */
813