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