|
1 /* |
|
2 * Copyright (C) 2008 Apple 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 |
|
6 * are met: |
|
7 * 1. Redistributions of source code must retain the above copyright |
|
8 * notice, this list of conditions and the following disclaimer. |
|
9 * 2. Redistributions in binary form must reproduce the above copyright |
|
10 * notice, this list of conditions and the following disclaimer in the |
|
11 * documentation and/or other materials provided with the distribution. |
|
12 * |
|
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
|
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
|
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
|
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
24 */ |
|
25 |
|
26 #if ENABLE(NETSCAPE_PLUGIN_API) |
|
27 |
|
28 #import "WebNetscapePluginEventHandlerCocoa.h" |
|
29 |
|
30 #import "WebKitSystemInterface.h" |
|
31 #import "WebNetscapePluginView.h" |
|
32 #import <wtf/UnusedParam.h> |
|
33 #import <wtf/Vector.h> |
|
34 |
|
35 WebNetscapePluginEventHandlerCocoa::WebNetscapePluginEventHandlerCocoa(WebNetscapePluginView* pluginView) |
|
36 : WebNetscapePluginEventHandler(pluginView) |
|
37 #ifndef __LP64__ |
|
38 , m_keyEventHandler(0) |
|
39 #endif |
|
40 { |
|
41 } |
|
42 |
|
43 static inline void initializeEvent(NPCocoaEvent* event, NPCocoaEventType type) |
|
44 { |
|
45 event->type = type; |
|
46 event->version = 0; |
|
47 } |
|
48 |
|
49 void WebNetscapePluginEventHandlerCocoa::drawRect(CGContextRef context, const NSRect& rect) |
|
50 { |
|
51 NPCocoaEvent event; |
|
52 |
|
53 initializeEvent(&event, NPCocoaEventDrawRect); |
|
54 event.data.draw.context = context; |
|
55 event.data.draw.x = rect.origin.x; |
|
56 event.data.draw.y = rect.origin.y; |
|
57 event.data.draw.width = rect.size.width; |
|
58 event.data.draw.height = rect.size.height; |
|
59 |
|
60 RetainPtr<CGContextRef> protect(context); |
|
61 |
|
62 sendEvent(&event); |
|
63 } |
|
64 |
|
65 void WebNetscapePluginEventHandlerCocoa::mouseDown(NSEvent *event) |
|
66 { |
|
67 sendMouseEvent(event, NPCocoaEventMouseDown); |
|
68 } |
|
69 |
|
70 void WebNetscapePluginEventHandlerCocoa::mouseDragged(NSEvent *event) |
|
71 { |
|
72 sendMouseEvent(event, NPCocoaEventMouseDragged); |
|
73 } |
|
74 |
|
75 void WebNetscapePluginEventHandlerCocoa::mouseEntered(NSEvent *event) |
|
76 { |
|
77 sendMouseEvent(event, NPCocoaEventMouseEntered); |
|
78 } |
|
79 |
|
80 void WebNetscapePluginEventHandlerCocoa::mouseExited(NSEvent *event) |
|
81 { |
|
82 sendMouseEvent(event, NPCocoaEventMouseExited); |
|
83 } |
|
84 |
|
85 void WebNetscapePluginEventHandlerCocoa::mouseMoved(NSEvent *event) |
|
86 { |
|
87 sendMouseEvent(event, NPCocoaEventMouseMoved); |
|
88 } |
|
89 |
|
90 void WebNetscapePluginEventHandlerCocoa::mouseUp(NSEvent *event) |
|
91 { |
|
92 sendMouseEvent(event, NPCocoaEventMouseUp); |
|
93 } |
|
94 |
|
95 bool WebNetscapePluginEventHandlerCocoa::scrollWheel(NSEvent* event) |
|
96 { |
|
97 return sendMouseEvent(event, NPCocoaEventScrollWheel); |
|
98 } |
|
99 |
|
100 bool WebNetscapePluginEventHandlerCocoa::sendMouseEvent(NSEvent *nsEvent, NPCocoaEventType type) |
|
101 { |
|
102 NPCocoaEvent event; |
|
103 |
|
104 NSPoint point = [m_pluginView convertPoint:[nsEvent locationInWindow] fromView:nil]; |
|
105 |
|
106 int clickCount; |
|
107 if (type == NPCocoaEventMouseEntered || type == NPCocoaEventMouseExited || type == NPCocoaEventScrollWheel) |
|
108 clickCount = 0; |
|
109 else |
|
110 clickCount = [nsEvent clickCount]; |
|
111 |
|
112 initializeEvent(&event, type); |
|
113 event.data.mouse.modifierFlags = [nsEvent modifierFlags]; |
|
114 event.data.mouse.buttonNumber = [nsEvent buttonNumber]; |
|
115 event.data.mouse.clickCount = clickCount; |
|
116 event.data.mouse.pluginX = point.x; |
|
117 event.data.mouse.pluginY = point.y; |
|
118 event.data.mouse.deltaX = [nsEvent deltaX]; |
|
119 event.data.mouse.deltaY = [nsEvent deltaY]; |
|
120 event.data.mouse.deltaZ = [nsEvent deltaZ]; |
|
121 |
|
122 return sendEvent(&event); |
|
123 } |
|
124 |
|
125 void WebNetscapePluginEventHandlerCocoa::keyDown(NSEvent *event) |
|
126 { |
|
127 bool retval = sendKeyEvent(event, NPCocoaEventKeyDown); |
|
128 |
|
129 #ifndef __LP64__ |
|
130 // If the plug-in did not handle the event, pass it on to the Input Manager. |
|
131 if (retval) |
|
132 WKSendKeyEventToTSM(event); |
|
133 #else |
|
134 UNUSED_PARAM(retval); |
|
135 #endif |
|
136 } |
|
137 |
|
138 void WebNetscapePluginEventHandlerCocoa::keyUp(NSEvent *event) |
|
139 { |
|
140 sendKeyEvent(event, NPCocoaEventKeyUp); |
|
141 } |
|
142 |
|
143 void WebNetscapePluginEventHandlerCocoa::flagsChanged(NSEvent *nsEvent) |
|
144 { |
|
145 NPCocoaEvent event; |
|
146 |
|
147 initializeEvent(&event, NPCocoaEventFlagsChanged); |
|
148 event.data.key.modifierFlags = [nsEvent modifierFlags]; |
|
149 event.data.key.keyCode = [nsEvent keyCode]; |
|
150 event.data.key.isARepeat = false; |
|
151 event.data.key.characters = 0; |
|
152 event.data.key.charactersIgnoringModifiers = 0; |
|
153 |
|
154 sendEvent(&event); |
|
155 } |
|
156 |
|
157 void WebNetscapePluginEventHandlerCocoa::syntheticKeyDownWithCommandModifier(int keyCode, char character) |
|
158 { |
|
159 char nullTerminatedString[] = { character, '\0' }; |
|
160 |
|
161 RetainPtr<NSString> characters(AdoptNS, [[NSString alloc] initWithUTF8String:nullTerminatedString]); |
|
162 |
|
163 NPCocoaEvent event; |
|
164 initializeEvent(&event, NPCocoaEventKeyDown); |
|
165 event.data.key.modifierFlags = NSCommandKeyMask; |
|
166 event.data.key.keyCode = keyCode; |
|
167 event.data.key.isARepeat = false; |
|
168 event.data.key.characters = (NPNSString *)characters.get(); |
|
169 event.data.key.charactersIgnoringModifiers = (NPNSString *)characters.get(); |
|
170 |
|
171 sendEvent(&event); |
|
172 } |
|
173 |
|
174 bool WebNetscapePluginEventHandlerCocoa::sendKeyEvent(NSEvent* nsEvent, NPCocoaEventType type) |
|
175 { |
|
176 NPCocoaEvent event; |
|
177 |
|
178 initializeEvent(&event, type); |
|
179 event.data.key.modifierFlags = [nsEvent modifierFlags]; |
|
180 event.data.key.keyCode = [nsEvent keyCode]; |
|
181 event.data.key.isARepeat = [nsEvent isARepeat]; |
|
182 event.data.key.characters = (NPNSString *)[nsEvent characters]; |
|
183 event.data.key.charactersIgnoringModifiers = (NPNSString *)[nsEvent charactersIgnoringModifiers]; |
|
184 |
|
185 return sendEvent(&event); |
|
186 } |
|
187 |
|
188 void WebNetscapePluginEventHandlerCocoa::windowFocusChanged(bool hasFocus) |
|
189 { |
|
190 NPCocoaEvent event; |
|
191 |
|
192 initializeEvent(&event, NPCocoaEventWindowFocusChanged); |
|
193 event.data.focus.hasFocus = hasFocus; |
|
194 |
|
195 sendEvent(&event); |
|
196 } |
|
197 |
|
198 void WebNetscapePluginEventHandlerCocoa::focusChanged(bool hasFocus) |
|
199 { |
|
200 NPCocoaEvent event; |
|
201 |
|
202 initializeEvent(&event, NPCocoaEventFocusChanged); |
|
203 event.data.focus.hasFocus = hasFocus; |
|
204 |
|
205 sendEvent(&event); |
|
206 |
|
207 if (hasFocus) |
|
208 installKeyEventHandler(); |
|
209 else |
|
210 removeKeyEventHandler(); |
|
211 } |
|
212 |
|
213 void* WebNetscapePluginEventHandlerCocoa::platformWindow(NSWindow* window) |
|
214 { |
|
215 return window; |
|
216 } |
|
217 |
|
218 bool WebNetscapePluginEventHandlerCocoa::sendEvent(NPCocoaEvent* event) |
|
219 { |
|
220 switch (event->type) { |
|
221 case NPCocoaEventMouseDown: |
|
222 case NPCocoaEventMouseUp: |
|
223 case NPCocoaEventMouseDragged: |
|
224 case NPCocoaEventKeyDown: |
|
225 case NPCocoaEventKeyUp: |
|
226 case NPCocoaEventFlagsChanged: |
|
227 case NPCocoaEventScrollWheel: |
|
228 m_currentEventIsUserGesture = true; |
|
229 break; |
|
230 default: |
|
231 m_currentEventIsUserGesture = false; |
|
232 } |
|
233 |
|
234 bool result = [m_pluginView sendEvent:event isDrawRect:event->type == NPCocoaEventDrawRect]; |
|
235 |
|
236 m_currentEventIsUserGesture = false; |
|
237 return result; |
|
238 } |
|
239 |
|
240 #ifndef __LP64__ |
|
241 |
|
242 void WebNetscapePluginEventHandlerCocoa::installKeyEventHandler() |
|
243 { |
|
244 static const EventTypeSpec TSMEvents[] = |
|
245 { |
|
246 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } |
|
247 }; |
|
248 |
|
249 if (!m_keyEventHandler) |
|
250 InstallEventHandler(GetWindowEventTarget((WindowRef)[[m_pluginView window] windowRef]), |
|
251 NewEventHandlerUPP(TSMEventHandler), |
|
252 GetEventTypeCount(TSMEvents), |
|
253 TSMEvents, |
|
254 this, |
|
255 &m_keyEventHandler); |
|
256 } |
|
257 |
|
258 void WebNetscapePluginEventHandlerCocoa::removeKeyEventHandler() |
|
259 { |
|
260 if (m_keyEventHandler) { |
|
261 RemoveEventHandler(m_keyEventHandler); |
|
262 m_keyEventHandler = 0; |
|
263 } |
|
264 } |
|
265 |
|
266 OSStatus WebNetscapePluginEventHandlerCocoa::TSMEventHandler(EventHandlerCallRef inHandlerRef, EventRef event, void* eventHandler) |
|
267 { |
|
268 return static_cast<WebNetscapePluginEventHandlerCocoa*>(eventHandler)->handleTSMEvent(event); |
|
269 } |
|
270 |
|
271 OSStatus WebNetscapePluginEventHandlerCocoa::handleTSMEvent(EventRef eventRef) |
|
272 { |
|
273 ASSERT(GetEventKind(eventRef) == kEventTextInputUnicodeForKeyEvent); |
|
274 |
|
275 // Get the text buffer size. |
|
276 ByteCount size; |
|
277 OSStatus result = GetEventParameter(eventRef, kEventParamTextInputSendText, typeUnicodeText, 0, 0, &size, 0); |
|
278 if (result != noErr) |
|
279 return result; |
|
280 |
|
281 unsigned length = size / sizeof(UniChar); |
|
282 Vector<UniChar, 16> characters(length); |
|
283 |
|
284 // Now get the actual text. |
|
285 result = GetEventParameter(eventRef, kEventParamTextInputSendText, typeUnicodeText, 0, size, 0, characters.data()); |
|
286 if (result != noErr) |
|
287 return result; |
|
288 |
|
289 RetainPtr<CFStringRef> text(AdoptCF, CFStringCreateWithCharacters(0, characters.data(), length)); |
|
290 |
|
291 NPCocoaEvent event; |
|
292 |
|
293 initializeEvent(&event, NPCocoaEventTextInput); |
|
294 event.data.text.text = (NPNSString*)text.get(); |
|
295 |
|
296 sendEvent(&event); |
|
297 |
|
298 return noErr; |
|
299 } |
|
300 |
|
301 #endif // __LP64__ |
|
302 |
|
303 #endif // ENABLE(NETSCAPE_PLUGIN_API) |