18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2007-2009 Torch Mobile Inc.
4db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
24db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block#include "PopupMenuWin.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "BitmapInfo.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FloatRect.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontSelector.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
34d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "HostWindow.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PlatformMouseEvent.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PlatformScreen.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTheme.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderView.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Scrollbar.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ScrollbarTheme.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SimpleFontData.h"
43ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "TextRun.h"
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "WebCoreInstanceHandle.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <windows.h>
46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <windowsx.h>
47d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE)
480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <ResDefCE.h>
490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#define MAKEPOINTS(l) (*((POINTS FAR *)&(l)))
500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing std::min;
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Default Window animation duration in milliseconds
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const int defaultAnimationDuration = 200;
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Maximum height of a popup window
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const int maxPopupHeight = 320;
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int optionSpacingMiddle = 1;
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int popupWindowBorderWidth = 1;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
662fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic LPCWSTR kPopupWindowClassName = L"PopupWindowClass";
67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// This is used from within our custom message pump when we want to send a
69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// message to the web view and not have our message stolen and sent to
70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// the popup window.
71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic const UINT WM_HOST_WINDOW_FIRST = WM_USER;
72231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic const UINT WM_HOST_WINDOW_CHAR = WM_USER + WM_CHAR;
73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic const UINT WM_HOST_WINDOW_MOUSEMOVE = WM_USER + WM_MOUSEMOVE;
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: Remove this as soon as practical.
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline bool isASCIIPrintable(unsigned c)
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return c >= 0x20 && c <= 0x7E;
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
81231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void translatePoint(LPARAM& lParam, HWND from, HWND to)
82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
83231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    POINT pt;
84231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    pt.x = (short)GET_X_LPARAM(lParam);
85231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    pt.y = (short)GET_Y_LPARAM(lParam);
86231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ::MapWindowPoints(from, to, &pt, 1);
87231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    lParam = MAKELPARAM(pt.x, pt.y);
88231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
90db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve BlockPopupMenuWin::PopupMenuWin(PopupMenuClient* client)
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_popupClient(client)
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_scrollbar(0)
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_popup(0)
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_DC(0)
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_bmp(0)
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_wasClicked(false)
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_itemHeight(0)
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_scrollOffset(0)
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_wheelDelta(0)
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_focusedIndex(0)
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_scrollbarCapturingMouse(false)
102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_showPopup(false)
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
106db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve BlockPopupMenuWin::~PopupMenuWin()
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_bmp)
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ::DeleteObject(m_bmp);
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_DC)
1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ::DeleteDC(m_DC);
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_popup)
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ::DestroyWindow(m_popup);
114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_scrollbar)
115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_scrollbar->setParent(0);
116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
118db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::disconnectClient()
119db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{
120db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    m_popupClient = 0;
121db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block}
122db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
1232fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockLPCWSTR PopupMenuWin::popupClassName()
124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return kPopupWindowClassName;
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
128db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::show(const IntRect& r, FrameView* view, int index)
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
130231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    calculatePositionAndSize(r, view);
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (clientRect().isEmpty())
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    HWND hostWindow = view->hostWindow()->platformPageClient();
135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_scrollbar && visibleItems() < client()->listSize()) {
137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // We need a scroll bar
138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_scrollbar = client()->createScrollbar(this, VerticalScrollbar, SmallScrollbar);
139231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_scrollbar->styleChanged();
140231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
141231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_popup) {
143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        registerClass();
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        DWORD exStyle = WS_EX_LTRREADING;
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_popup = ::CreateWindowExW(exStyle, kPopupWindowClassName, L"PopupMenu",
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            WS_POPUP | WS_BORDER,
149231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(),
150dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            hostWindow, 0, WebCore::instanceHandle(), this);
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!m_popup)
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } else {
155231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // We need to reposition the popup window.
156231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ::MoveWindow(m_popup, m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height(), false);
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Determine whether we should animate our popups
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Note: Must use 'BOOL' and 'FALSE' instead of 'bool' and 'false' to avoid stack corruption with SystemParametersInfo
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    BOOL shouldAnimate = FALSE;
162d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !OS(WINCE)
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ::SystemParametersInfo(SPI_GETCOMBOBOXANIMATION, 0, &shouldAnimate, 0);
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (shouldAnimate) {
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RECT viewRect = {0};
167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ::GetWindowRect(hostWindow, &viewRect);
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!::IsRectEmpty(&viewRect)) {
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Popups should slide into view away from the <select> box
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // NOTE: This may have to change for Vista
172231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            DWORD slideDirection = (m_windowRect.y() < viewRect.top + view->contentsToWindow(r.location()).y()) ? AW_VER_NEGATIVE : AW_VER_POSITIVE;
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
174231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ::AnimateWindow(m_popup, defaultAnimationDuration, AW_SLIDE | slideDirection);
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
178231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ::ShowWindow(m_popup, SW_SHOWNOACTIVATE);
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (client()) {
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int index = client()->selectedIndex();
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (index >= 0)
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setFocusedIndex(index);
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
186231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_showPopup = true;
187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Protect the popup menu in case its owner is destroyed while we're running the message pump.
189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<PopupMenu> protect(this);
190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ::SetCapture(hostWindow);
192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    MSG msg;
194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    HWND activeWindow;
195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    while (::GetMessage(&msg, 0, 0, 0)) {
197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        switch (msg.message) {
198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_HOST_WINDOW_MOUSEMOVE:
199231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_HOST_WINDOW_CHAR:
200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (msg.hwnd == m_popup) {
201231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    // This message should be sent to the host window.
202231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    msg.hwnd = hostWindow;
203231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    msg.message -= WM_HOST_WINDOW_FIRST;
204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                }
205231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                break;
206231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
207231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Steal mouse messages.
2080617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#if !OS(WINCE)
209231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_NCMOUSEMOVE:
210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_NCLBUTTONDOWN:
211231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_NCLBUTTONUP:
212231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_NCLBUTTONDBLCLK:
213231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_NCRBUTTONDOWN:
214231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_NCRBUTTONUP:
215231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_NCRBUTTONDBLCLK:
216231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_NCMBUTTONDOWN:
217231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_NCMBUTTONUP:
218231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_NCMBUTTONDBLCLK:
2190617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#endif
220231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_MOUSEWHEEL:
221231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                msg.hwnd = m_popup;
222231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                break;
223231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
224231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // These mouse messages use client coordinates so we need to convert them.
225231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_MOUSEMOVE:
226231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_LBUTTONDOWN:
227231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_LBUTTONUP:
228231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_LBUTTONDBLCLK:
229231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_RBUTTONDOWN:
230231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_RBUTTONUP:
231231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_RBUTTONDBLCLK:
232231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_MBUTTONDOWN:
233231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_MBUTTONUP:
234231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_MBUTTONDBLCLK: {
235231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // Translate the coordinate.
236231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                translatePoint(msg.lParam, msg.hwnd, m_popup);
237231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
238231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                msg.hwnd = m_popup;
239231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                break;
240231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
241231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
242231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Steal all keyboard messages.
243231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_KEYDOWN:
244231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_KEYUP:
245231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_CHAR:
246231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_DEADCHAR:
247231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_SYSKEYUP:
248231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_SYSCHAR:
249231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case WM_SYSDEADCHAR:
250231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                msg.hwnd = m_popup;
251231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                break;
252231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
253231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
254231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ::TranslateMessage(&msg);
255231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ::DispatchMessage(&msg);
256231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
257231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (!m_popupClient)
258231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            break;
259231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
260231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (!m_showPopup)
261231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            break;
262231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        activeWindow = ::GetActiveWindow();
263231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (activeWindow != hostWindow && !::IsChild(activeWindow, hostWindow))
264231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            break;
265231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (::GetCapture() != hostWindow)
266231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            break;
267231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
268231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
269231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (::GetCapture() == hostWindow)
270231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ::ReleaseCapture();
271231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
272231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // We're done, hide the popup if necessary.
273231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    hide();
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
276db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::hide()
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
278231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!m_showPopup)
279231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
280231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
281231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_showPopup = false;
282231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ::ShowWindow(m_popup, SW_HIDE);
284231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
285231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (client())
286231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        client()->popupDidHide();
287231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
288231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Post a WM_NULL message to wake up the message pump if necessary.
289231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    ::PostMessage(m_popup, WM_NULL, 0, 0);
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
292db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::calculatePositionAndSize(const IntRect& r, FrameView* v)
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // r is in absolute document coordinates, but we want to be in screen coordinates
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // First, move to WebView coordinates
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect rScreenCoords(v->contentsToWindow(r.location()), r.size());
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Then, translate to screen coordinates
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    POINT location(rScreenCoords.location());
301231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (!::ClientToScreen(v->hostWindow()->platformPageClient(), &location))
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    rScreenCoords.setLocation(location);
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // First, determine the popup's height
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int itemCount = client()->listSize();
3082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_itemHeight = client()->menuStyle().font().fontMetrics().height() + optionSpacingMiddle;
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int naturalHeight = m_itemHeight * itemCount;
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int popupHeight = min(maxPopupHeight, naturalHeight);
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The popup should show an integral number of items (i.e. no partial items should be visible)
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popupHeight -= popupHeight % m_itemHeight;
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Next determine its width
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int popupWidth = 0;
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; i < itemCount; ++i) {
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String text = client()->itemText(i);
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (text.isEmpty())
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Font itemFont = client()->menuStyle().font();
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (client()->itemIsLabel(i)) {
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            FontDescription d = itemFont.fontDescription();
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            d.setWeight(d.bolderWeight());
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing());
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            itemFont.update(m_popupClient->fontSelector());
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        popupWidth = max(popupWidth, static_cast<int>(ceilf(itemFont.width(TextRun(text.characters(), text.length())))));
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (naturalHeight > maxPopupHeight)
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We need room for a scrollbar
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        popupWidth += ScrollbarTheme::nativeTheme()->scrollbarThickness(SmallScrollbar);
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add padding to align the popup text with the <select> text
337d0825bca7fe65beaee391d30da42e937db621564Steve Block    popupWidth += max(0, client()->clientPaddingRight() - client()->clientInsetRight()) + max(0, client()->clientPaddingLeft() - client()->clientInsetLeft());
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Leave room for the border
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popupWidth += 2 * popupWindowBorderWidth;
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popupHeight += 2 * popupWindowBorderWidth;
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The popup should be at least as wide as the control on the page
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popupWidth = max(rScreenCoords.width() - client()->clientInsetLeft() - client()->clientInsetRight(), popupWidth);
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Always left-align items in the popup.  This matches popup menus on the mac.
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int popupX = rScreenCoords.x() + client()->clientInsetLeft();
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntRect popupRect(popupX, rScreenCoords.maxY(), popupWidth, popupHeight);
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The popup needs to stay within the bounds of the screen and not overlap any toolbars
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FloatRect screen = screenAvailableRect(v);
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check that we don't go off the screen vertically
3552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (popupRect.maxY() > screen.height()) {
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The popup will go off the screen, so try placing it above the client
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (rScreenCoords.y() - popupRect.height() < 0) {
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The popup won't fit above, either, so place it whereever's bigger and resize it to fit
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if ((rScreenCoords.y() + rScreenCoords.height() / 2) < (screen.height() / 2)) {
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Below is bigger
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popupRect.setHeight(screen.height() - popupRect.y());
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Above is bigger
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popupRect.setY(0);
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popupRect.setHeight(rScreenCoords.y());
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The popup fits above, so reposition it
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            popupRect.setY(rScreenCoords.y() - popupRect.height());
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check that we don't go off the screen horizontally
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (popupRect.x() < screen.x()) {
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        popupRect.setWidth(popupRect.width() - (screen.x() - popupRect.x()));
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        popupRect.setX(screen.x());
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_windowRect = popupRect;
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return;
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
382db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockbool PopupMenuWin::setFocusedIndex(int i, bool hotTracking)
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (i < 0 || i >= client()->listSize() || i == focusedIndex())
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!client()->itemIsEnabled(i))
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    invalidateItem(focusedIndex());
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    invalidateItem(i);
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_focusedIndex = i;
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!hotTracking)
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        client()->setTextFromItem(i);
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!scrollToRevealSelection())
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ::UpdateWindow(m_popup);
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
404db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockint PopupMenuWin::visibleItems() const
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return clientRect().height() / m_itemHeight;
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
409db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockint PopupMenuWin::listIndexAtPoint(const IntPoint& point) const
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_scrollOffset + point.y() / m_itemHeight;
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
414db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockint PopupMenuWin::focusedIndex() const
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_focusedIndex;
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
419db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::focusFirst()
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!client())
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int size = client()->listSize();
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; i < size; ++i)
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (client()->itemIsEnabled(i)) {
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setFocusedIndex(i);
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
433db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::focusLast()
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!client())
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int size = client()->listSize();
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = size - 1; i > 0; --i)
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (client()->itemIsEnabled(i)) {
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setFocusedIndex(i);
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
447db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockbool PopupMenuWin::down(unsigned lines)
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!client())
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int size = client()->listSize();
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int lastSelectableIndex, selectedListIndex;
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    lastSelectableIndex = selectedListIndex = focusedIndex();
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = selectedListIndex + 1; i >= 0 && i < size; ++i)
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (client()->itemIsEnabled(i)) {
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastSelectableIndex = i;
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (i >= selectedListIndex + (int)lines)
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return setFocusedIndex(lastSelectableIndex);
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
466db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockbool PopupMenuWin::up(unsigned lines)
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!client())
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int size = client()->listSize();
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int lastSelectableIndex, selectedListIndex;
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    lastSelectableIndex = selectedListIndex = focusedIndex();
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = selectedListIndex - 1; i >= 0 && i < size; --i)
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (client()->itemIsEnabled(i)) {
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastSelectableIndex = i;
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (i <= selectedListIndex - (int)lines)
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return setFocusedIndex(lastSelectableIndex);
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
485db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::invalidateItem(int index)
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_popup)
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect damageRect(clientRect());
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    damageRect.setY(m_itemHeight * (index - m_scrollOffset));
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    damageRect.setHeight(m_itemHeight);
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_scrollbar)
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        damageRect.setWidth(damageRect.width() - m_scrollbar->frameRect().width());
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RECT r = damageRect;
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ::InvalidateRect(m_popup, &r, TRUE);
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
500db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve BlockIntRect PopupMenuWin::clientRect() const
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect clientRect = m_windowRect;
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    clientRect.inflate(-popupWindowBorderWidth);
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    clientRect.setLocation(IntPoint(0, 0));
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return clientRect;
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::incrementWheelDelta(int delta)
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_wheelDelta += delta;
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
513db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::reduceWheelDelta(int delta)
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(delta >= 0);
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(delta <= abs(m_wheelDelta));
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_wheelDelta > 0)
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_wheelDelta -= delta;
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (m_wheelDelta < 0)
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_wheelDelta += delta;
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
526db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockbool PopupMenuWin::scrollToRevealSelection()
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_scrollbar)
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int index = focusedIndex();
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (index < m_scrollOffset) {
534ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        ScrollableArea::scrollToYOffsetWithoutAnimation(index);
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (index >= m_scrollOffset + visibleItems()) {
539ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        ScrollableArea::scrollToYOffsetWithoutAnimation(index - visibleItems() + 1);
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
546db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::updateFromElement()
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_popup)
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_focusedIndex = client()->selectedIndex();
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ::InvalidateRect(m_popup, 0, TRUE);
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!scrollToRevealSelection())
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ::UpdateWindow(m_popup);
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int separatorPadding = 4;
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int separatorHeight = 1;
560db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::paint(const IntRect& damageRect, HDC hdc)
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_popup)
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_DC) {
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_DC = ::CreateCompatibleDC(::GetDC(m_popup));
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!m_DC)
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_bmp) {
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool keepBitmap = false;
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        BITMAP bitmap;
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (GetObject(m_bmp, sizeof(bitmap), &bitmap))
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            keepBitmap = bitmap.bmWidth == clientRect().width()
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                && bitmap.bmHeight == clientRect().height();
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!keepBitmap) {
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            DeleteObject(m_bmp);
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_bmp = 0;
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_bmp) {
583d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE)
584e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(clientRect().size(), BitmapInfo::BitCount16);
5850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else
5860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(clientRect().size());
5870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        void* pixels = 0;
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_bmp = ::CreateDIBSection(m_DC, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0);
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!m_bmp)
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ::SelectObject(m_DC, m_bmp);
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GraphicsContext context(m_DC);
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int itemCount = client()->listSize();
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // listRect is the damageRect translated into the coordinates of the entire menu list (which is itemCount * m_itemHeight pixels tall)
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect listRect = damageRect;
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    listRect.move(IntSize(0, m_scrollOffset * m_itemHeight));
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    for (int y = listRect.y(); y < listRect.maxY(); y += m_itemHeight) {
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int index = y / m_itemHeight;
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Color optionBackgroundColor, optionTextColor;
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PopupMenuStyle itemStyle = client()->itemStyle(index);
6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (index == focusedIndex()) {
6100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            optionBackgroundColor = RenderTheme::defaultTheme()->activeListBoxSelectionBackgroundColor();
6110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            optionTextColor = RenderTheme::defaultTheme()->activeListBoxSelectionForegroundColor();
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            optionBackgroundColor = itemStyle.backgroundColor();
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            optionTextColor = itemStyle.foregroundColor();
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // itemRect is in client coordinates
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntRect itemRect(0, (index - m_scrollOffset) * m_itemHeight, damageRect.width(), m_itemHeight);
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Draw the background for this menu item
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (itemStyle.isVisible())
622a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            context.fillRect(itemRect, optionBackgroundColor, ColorSpaceDeviceRGB);
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (client()->itemIsSeparator(index)) {
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            IntRect separatorRect(itemRect.x() + separatorPadding, itemRect.y() + (itemRect.height() - separatorHeight) / 2, itemRect.width() - 2 * separatorPadding, separatorHeight);
626a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            context.fillRect(separatorRect, optionTextColor, ColorSpaceDeviceRGB);
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String itemText = client()->itemText(index);
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unsigned length = itemText.length();
6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const UChar* string = itemText.characters();
6342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft);
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
636a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        context.setFillColor(optionTextColor, ColorSpaceDeviceRGB);
6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Font itemFont = client()->menuStyle().font();
6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (client()->itemIsLabel(index)) {
6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            FontDescription d = itemFont.fontDescription();
6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            d.setWeight(d.bolderWeight());
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing());
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            itemFont.update(m_popupClient->fontSelector());
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Draw the item text
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (itemStyle.isVisible()) {
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int textX = max(0, client()->clientPaddingLeft() - client()->clientInsetLeft());
6490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (RenderTheme::defaultTheme()->popupOptionSupportsTextIndent() && itemStyle.textDirection() == LTR)
6508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                textX += itemStyle.textIndent().calcMinValue(itemRect.width());
6512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            int textY = itemRect.y() + itemFont.fontMetrics().ascent() + (itemRect.height() - itemFont.fontMetrics().height()) / 2;
652635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            context.drawBidiText(itemFont, textRun, IntPoint(textX, textY));
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_scrollbar)
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_scrollbar->paint(&context, damageRect);
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    HDC localDC = hdc ? hdc : ::GetDC(m_popup);
6600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ::BitBlt(localDC, damageRect.x(), damageRect.y(), damageRect.width(), damageRect.height(), m_DC, damageRect.x(), damageRect.y(), SRCCOPY);
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!hdc)
6640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ::ReleaseDC(m_popup, localDC);
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6675abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickint PopupMenuWin::scrollSize(ScrollbarOrientation orientation) const
6685abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
6695abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    return ((orientation == VerticalScrollbar) && m_scrollbar) ? (m_scrollbar->totalSize() - m_scrollbar->visibleSize()) : 0;
6705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
6715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
672ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochint PopupMenuWin::scrollPosition(Scrollbar*) const
6735abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
674ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    return m_scrollOffset;
675ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
676ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
677ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid PopupMenuWin::setScrollOffset(const IntPoint& offset)
678ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
679ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    scrollTo(offset.y());
6805abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
6815abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
682ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid PopupMenuWin::scrollTo(int offset)
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_scrollbar);
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_popup)
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_scrollOffset == offset)
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int scrolledLines = m_scrollOffset - offset;
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_scrollOffset = offset;
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UINT flags = SW_INVALIDATE;
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef CAN_SET_SMOOTH_SCROLLING_DURATION
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    BOOL shouldSmoothScroll = FALSE;
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ::SystemParametersInfo(SPI_GETLISTBOXSMOOTHSCROLLING, 0, &shouldSmoothScroll, 0);
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (shouldSmoothScroll)
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        flags |= MAKEWORD(SW_SMOOTHSCROLL, smoothScrollAnimationDuration);
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect listRect = clientRect();
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_scrollbar)
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        listRect.setWidth(listRect.width() - m_scrollbar->frameRect().width());
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RECT r = listRect;
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ::ScrollWindowEx(m_popup, 0, scrolledLines * m_itemHeight, &r, 0, 0, 0, flags);
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_scrollbar) {
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        r = m_scrollbar->frameRect();
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ::InvalidateRect(m_popup, &r, TRUE);
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ::UpdateWindow(m_popup);
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
716db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntRect scrollRect = rect;
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    scrollRect.move(scrollbar->x(), scrollbar->y());
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RECT r = scrollRect;
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ::InvalidateRect(m_popup, &r, false);
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
724db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid PopupMenuWin::registerClass()
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static bool haveRegisteredWindowClass = false;
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (haveRegisteredWindowClass)
729231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
731d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE)
7320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    WNDCLASS wcex;
7330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    WNDCLASSEX wcex;
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wcex.cbSize = sizeof(WNDCLASSEX);
7360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    wcex.hIconSm        = 0;
7375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    wcex.style          = CS_DROPSHADOW;
7380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
7390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
740231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    wcex.lpfnWndProc    = PopupMenuWndProc;
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wcex.cbClsExtra     = 0;
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wcex.cbWndExtra     = sizeof(PopupMenu*); // For the PopupMenu pointer
743dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    wcex.hInstance      = WebCore::instanceHandle();
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wcex.hIcon          = 0;
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wcex.hCursor        = LoadCursor(0, IDC_ARROW);
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wcex.hbrBackground  = 0;
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wcex.lpszMenuName   = 0;
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    wcex.lpszClassName  = kPopupWindowClassName;
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    haveRegisteredWindowClass = true;
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
752d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE)
753231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RegisterClass(&wcex);
7540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else
755231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RegisterClassEx(&wcex);
7560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
759231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
760db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve BlockLRESULT CALLBACK PopupMenuWin::PopupMenuWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
762d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE)
7630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    LONG longPtr = GetWindowLong(hWnd, 0);
7640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else
7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LONG_PTR longPtr = GetWindowLongPtr(hWnd, 0);
7660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
767231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
768db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    if (PopupMenuWin* popup = reinterpret_cast<PopupMenuWin*>(longPtr))
769231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return popup->wndProc(hWnd, message, wParam, lParam);
770231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
771231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (message == WM_CREATE) {
772231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
773231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
774231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Associate the PopupMenu with the window.
775d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE)
776231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ::SetWindowLong(hWnd, 0, (LONG)createStruct->lpCreateParams);
777231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#else
778231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ::SetWindowLongPtr(hWnd, 0, (LONG_PTR)createStruct->lpCreateParams);
779231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif
780231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return 0;
781231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
782231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
783231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return ::DefWindowProc(hWnd, message, wParam, lParam);
784231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
785231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
786231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockconst int smoothScrollAnimationDuration = 5000;
787231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
788db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve BlockLRESULT PopupMenuWin::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
789231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
790231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    LRESULT lResult = 0;
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (message) {
7930617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#if !OS(WINCE)
794231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case WM_MOUSEACTIVATE:
795231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return MA_NOACTIVATE;
7960617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#endif
797231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case WM_SIZE: {
798231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!scrollbar())
799231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                break;
800231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
801231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            IntSize size(LOWORD(lParam), HIWORD(lParam));
802231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            scrollbar()->setFrameRect(IntRect(size.width() - scrollbar()->width(), 0, scrollbar()->width(), size.height()));
803231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
804231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            int visibleItems = this->visibleItems();
805231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            scrollbar()->setEnabled(visibleItems < client()->listSize());
806231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            scrollbar()->setSteps(1, max(1, visibleItems - 1));
807231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            scrollbar()->setProportion(visibleItems, client()->listSize());
808231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
810231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case WM_KEYDOWN:
812231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!client())
813231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                break;
814231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
815231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            lResult = 0;
816231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            switch (LOWORD(wParam)) {
817231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case VK_DOWN:
818231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case VK_RIGHT:
819231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    down();
820231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
821231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case VK_UP:
822231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case VK_LEFT:
823231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    up();
824231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
825231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case VK_HOME:
826231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    focusFirst();
827231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
828231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case VK_END:
829231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    focusLast();
830231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
831231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case VK_PRIOR:
832231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    if (focusedIndex() != scrollOffset()) {
833231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        // Set the selection to the first visible item
834231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        int firstVisibleItem = scrollOffset();
835231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        up(focusedIndex() - firstVisibleItem);
836231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    } else {
837231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        // The first visible item is selected, so move the selection back one page
838231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        up(visibleItems());
839231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    }
840231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
841231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case VK_NEXT: {
842231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    int lastVisibleItem = scrollOffset() + visibleItems() - 1;
843231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    if (focusedIndex() != lastVisibleItem) {
844231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        // Set the selection to the last visible item
845231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        down(lastVisibleItem - focusedIndex());
846231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    } else {
847231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        // The last visible item is selected, so move the selection forward one page
848231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        down(visibleItems());
849231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    }
850231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
852231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case VK_TAB:
853231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    ::SendMessage(client()->hostWindow()->platformPageClient(), message, wParam, lParam);
854231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    hide();
855231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
856231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case VK_ESCAPE:
857231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    hide();
858231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
859231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                default:
860231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    if (isASCIIPrintable(wParam))
861231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        // Send the keydown to the WebView so it can be used for type-to-select.
862231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        // Since we know that the virtual key is ASCII printable, it's OK to convert this to
863231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        // a WM_CHAR message. (We don't want to call TranslateMessage because that will post a
864231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        // WM_CHAR message that will be stolen and redirected to the popup HWND.
865231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        ::PostMessage(m_popup, WM_HOST_WINDOW_CHAR, wParam, lParam);
866231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    else
867231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        lResult = 1;
868231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
871231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case WM_CHAR: {
872231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!client())
873231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                break;
874231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
875231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            lResult = 0;
876231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            int index;
877231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            switch (wParam) {
878231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case 0x0D:   // Enter/Return
879231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    hide();
880231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    index = focusedIndex();
881231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    ASSERT(index >= 0);
882231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    client()->valueChanged(index);
883231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
884231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case 0x1B:   // Escape
885231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    hide();
886231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
887231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case 0x09:   // TAB
888231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case 0x08:   // Backspace
889231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                case 0x0A:   // Linefeed
890231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                default:     // Character
891231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    lResult = 1;
892231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
895231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
896231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case WM_MOUSEMOVE: {
897231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            IntPoint mousePoint(MAKEPOINTS(lParam));
898231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (scrollbar()) {
899231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                IntRect scrollBarRect = scrollbar()->frameRect();
900231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) {
901231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    // Put the point into coordinates relative to the scroll bar
902231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
903231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
904231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    scrollbar()->mouseMoved(event);
905231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
907231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
909231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            BOOL shouldHotTrack = FALSE;
910d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !OS(WINCE)
911231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ::SystemParametersInfo(SPI_GETHOTTRACKING, 0, &shouldHotTrack, 0);
9120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
914231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            RECT bounds;
915231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            GetClientRect(popupHandle(), &bounds);
916231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!::PtInRect(&bounds, mousePoint) && !(wParam & MK_LBUTTON) && client()) {
917231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // When the mouse is not inside the popup menu and the left button isn't down, just
918231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // repost the message to the web view.
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
920231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // Translate the coordinate.
921231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                translatePoint(lParam, m_popup, client()->hostWindow()->platformPageClient());
922231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
923231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ::PostMessage(m_popup, WM_HOST_WINDOW_MOUSEMOVE, wParam, lParam);
924231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                break;
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
926231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
927231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if ((shouldHotTrack || wParam & MK_LBUTTON) && ::PtInRect(&bounds, mousePoint))
928231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                setFocusedIndex(listIndexAtPoint(mousePoint), true);
929231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
931231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
932231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case WM_LBUTTONDOWN: {
933231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            IntPoint mousePoint(MAKEPOINTS(lParam));
934231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (scrollbar()) {
935231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                IntRect scrollBarRect = scrollbar()->frameRect();
936231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (scrollBarRect.contains(mousePoint)) {
937231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    // Put the point into coordinates relative to the scroll bar
938231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
939231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
940231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    scrollbar()->mouseDown(event);
941231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    setScrollbarCapturingMouse(true);
942231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
945231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
946231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // If the mouse is inside the window, update the focused index. Otherwise,
947231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // hide the popup.
948231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            RECT bounds;
949231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            GetClientRect(m_popup, &bounds);
950231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (::PtInRect(&bounds, mousePoint))
951231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                setFocusedIndex(listIndexAtPoint(mousePoint), true);
952231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            else
953231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                hide();
9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
955231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
956231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case WM_LBUTTONUP: {
957231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            IntPoint mousePoint(MAKEPOINTS(lParam));
958231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (scrollbar()) {
959231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                IntRect scrollBarRect = scrollbar()->frameRect();
960231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (scrollbarCapturingMouse() || scrollBarRect.contains(mousePoint)) {
961231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    setScrollbarCapturingMouse(false);
962231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    // Put the point into coordinates relative to the scroll bar
963231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    mousePoint.move(-scrollBarRect.x(), -scrollBarRect.y());
964231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    PlatformMouseEvent event(hWnd, message, wParam, MAKELPARAM(mousePoint.x(), mousePoint.y()));
965231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    scrollbar()->mouseUp();
966231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    // FIXME: This is a hack to work around Scrollbar not invalidating correctly when it doesn't have a parent widget
967231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    RECT r = scrollBarRect;
968231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    ::InvalidateRect(popupHandle(), &r, TRUE);
969231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    break;
9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
972231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Only hide the popup if the mouse is inside the popup window.
973231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            RECT bounds;
974231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            GetClientRect(popupHandle(), &bounds);
975231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (client() && ::PtInRect(&bounds, mousePoint)) {
976231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                hide();
977231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                int index = focusedIndex();
978231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (index >= 0)
979231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    client()->valueChanged(index);
980231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
982231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
983231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
984231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case WM_MOUSEWHEEL: {
985231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!scrollbar())
986231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                break;
9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
988231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            int i = 0;
989231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            for (incrementWheelDelta(GET_WHEEL_DELTA_WPARAM(wParam)); abs(wheelDelta()) >= WHEEL_DELTA; reduceWheelDelta(WHEEL_DELTA)) {
990231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (wheelDelta() > 0)
991231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    ++i;
992231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                else
993231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    --i;
9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
995ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
996ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch            ScrollableArea::scroll(i > 0 ? ScrollUp : ScrollDown, ScrollByLine, abs(i));
9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
998231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
999231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1000231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case WM_PAINT: {
1001231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            PAINTSTRUCT paintInfo;
1002231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ::BeginPaint(popupHandle(), &paintInfo);
1003231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            paint(paintInfo.rcPaint, paintInfo.hdc);
1004231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ::EndPaint(popupHandle(), &paintInfo);
1005231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            lResult = 0;
10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
1007231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
1008d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !OS(WINCE)
10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case WM_PRINTCLIENT:
1010231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            paint(clientRect(), (HDC)wParam);
10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
10120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        default:
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lResult = DefWindowProc(hWnd, message, wParam, lParam);
10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return lResult;
10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1021