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