• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "config.h"
32 #include "WebPopupMenuImpl.h"
33 
34 #include "Cursor.h"
35 #include "FramelessScrollView.h"
36 #include "FrameView.h"
37 #include "IntRect.h"
38 #include "PlatformContextSkia.h"
39 #include "PlatformKeyboardEvent.h"
40 #include "PlatformMouseEvent.h"
41 #include "PlatformWheelEvent.h"
42 #include "SkiaUtils.h"
43 
44 #include "WebInputEvent.h"
45 #include "WebInputEventConversion.h"
46 #include "WebRect.h"
47 #include "WebWidgetClient.h"
48 
49 #include <skia/ext/platform_canvas.h>
50 
51 using namespace WebCore;
52 
53 namespace WebKit {
54 
55 // WebPopupMenu ---------------------------------------------------------------
56 
create(WebWidgetClient * client)57 WebPopupMenu* WebPopupMenu::create(WebWidgetClient* client)
58 {
59     return new WebPopupMenuImpl(client);
60 }
61 
62 // WebWidget ------------------------------------------------------------------
63 
WebPopupMenuImpl(WebWidgetClient * client)64 WebPopupMenuImpl::WebPopupMenuImpl(WebWidgetClient* client)
65     : m_client(client)
66     , m_widget(0)
67 {
68     // set to impossible point so we always get the first mouse pos
69     m_lastMousePosition = WebPoint(-1, -1);
70 }
71 
~WebPopupMenuImpl()72 WebPopupMenuImpl::~WebPopupMenuImpl()
73 {
74     if (m_widget)
75         m_widget->setClient(0);
76 }
77 
Init(FramelessScrollView * widget,const WebRect & bounds)78 void WebPopupMenuImpl::Init(FramelessScrollView* widget, const WebRect& bounds)
79 {
80     m_widget = widget;
81     m_widget->setClient(this);
82 
83     if (m_client) {
84         m_client->setWindowRect(bounds);
85         m_client->show(WebNavigationPolicy());  // Policy is ignored
86     }
87 }
88 
MouseMove(const WebMouseEvent & event)89 void WebPopupMenuImpl::MouseMove(const WebMouseEvent& event)
90 {
91     // don't send mouse move messages if the mouse hasn't moved.
92     if (event.x != m_lastMousePosition.x || event.y != m_lastMousePosition.y) {
93         m_lastMousePosition = WebPoint(event.x, event.y);
94         m_widget->handleMouseMoveEvent(PlatformMouseEventBuilder(m_widget, event));
95     }
96 }
97 
MouseLeave(const WebMouseEvent & event)98 void WebPopupMenuImpl::MouseLeave(const WebMouseEvent& event)
99 {
100     m_widget->handleMouseMoveEvent(PlatformMouseEventBuilder(m_widget, event));
101 }
102 
MouseDown(const WebMouseEvent & event)103 void WebPopupMenuImpl::MouseDown(const WebMouseEvent& event)
104 {
105     m_widget->handleMouseDownEvent(PlatformMouseEventBuilder(m_widget, event));
106 }
107 
MouseUp(const WebMouseEvent & event)108 void WebPopupMenuImpl::MouseUp(const WebMouseEvent& event)
109 {
110     mouseCaptureLost();
111     m_widget->handleMouseReleaseEvent(PlatformMouseEventBuilder(m_widget, event));
112 }
113 
MouseWheel(const WebMouseWheelEvent & event)114 void WebPopupMenuImpl::MouseWheel(const WebMouseWheelEvent& event)
115 {
116     m_widget->handleWheelEvent(PlatformWheelEventBuilder(m_widget, event));
117 }
118 
KeyEvent(const WebKeyboardEvent & event)119 bool WebPopupMenuImpl::KeyEvent(const WebKeyboardEvent& event)
120 {
121     return m_widget->handleKeyEvent(PlatformKeyboardEventBuilder(event));
122 }
123 
124 // WebWidget -------------------------------------------------------------------
125 
close()126 void WebPopupMenuImpl::close()
127 {
128     if (m_widget)
129         m_widget->hide();
130 
131     m_client = 0;
132 
133     deref();  // Balances ref() from WebWidget::Create
134 }
135 
resize(const WebSize & newSize)136 void WebPopupMenuImpl::resize(const WebSize& newSize)
137 {
138     if (m_size == newSize)
139         return;
140     m_size = newSize;
141 
142     if (m_widget) {
143       IntRect newGeometry(0, 0, m_size.width, m_size.height);
144       m_widget->setFrameRect(newGeometry);
145     }
146 
147     if (m_client) {
148       WebRect damagedRect(0, 0, m_size.width, m_size.height);
149       m_client->didInvalidateRect(damagedRect);
150     }
151 }
152 
layout()153 void WebPopupMenuImpl::layout()
154 {
155 }
156 
paint(WebCanvas * canvas,const WebRect & rect)157 void WebPopupMenuImpl::paint(WebCanvas* canvas, const WebRect& rect)
158 {
159     if (!m_widget)
160         return;
161 
162     if (!rect.isEmpty()) {
163 #if WEBKIT_USING_CG
164         GraphicsContext gc(canvas);
165 #elif WEBKIT_USING_SKIA
166         PlatformContextSkia context(canvas);
167         // PlatformGraphicsContext is actually a pointer to PlatformContextSkia.
168         GraphicsContext gc(reinterpret_cast<PlatformGraphicsContext*>(&context));
169 #else
170         notImplemented();
171 #endif
172         m_widget->paint(&gc, rect);
173     }
174 }
175 
handleInputEvent(const WebInputEvent & inputEvent)176 bool WebPopupMenuImpl::handleInputEvent(const WebInputEvent& inputEvent)
177 {
178     if (!m_widget)
179         return false;
180 
181     // TODO (jcampan): WebKit seems to always return false on mouse events
182     // methods. For now we'll assume it has processed them (as we are only
183     // interested in whether keyboard events are processed).
184     switch (inputEvent.type) {
185     case WebInputEvent::MouseMove:
186         MouseMove(*static_cast<const WebMouseEvent*>(&inputEvent));
187         return true;
188 
189     case WebInputEvent::MouseLeave:
190         MouseLeave(*static_cast<const WebMouseEvent*>(&inputEvent));
191         return true;
192 
193     case WebInputEvent::MouseWheel:
194         MouseWheel(*static_cast<const WebMouseWheelEvent*>(&inputEvent));
195         return true;
196 
197     case WebInputEvent::MouseDown:
198         MouseDown(*static_cast<const WebMouseEvent*>(&inputEvent));
199         return true;
200 
201     case WebInputEvent::MouseUp:
202         MouseUp(*static_cast<const WebMouseEvent*>(&inputEvent));
203         return true;
204 
205     // In Windows, RawKeyDown only has information about the physical key, but
206     // for "selection", we need the information about the character the key
207     // translated into. For English, the physical key value and the character
208     // value are the same, hence, "selection" works for English. But for other
209     // languages, such as Hebrew, the character value is different from the
210     // physical key value. Thus, without accepting Char event type which
211     // contains the key's character value, the "selection" won't work for
212     // non-English languages, such as Hebrew.
213     case WebInputEvent::RawKeyDown:
214     case WebInputEvent::KeyDown:
215     case WebInputEvent::KeyUp:
216     case WebInputEvent::Char:
217         return KeyEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent));
218 
219     default:
220         break;
221     }
222     return false;
223 }
224 
mouseCaptureLost()225 void WebPopupMenuImpl::mouseCaptureLost()
226 {
227 }
228 
setFocus(bool enable)229 void WebPopupMenuImpl::setFocus(bool enable)
230 {
231 }
232 
handleCompositionEvent(WebCompositionCommand command,int cursorPosition,int targetStart,int targetEnd,const WebString & imeString)233 bool WebPopupMenuImpl::handleCompositionEvent(
234     WebCompositionCommand command, int cursorPosition, int targetStart,
235     int targetEnd, const WebString& imeString)
236 {
237     return false;
238 }
239 
queryCompositionStatus(bool * enabled,WebRect * caretRect)240 bool WebPopupMenuImpl::queryCompositionStatus(bool* enabled, WebRect* caretRect)
241 {
242     return false;
243 }
244 
setTextDirection(WebTextDirection direction)245 void WebPopupMenuImpl::setTextDirection(WebTextDirection direction)
246 {
247 }
248 
249 
250 //-----------------------------------------------------------------------------
251 // WebCore::HostWindow
252 
repaint(const IntRect & paintRect,bool contentChanged,bool immediate,bool repaintContentOnly)253 void WebPopupMenuImpl::repaint(const IntRect& paintRect,
254                                bool contentChanged,
255                                bool immediate,
256                                bool repaintContentOnly)
257 {
258     // Ignore spurious calls.
259     if (!contentChanged || paintRect.isEmpty())
260         return;
261     if (m_client)
262         m_client->didInvalidateRect(paintRect);
263 }
264 
scroll(const IntSize & scrollDelta,const IntRect & scrollRect,const IntRect & clipRect)265 void WebPopupMenuImpl::scroll(const IntSize& scrollDelta,
266                               const IntRect& scrollRect,
267                               const IntRect& clipRect)
268 {
269     if (m_client) {
270         int dx = scrollDelta.width();
271         int dy = scrollDelta.height();
272         m_client->didScrollRect(dx, dy, clipRect);
273     }
274 }
275 
screenToWindow(const IntPoint & point) const276 IntPoint WebPopupMenuImpl::screenToWindow(const IntPoint& point) const
277 {
278     notImplemented();
279     return IntPoint();
280 }
281 
windowToScreen(const IntRect & rect) const282 IntRect WebPopupMenuImpl::windowToScreen(const IntRect& rect) const
283 {
284     notImplemented();
285     return IntRect();
286 }
287 
scrollRectIntoView(const IntRect &,const ScrollView *) const288 void WebPopupMenuImpl::scrollRectIntoView(const IntRect&, const ScrollView*) const
289 {
290     // Nothing to be done here since we do not have the concept of a container
291     // that implements its own scrolling.
292 }
293 
scrollbarsModeDidChange() const294 void WebPopupMenuImpl::scrollbarsModeDidChange() const
295 {
296     // Nothing to be done since we have no concept of different scrollbar modes.
297 }
298 
299 //-----------------------------------------------------------------------------
300 // WebCore::FramelessScrollViewClient
301 
popupClosed(FramelessScrollView * widget)302 void WebPopupMenuImpl::popupClosed(FramelessScrollView* widget)
303 {
304     ASSERT(widget == m_widget);
305     if (m_widget) {
306         m_widget->setClient(0);
307         m_widget = 0;
308     }
309     m_client->closeWidgetSoon();
310 }
311 
312 } // namespace WebKit
313