initial import
[vuplus_webkit] / Source / WebKit2 / Shared / mac / WebEventFactory.mm
1 /*
2  * Copyright (C) 2010, 2011 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "WebEventFactory.h"
28
29 #import "WebKitSystemInterface.h"
30 #import <wtf/ASCIICType.h>
31 #import <WebCore/Scrollbar.h>
32 #import <WebCore/WindowsKeyboardCodes.h>
33
34 using namespace WebCore;
35
36 namespace WebKit {
37
38 static WebMouseEvent::Button currentMouseButton()
39 {
40     NSUInteger pressedMouseButtons = [NSEvent pressedMouseButtons];
41     if (!pressedMouseButtons)
42         return WebMouseEvent::NoButton;
43     if (pressedMouseButtons == 1 << 0)
44         return WebMouseEvent::LeftButton;
45     if (pressedMouseButtons == 1 << 1)
46         return WebMouseEvent::RightButton;
47     return WebMouseEvent::MiddleButton;
48 }
49
50 static WebMouseEvent::Button mouseButtonForEvent(NSEvent *event)
51 {
52     switch ([event type]) {
53         case NSLeftMouseDown:
54         case NSLeftMouseUp:
55         case NSLeftMouseDragged:
56             return WebMouseEvent::LeftButton;
57         case NSRightMouseDown:
58         case NSRightMouseUp:
59         case NSRightMouseDragged:
60             return WebMouseEvent::RightButton;
61         case NSOtherMouseDown:
62         case NSOtherMouseUp:
63         case NSOtherMouseDragged:
64             return WebMouseEvent::MiddleButton;
65         case NSMouseEntered:
66         case NSMouseExited:
67             return currentMouseButton();
68         default:
69             return WebMouseEvent::NoButton;
70     }
71 }
72
73 static WebEvent::Type mouseEventTypeForEvent(NSEvent* event)
74 {
75     switch ([event type]) {
76         case NSLeftMouseDragged:
77         case NSMouseEntered:
78         case NSMouseExited:
79         case NSMouseMoved:
80         case NSOtherMouseDragged:
81         case NSRightMouseDragged:
82             return WebEvent::MouseMove;
83         case NSLeftMouseDown:
84         case NSRightMouseDown:
85         case NSOtherMouseDown:
86             return WebEvent::MouseDown;
87         case NSLeftMouseUp:
88         case NSRightMouseUp:
89         case NSOtherMouseUp:
90             return WebEvent::MouseUp;
91         default:
92             return WebEvent::MouseMove;
93     }
94 }
95
96 static int clickCountForEvent(NSEvent *event)
97 {
98     switch ([event type]) {
99         case NSLeftMouseDown:
100         case NSLeftMouseUp:
101         case NSLeftMouseDragged:
102         case NSRightMouseDown:
103         case NSRightMouseUp:
104         case NSRightMouseDragged:
105         case NSOtherMouseDown:
106         case NSOtherMouseUp:
107         case NSOtherMouseDragged:
108             return [event clickCount];
109         default:
110             return 0;
111     }
112 }
113
114 static NSScreen *screenForWindow(NSWindow *window)
115 {
116     NSScreen *screen = [window screen]; // nil if the window is off-screen
117     if (screen)
118         return screen;
119     
120     NSArray *screens = [NSScreen screens];
121     if ([screens count] > 0)
122         return [screens objectAtIndex:0]; // screen containing the menubar
123     
124     return nil;
125 }
126
127 static NSPoint flipScreenPoint(const NSPoint& screenPoint, NSScreen *screen)
128 {
129     NSPoint flippedPoint = screenPoint;
130     flippedPoint.y = NSMaxY([screen frame]) - flippedPoint.y;
131     return flippedPoint;
132 }
133
134 static NSPoint globalPoint(const NSPoint& windowPoint, NSWindow *window)
135 {
136     return flipScreenPoint([window convertBaseToScreen:windowPoint], screenForWindow(window));
137 }
138
139 static NSPoint globalPointForEvent(NSEvent *event)
140 {
141     switch ([event type]) {
142         case NSLeftMouseDown:
143         case NSLeftMouseDragged:
144         case NSLeftMouseUp:
145         case NSMouseEntered:
146         case NSMouseExited:
147         case NSMouseMoved:
148         case NSOtherMouseDown:
149         case NSOtherMouseDragged:
150         case NSOtherMouseUp:
151         case NSRightMouseDown:
152         case NSRightMouseDragged:
153         case NSRightMouseUp:
154         case NSScrollWheel:
155             return globalPoint([event locationInWindow], [event window]);
156         default:
157             return NSZeroPoint;
158     }
159 }
160
161 static NSPoint pointForEvent(NSEvent *event, NSView *windowView)
162 {
163     switch ([event type]) {
164         case NSLeftMouseDown:
165         case NSLeftMouseDragged:
166         case NSLeftMouseUp:
167         case NSMouseEntered:
168         case NSMouseExited:
169         case NSMouseMoved:
170         case NSOtherMouseDown:
171         case NSOtherMouseDragged:
172         case NSOtherMouseUp:
173         case NSRightMouseDown:
174         case NSRightMouseDragged:
175         case NSRightMouseUp:
176         case NSScrollWheel: {
177             // Note: This will have its origin at the bottom left of the window unless windowView is flipped.
178             // In those cases, the Y coordinate gets flipped by Widget::convertFromContainingWindow.
179             NSPoint location = [event locationInWindow];
180             if (windowView)
181                 location = [windowView convertPoint:location fromView:nil];
182             return location;
183         }
184         default:
185             return NSZeroPoint;
186     }
187 }
188
189 static WebWheelEvent::Phase phaseForEvent(NSEvent *event)
190 {
191 #if !defined(BUILDING_ON_SNOW_LEOPARD)
192     uint32_t phase = WebWheelEvent::PhaseNone; 
193     if ([event phase] & NSEventPhaseBegan)
194         phase |= WebWheelEvent::PhaseBegan;
195     if ([event phase] & NSEventPhaseStationary)
196         phase |= WebWheelEvent::PhaseStationary;
197     if ([event phase] & NSEventPhaseChanged)
198         phase |= WebWheelEvent::PhaseChanged;
199     if ([event phase] & NSEventPhaseEnded)
200         phase |= WebWheelEvent::PhaseEnded;
201     if ([event phase] & NSEventPhaseCancelled)
202         phase |= WebWheelEvent::PhaseCancelled;
203     return static_cast<WebWheelEvent::Phase>(phase);
204 #else
205     return WebWheelEvent::PhaseNone;
206 #endif
207 }
208
209 static WebWheelEvent::Phase momentumPhaseForEvent(NSEvent *event)
210 {
211     uint32_t phase = WebWheelEvent::PhaseNone; 
212
213 #if !defined(BUILDING_ON_SNOW_LEOPARD)
214     if ([event momentumPhase] & NSEventPhaseBegan)
215         phase |= WebWheelEvent::PhaseBegan;
216     if ([event momentumPhase] & NSEventPhaseStationary)
217         phase |= WebWheelEvent::PhaseStationary;
218     if ([event momentumPhase] & NSEventPhaseChanged)
219         phase |= WebWheelEvent::PhaseChanged;
220     if ([event momentumPhase] & NSEventPhaseEnded)
221         phase |= WebWheelEvent::PhaseEnded;
222     if ([event momentumPhase] & NSEventPhaseCancelled)
223         phase |= WebWheelEvent::PhaseCancelled;
224 #else
225     switch (WKGetNSEventMomentumPhase(event)) {
226     case WKEventPhaseNone:
227         phase = WebWheelEvent::PhaseNone;
228         break;
229     case WKEventPhaseBegan:
230         phase = WebWheelEvent::PhaseBegan;
231         break;
232     case WKEventPhaseChanged:
233         phase = WebWheelEvent::PhaseChanged;
234         break;
235     case WKEventPhaseEnded:
236         phase = WebWheelEvent::PhaseEnded;
237         break;
238     }
239 #endif
240
241     return static_cast<WebWheelEvent::Phase>(phase);
242 }
243
244 #if ENABLE(GESTURE_EVENTS)
245 static WebEvent::Type gestureEventTypeForEvent(NSEvent *event)
246 {
247     switch ([event type]) {
248     case NSEventTypeBeginGesture:
249         return WebEvent::GestureScrollBegin;
250     case NSEventTypeEndGesture:
251         return WebEvent::GestureScrollEnd;
252     default:
253         ASSERT_NOT_REACHED();
254         return WebEvent::GestureScrollEnd;
255     }
256 }
257 #endif
258
259 static inline String textFromEvent(NSEvent* event)
260 {
261     if ([event type] == NSFlagsChanged)
262         return String("");
263     return String([event characters]);
264 }
265
266 static inline String unmodifiedTextFromEvent(NSEvent* event)
267 {
268     if ([event type] == NSFlagsChanged)
269         return String("");
270     return String([event charactersIgnoringModifiers]);
271 }
272
273 static String keyIdentifierForKeyEvent(NSEvent* event)
274 {
275     if ([event type] == NSFlagsChanged) 
276         switch ([event keyCode]) {
277             case 54: // Right Command
278             case 55: // Left Command
279                 return String("Meta");
280                 
281             case 57: // Capslock
282                 return String("CapsLock");
283                 
284             case 56: // Left Shift
285             case 60: // Right Shift
286                 return String("Shift");
287                 
288             case 58: // Left Alt
289             case 61: // Right Alt
290                 return String("Alt");
291                 
292             case 59: // Left Ctrl
293             case 62: // Right Ctrl
294                 return String("Control");
295                 
296             default:
297                 ASSERT_NOT_REACHED();
298                 return String("");
299         }
300     
301     NSString *s = [event charactersIgnoringModifiers];
302     if ([s length] != 1)
303         return String("Unidentified");
304
305     unichar c = [s characterAtIndex:0];
306     switch (c) {
307         // Each identifier listed in the DOM spec is listed here.
308         // Many are simply commented out since they do not appear on standard Macintosh keyboards
309         // or are on a key that doesn't have a corresponding character.
310
311         // "Accept"
312         // "AllCandidates"
313
314         // "Alt"
315         case NSMenuFunctionKey:
316             return String("Alt");
317
318         // "Apps"
319         // "BrowserBack"
320         // "BrowserForward"
321         // "BrowserHome"
322         // "BrowserRefresh"
323         // "BrowserSearch"
324         // "BrowserStop"
325         // "CapsLock"
326
327         // "Clear"
328         case NSClearLineFunctionKey:
329             return String("Clear");
330
331         // "CodeInput"
332         // "Compose"
333         // "Control"
334         // "Crsel"
335         // "Convert"
336         // "Copy"
337         // "Cut"
338
339         // "Down"
340         case NSDownArrowFunctionKey:
341             return String("Down");
342         // "End"
343         case NSEndFunctionKey:
344             return String("End");
345         // "Enter"
346         case 0x3: case 0xA: case 0xD: // Macintosh calls the one on the main keyboard Return, but Windows calls it Enter, so we'll do the same for the DOM
347             return String("Enter");
348
349         // "EraseEof"
350
351         // "Execute"
352         case NSExecuteFunctionKey:
353             return String("Execute");
354
355         // "Exsel"
356
357         // "F1"
358         case NSF1FunctionKey:
359             return String("F1");
360         // "F2"
361         case NSF2FunctionKey:
362             return String("F2");
363         // "F3"
364         case NSF3FunctionKey:
365             return String("F3");
366         // "F4"
367         case NSF4FunctionKey:
368             return String("F4");
369         // "F5"
370         case NSF5FunctionKey:
371             return String("F5");
372         // "F6"
373         case NSF6FunctionKey:
374             return String("F6");
375         // "F7"
376         case NSF7FunctionKey:
377             return String("F7");
378         // "F8"
379         case NSF8FunctionKey:
380             return String("F8");
381         // "F9"
382         case NSF9FunctionKey:
383             return String("F9");
384         // "F10"
385         case NSF10FunctionKey:
386             return String("F10");
387         // "F11"
388         case NSF11FunctionKey:
389             return String("F11");
390         // "F12"
391         case NSF12FunctionKey:
392             return String("F12");
393         // "F13"
394         case NSF13FunctionKey:
395             return String("F13");
396         // "F14"
397         case NSF14FunctionKey:
398             return String("F14");
399         // "F15"
400         case NSF15FunctionKey:
401             return String("F15");
402         // "F16"
403         case NSF16FunctionKey:
404             return String("F16");
405         // "F17"
406         case NSF17FunctionKey:
407             return String("F17");
408         // "F18"
409         case NSF18FunctionKey:
410             return String("F18");
411         // "F19"
412         case NSF19FunctionKey:
413             return String("F19");
414         // "F20"
415         case NSF20FunctionKey:
416             return String("F20");
417         // "F21"
418         case NSF21FunctionKey:
419             return String("F21");
420         // "F22"
421         case NSF22FunctionKey:
422             return String("F22");
423         // "F23"
424         case NSF23FunctionKey:
425             return String("F23");
426         // "F24"
427         case NSF24FunctionKey:
428             return String("F24");
429
430         // "FinalMode"
431
432         // "Find"
433         case NSFindFunctionKey:
434             return String("Find");
435
436         // "FullWidth"
437         // "HalfWidth"
438         // "HangulMode"
439         // "HanjaMode"
440
441         // "Help"
442         case NSHelpFunctionKey:
443             return String("Help");
444
445         // "Hiragana"
446
447         // "Home"
448         case NSHomeFunctionKey:
449             return String("Home");
450         // "Insert"
451         case NSInsertFunctionKey:
452             return String("Insert");
453
454         // "JapaneseHiragana"
455         // "JapaneseKatakana"
456         // "JapaneseRomaji"
457         // "JunjaMode"
458         // "KanaMode"
459         // "KanjiMode"
460         // "Katakana"
461         // "LaunchApplication1"
462         // "LaunchApplication2"
463         // "LaunchMail"
464
465         // "Left"
466         case NSLeftArrowFunctionKey:
467             return String("Left");
468
469         // "Meta"
470         // "MediaNextTrack"
471         // "MediaPlayPause"
472         // "MediaPreviousTrack"
473         // "MediaStop"
474
475         // "ModeChange"
476         case NSModeSwitchFunctionKey:
477             return String("ModeChange");
478
479         // "Nonconvert"
480         // "NumLock"
481
482         // "PageDown"
483         case NSPageDownFunctionKey:
484             return String("PageDown");
485         // "PageUp"
486         case NSPageUpFunctionKey:
487             return String("PageUp");
488
489         // "Paste"
490
491         // "Pause"
492         case NSPauseFunctionKey:
493             return String("Pause");
494
495         // "Play"
496         // "PreviousCandidate"
497
498         // "PrintScreen"
499         case NSPrintScreenFunctionKey:
500             return String("PrintScreen");
501
502         // "Process"
503         // "Props"
504
505         // "Right"
506         case NSRightArrowFunctionKey:
507             return String("Right");
508
509         // "RomanCharacters"
510
511         // "Scroll"
512         case NSScrollLockFunctionKey:
513             return String("Scroll");
514         // "Select"
515         case NSSelectFunctionKey:
516             return String("Select");
517
518         // "SelectMedia"
519         // "Shift"
520
521         // "Stop"
522         case NSStopFunctionKey:
523             return String("Stop");
524         // "Up"
525         case NSUpArrowFunctionKey:
526             return String("Up");
527         // "Undo"
528         case NSUndoFunctionKey:
529             return String("Undo");
530
531         // "VolumeDown"
532         // "VolumeMute"
533         // "VolumeUp"
534         // "Win"
535         // "Zoom"
536
537         // More function keys, not in the key identifier specification.
538         case NSF25FunctionKey:
539             return String("F25");
540         case NSF26FunctionKey:
541             return String("F26");
542         case NSF27FunctionKey:
543             return String("F27");
544         case NSF28FunctionKey:
545             return String("F28");
546         case NSF29FunctionKey:
547             return String("F29");
548         case NSF30FunctionKey:
549             return String("F30");
550         case NSF31FunctionKey:
551             return String("F31");
552         case NSF32FunctionKey:
553             return String("F32");
554         case NSF33FunctionKey:
555             return String("F33");
556         case NSF34FunctionKey:
557             return String("F34");
558         case NSF35FunctionKey:
559             return String("F35");
560
561         // Turn 0x7F into 0x08, because backspace needs to always be 0x08.
562         case 0x7F:
563             return String("U+0008");
564         // Standard says that DEL becomes U+007F.
565         case NSDeleteFunctionKey:
566             return String("U+007F");
567             
568         // Always use 0x09 for tab instead of AppKit's backtab character.
569         case NSBackTabCharacter:
570             return String("U+0009");
571
572         case NSBeginFunctionKey:
573         case NSBreakFunctionKey:
574         case NSClearDisplayFunctionKey:
575         case NSDeleteCharFunctionKey:
576         case NSDeleteLineFunctionKey:
577         case NSInsertCharFunctionKey:
578         case NSInsertLineFunctionKey:
579         case NSNextFunctionKey:
580         case NSPrevFunctionKey:
581         case NSPrintFunctionKey:
582         case NSRedoFunctionKey:
583         case NSResetFunctionKey:
584         case NSSysReqFunctionKey:
585         case NSSystemFunctionKey:
586         case NSUserFunctionKey:
587             // FIXME: We should use something other than the vendor-area Unicode values for the above keys.
588             // For now, just fall through to the default.
589         default:
590             return String::format("U+%04X", toASCIIUpper(c));
591     }
592 }
593
594 static bool isKeypadEvent(NSEvent* event)
595 {
596     // Check that this is the type of event that has a keyCode.
597     switch ([event type]) {
598         case NSKeyDown:
599         case NSKeyUp:
600         case NSFlagsChanged:
601             break;
602         default:
603             return false;
604     }
605
606     switch ([event keyCode]) {
607         case 71: // Clear
608         case 81: // =
609         case 75: // /
610         case 67: // *
611         case 78: // -
612         case 69: // +
613         case 76: // Enter
614         case 65: // .
615         case 82: // 0
616         case 83: // 1
617         case 84: // 2
618         case 85: // 3
619         case 86: // 4
620         case 87: // 5
621         case 88: // 6
622         case 89: // 7
623         case 91: // 8
624         case 92: // 9
625             return true;
626      }
627      
628      return false;
629 }
630
631 static int windowsKeyCodeForKeyEvent(NSEvent* event)
632 {
633     switch ([event keyCode]) {
634         // VK_TAB (09) TAB key
635         case 48: return 0x09;
636
637         // VK_APPS (5D) Right windows/meta key
638         case 54: // Right Command
639             return 0x5D;
640             
641         // VK_LWIN (5B) Left windows/meta key
642         case 55: // Left Command
643             return 0x5B;
644             
645         // VK_CAPITAL (14) caps locks key
646         case 57: // Capslock
647             return 0x14;
648             
649         // VK_SHIFT (10) either shift key
650         case 56: // Left Shift
651         case 60: // Right Shift
652             return 0x10;
653             
654         // VK_MENU (12) either alt key
655         case 58: // Left Alt
656         case 61: // Right Alt
657             return 0x12;
658             
659         // VK_CONTROL (11) either ctrl key
660         case 59: // Left Ctrl
661         case 62: // Right Ctrl
662             return 0x11;
663             
664         // VK_CLEAR (0C) CLEAR key
665         case 71: return 0x0C;
666
667         // VK_NUMPAD0 (60) Numeric keypad 0 key
668         case 82: return 0x60;
669         // VK_NUMPAD1 (61) Numeric keypad 1 key
670         case 83: return 0x61;
671         // VK_NUMPAD2 (62) Numeric keypad 2 key
672         case 84: return 0x62;
673         // VK_NUMPAD3 (63) Numeric keypad 3 key
674         case 85: return 0x63;
675         // VK_NUMPAD4 (64) Numeric keypad 4 key
676         case 86: return 0x64;
677         // VK_NUMPAD5 (65) Numeric keypad 5 key
678         case 87: return 0x65;
679         // VK_NUMPAD6 (66) Numeric keypad 6 key
680         case 88: return 0x66;
681         // VK_NUMPAD7 (67) Numeric keypad 7 key
682         case 89: return 0x67;
683         // VK_NUMPAD8 (68) Numeric keypad 8 key
684         case 91: return 0x68;
685         // VK_NUMPAD9 (69) Numeric keypad 9 key
686         case 92: return 0x69;
687         // VK_MULTIPLY (6A) Multiply key
688         case 67: return 0x6A;
689         // VK_ADD (6B) Add key
690         case 69: return 0x6B;
691
692         // VK_SUBTRACT (6D) Subtract key
693         case 78: return 0x6D;
694         // VK_DECIMAL (6E) Decimal key
695         case 65: return 0x6E;
696         // VK_DIVIDE (6F) Divide key
697         case 75: return 0x6F;
698      }
699     
700     if ([event type] == NSFlagsChanged)
701         return 0;
702
703     NSString* s = [event charactersIgnoringModifiers];
704     if ([s length] != 1)
705         return 0;
706
707     switch ([s characterAtIndex:0]) {
708         // VK_LBUTTON (01) Left mouse button
709         // VK_RBUTTON (02) Right mouse button
710         // VK_CANCEL (03) Control-break processing
711         // VK_MBUTTON (04) Middle mouse button (three-button mouse)
712         // VK_XBUTTON1 (05)
713         // VK_XBUTTON2 (06)
714
715         // VK_BACK (08) BACKSPACE key
716         case 8: case 0x7F: return 0x08;
717         // VK_TAB (09) TAB key
718         case 9: return 0x09;
719
720         // VK_CLEAR (0C) CLEAR key
721         // handled by key code above
722
723         // VK_RETURN (0D)
724         case 0xD: case 3: return 0x0D;
725
726         // VK_SHIFT (10) SHIFT key
727         // VK_CONTROL (11) CTRL key
728         // VK_MENU (12) ALT key
729
730         // VK_PAUSE (13) PAUSE key
731         case NSPauseFunctionKey: return 0x13;
732
733         // VK_CAPITAL (14) CAPS LOCK key
734         // VK_KANA (15) Input Method Editor (IME) Kana mode
735         // VK_HANGUEL (15) IME Hanguel mode (maintained for compatibility; use VK_HANGUL)
736         // VK_HANGUL (15) IME Hangul mode
737         // VK_JUNJA (17) IME Junja mode
738         // VK_FINAL (18) IME final mode
739         // VK_HANJA (19) IME Hanja mode
740         // VK_KANJI (19) IME Kanji mode
741
742         // VK_ESCAPE (1B) ESC key
743         case 0x1B: return 0x1B;
744
745         // VK_CONVERT (1C) IME convert
746         // VK_NONCONVERT (1D) IME nonconvert
747         // VK_ACCEPT (1E) IME accept
748         // VK_MODECHANGE (1F) IME mode change request
749
750         // VK_SPACE (20) SPACEBAR
751         case ' ': return 0x20;
752         // VK_PRIOR (21) PAGE UP key
753         case NSPageUpFunctionKey: return 0x21;
754         // VK_NEXT (22) PAGE DOWN key
755         case NSPageDownFunctionKey: return 0x22;
756         // VK_END (23) END key
757         case NSEndFunctionKey: return 0x23;
758         // VK_HOME (24) HOME key
759         case NSHomeFunctionKey: return 0x24;
760         // VK_LEFT (25) LEFT ARROW key
761         case NSLeftArrowFunctionKey: return 0x25;
762         // VK_UP (26) UP ARROW key
763         case NSUpArrowFunctionKey: return 0x26;
764         // VK_RIGHT (27) RIGHT ARROW key
765         case NSRightArrowFunctionKey: return 0x27;
766         // VK_DOWN (28) DOWN ARROW key
767         case NSDownArrowFunctionKey: return 0x28;
768         // VK_SELECT (29) SELECT key
769         case NSSelectFunctionKey: return 0x29;
770         // VK_PRINT (2A) PRINT key
771         case NSPrintFunctionKey: return 0x2A;
772         // VK_EXECUTE (2B) EXECUTE key
773         case NSExecuteFunctionKey: return 0x2B;
774         // VK_SNAPSHOT (2C) PRINT SCREEN key
775         case NSPrintScreenFunctionKey: return 0x2C;
776         // VK_INSERT (2D) INS key
777         case NSInsertFunctionKey: case NSHelpFunctionKey: return 0x2D;
778         // VK_DELETE (2E) DEL key
779         case NSDeleteFunctionKey: return 0x2E;
780
781         // VK_HELP (2F) HELP key
782
783         //  (30) 0 key
784         case '0': case ')': return 0x30;
785         //  (31) 1 key
786         case '1': case '!': return 0x31;
787         //  (32) 2 key
788         case '2': case '@': return 0x32;
789         //  (33) 3 key
790         case '3': case '#': return 0x33;
791         //  (34) 4 key
792         case '4': case '$': return 0x34;
793         //  (35) 5 key
794         case '5': case '%': return 0x35;
795         //  (36) 6 key
796         case '6': case '^': return 0x36;
797         //  (37) 7 key
798         case '7': case '&': return 0x37;
799         //  (38) 8 key
800         case '8': case '*': return 0x38;
801         //  (39) 9 key
802         case '9': case '(': return 0x39;
803         //  (41) A key
804         case 'a': case 'A': return 0x41;
805         //  (42) B key
806         case 'b': case 'B': return 0x42;
807         //  (43) C key
808         case 'c': case 'C': return 0x43;
809         //  (44) D key
810         case 'd': case 'D': return 0x44;
811         //  (45) E key
812         case 'e': case 'E': return 0x45;
813         //  (46) F key
814         case 'f': case 'F': return 0x46;
815         //  (47) G key
816         case 'g': case 'G': return 0x47;
817         //  (48) H key
818         case 'h': case 'H': return 0x48;
819         //  (49) I key
820         case 'i': case 'I': return 0x49;
821         //  (4A) J key
822         case 'j': case 'J': return 0x4A;
823         //  (4B) K key
824         case 'k': case 'K': return 0x4B;
825         //  (4C) L key
826         case 'l': case 'L': return 0x4C;
827         //  (4D) M key
828         case 'm': case 'M': return 0x4D;
829         //  (4E) N key
830         case 'n': case 'N': return 0x4E;
831         //  (4F) O key
832         case 'o': case 'O': return 0x4F;
833         //  (50) P key
834         case 'p': case 'P': return 0x50;
835         //  (51) Q key
836         case 'q': case 'Q': return 0x51;
837         //  (52) R key
838         case 'r': case 'R': return 0x52;
839         //  (53) S key
840         case 's': case 'S': return 0x53;
841         //  (54) T key
842         case 't': case 'T': return 0x54;
843         //  (55) U key
844         case 'u': case 'U': return 0x55;
845         //  (56) V key
846         case 'v': case 'V': return 0x56;
847         //  (57) W key
848         case 'w': case 'W': return 0x57;
849         //  (58) X key
850         case 'x': case 'X': return 0x58;
851         //  (59) Y key
852         case 'y': case 'Y': return 0x59;
853         //  (5A) Z key
854         case 'z': case 'Z': return 0x5A;
855
856         // VK_LWIN (5B) Left Windows key (Microsoft Natural keyboard)
857         // VK_RWIN (5C) Right Windows key (Natural keyboard)
858         // VK_APPS (5D) Applications key (Natural keyboard)
859         // VK_SLEEP (5F) Computer Sleep key
860
861         // VK_NUMPAD0 (60) Numeric keypad 0 key
862         // VK_NUMPAD1 (61) Numeric keypad 1 key
863         // VK_NUMPAD2 (62) Numeric keypad 2 key
864         // VK_NUMPAD3 (63) Numeric keypad 3 key
865         // VK_NUMPAD4 (64) Numeric keypad 4 key
866         // VK_NUMPAD5 (65) Numeric keypad 5 key
867         // VK_NUMPAD6 (66) Numeric keypad 6 key
868         // VK_NUMPAD7 (67) Numeric keypad 7 key
869         // VK_NUMPAD8 (68) Numeric keypad 8 key
870         // VK_NUMPAD9 (69) Numeric keypad 9 key
871         // VK_MULTIPLY (6A) Multiply key
872         // VK_ADD (6B) Add key
873         // handled by key code above
874
875         // VK_SEPARATOR (6C) Separator key
876
877         // VK_SUBTRACT (6D) Subtract key
878         // VK_DECIMAL (6E) Decimal key
879         // VK_DIVIDE (6F) Divide key
880         // handled by key code above
881
882         // VK_F1 (70) F1 key
883         case NSF1FunctionKey: return 0x70;
884         // VK_F2 (71) F2 key
885         case NSF2FunctionKey: return 0x71;
886         // VK_F3 (72) F3 key
887         case NSF3FunctionKey: return 0x72;
888         // VK_F4 (73) F4 key
889         case NSF4FunctionKey: return 0x73;
890         // VK_F5 (74) F5 key
891         case NSF5FunctionKey: return 0x74;
892         // VK_F6 (75) F6 key
893         case NSF6FunctionKey: return 0x75;
894         // VK_F7 (76) F7 key
895         case NSF7FunctionKey: return 0x76;
896         // VK_F8 (77) F8 key
897         case NSF8FunctionKey: return 0x77;
898         // VK_F9 (78) F9 key
899         case NSF9FunctionKey: return 0x78;
900         // VK_F10 (79) F10 key
901         case NSF10FunctionKey: return 0x79;
902         // VK_F11 (7A) F11 key
903         case NSF11FunctionKey: return 0x7A;
904         // VK_F12 (7B) F12 key
905         case NSF12FunctionKey: return 0x7B;
906         // VK_F13 (7C) F13 key
907         case NSF13FunctionKey: return 0x7C;
908         // VK_F14 (7D) F14 key
909         case NSF14FunctionKey: return 0x7D;
910         // VK_F15 (7E) F15 key
911         case NSF15FunctionKey: return 0x7E;
912         // VK_F16 (7F) F16 key
913         case NSF16FunctionKey: return 0x7F;
914         // VK_F17 (80H) F17 key
915         case NSF17FunctionKey: return 0x80;
916         // VK_F18 (81H) F18 key
917         case NSF18FunctionKey: return 0x81;
918         // VK_F19 (82H) F19 key
919         case NSF19FunctionKey: return 0x82;
920         // VK_F20 (83H) F20 key
921         case NSF20FunctionKey: return 0x83;
922         // VK_F21 (84H) F21 key
923         case NSF21FunctionKey: return 0x84;
924         // VK_F22 (85H) F22 key
925         case NSF22FunctionKey: return 0x85;
926         // VK_F23 (86H) F23 key
927         case NSF23FunctionKey: return 0x86;
928         // VK_F24 (87H) F24 key
929         case NSF24FunctionKey: return 0x87;
930
931         // VK_NUMLOCK (90) NUM LOCK key
932
933         // VK_SCROLL (91) SCROLL LOCK key
934         case NSScrollLockFunctionKey: return 0x91;
935
936         // VK_LSHIFT (A0) Left SHIFT key
937         // VK_RSHIFT (A1) Right SHIFT key
938         // VK_LCONTROL (A2) Left CONTROL key
939         // VK_RCONTROL (A3) Right CONTROL key
940         // VK_LMENU (A4) Left MENU key
941         // VK_RMENU (A5) Right MENU key
942         // VK_BROWSER_BACK (A6) Windows 2000/XP: Browser Back key
943         // VK_BROWSER_FORWARD (A7) Windows 2000/XP: Browser Forward key
944         // VK_BROWSER_REFRESH (A8) Windows 2000/XP: Browser Refresh key
945         // VK_BROWSER_STOP (A9) Windows 2000/XP: Browser Stop key
946         // VK_BROWSER_SEARCH (AA) Windows 2000/XP: Browser Search key
947         // VK_BROWSER_FAVORITES (AB) Windows 2000/XP: Browser Favorites key
948         // VK_BROWSER_HOME (AC) Windows 2000/XP: Browser Start and Home key
949         // VK_VOLUME_MUTE (AD) Windows 2000/XP: Volume Mute key
950         // VK_VOLUME_DOWN (AE) Windows 2000/XP: Volume Down key
951         // VK_VOLUME_UP (AF) Windows 2000/XP: Volume Up key
952         // VK_MEDIA_NEXT_TRACK (B0) Windows 2000/XP: Next Track key
953         // VK_MEDIA_PREV_TRACK (B1) Windows 2000/XP: Previous Track key
954         // VK_MEDIA_STOP (B2) Windows 2000/XP: Stop Media key
955         // VK_MEDIA_PLAY_PAUSE (B3) Windows 2000/XP: Play/Pause Media key
956         // VK_LAUNCH_MAIL (B4) Windows 2000/XP: Start Mail key
957         // VK_LAUNCH_MEDIA_SELECT (B5) Windows 2000/XP: Select Media key
958         // VK_LAUNCH_APP1 (B6) Windows 2000/XP: Start Application 1 key
959         // VK_LAUNCH_APP2 (B7) Windows 2000/XP: Start Application 2 key
960
961         // VK_OEM_1 (BA) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ';:' key
962         case ';': case ':': return 0xBA;
963         // VK_OEM_PLUS (BB) Windows 2000/XP: For any country/region, the '+' key
964         case '=': case '+': return 0xBB;
965         // VK_OEM_COMMA (BC) Windows 2000/XP: For any country/region, the ',' key
966         case ',': case '<': return 0xBC;
967         // VK_OEM_MINUS (BD) Windows 2000/XP: For any country/region, the '-' key
968         case '-': case '_': return 0xBD;
969         // VK_OEM_PERIOD (BE) Windows 2000/XP: For any country/region, the '.' key
970         case '.': case '>': return 0xBE;
971         // VK_OEM_2 (BF) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '/?' key
972         case '/': case '?': return 0xBF;
973         // VK_OEM_3 (C0) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '`~' key
974         case '`': case '~': return 0xC0;
975         // VK_OEM_4 (DB) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '[{' key
976         case '[': case '{': return 0xDB;
977         // VK_OEM_5 (DC) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '\|' key
978         case '\\': case '|': return 0xDC;
979         // VK_OEM_6 (DD) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ']}' key
980         case ']': case '}': return 0xDD;
981         // VK_OEM_7 (DE) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
982         case '\'': case '"': return 0xDE;
983
984         // VK_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard.
985         // VK_OEM_102 (E2) Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
986         // VK_PROCESSKEY (E5) Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key
987         // VK_PACKET (E7) Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT,SendInput, WM_KEYDOWN, and WM_KEYUP
988         // VK_ATTN (F6) Attn key
989         // VK_CRSEL (F7) CrSel key
990         // VK_EXSEL (F8) ExSel key
991         // VK_EREOF (F9) Erase EOF key
992         // VK_PLAY (FA) Play key
993         // VK_ZOOM (FB) Zoom key
994         // VK_NONAME (FC) Reserved for future use
995         // VK_PA1 (FD) PA1 key
996         // VK_OEM_CLEAR (FE) Clear key
997     }
998
999     return 0;
1000 }
1001
1002 static inline bool isKeyUpEvent(NSEvent *event)
1003 {
1004     if ([event type] != NSFlagsChanged)
1005         return [event type] == NSKeyUp;
1006     // FIXME: This logic fails if the user presses both Shift keys at once, for example:
1007     // we treat releasing one of them as keyDown.
1008     switch ([event keyCode]) {
1009         case 54: // Right Command
1010         case 55: // Left Command
1011             return ([event modifierFlags] & NSCommandKeyMask) == 0;
1012             
1013         case 57: // Capslock
1014             return ([event modifierFlags] & NSAlphaShiftKeyMask) == 0;
1015             
1016         case 56: // Left Shift
1017         case 60: // Right Shift
1018             return ([event modifierFlags] & NSShiftKeyMask) == 0;
1019             
1020         case 58: // Left Alt
1021         case 61: // Right Alt
1022             return ([event modifierFlags] & NSAlternateKeyMask) == 0;
1023             
1024         case 59: // Left Ctrl
1025         case 62: // Right Ctrl
1026             return ([event modifierFlags] & NSControlKeyMask) == 0;
1027             
1028         case 63: // Function
1029             return ([event modifierFlags] & NSFunctionKeyMask) == 0;
1030     }
1031     return false;
1032 }
1033
1034 static inline WebEvent::Modifiers modifiersForEvent(NSEvent *event)
1035 {
1036     unsigned modifiers = 0;
1037     if ([event modifierFlags] & NSAlphaShiftKeyMask)
1038         modifiers |= WebEvent::CapsLockKey;
1039     if ([event modifierFlags] & NSShiftKeyMask)
1040         modifiers |= WebEvent::ShiftKey;
1041     if ([event modifierFlags] & NSControlKeyMask)
1042         modifiers |= WebEvent::ControlKey;
1043     if ([event modifierFlags] & NSAlternateKeyMask)
1044         modifiers |= WebEvent::AltKey;
1045     if ([event modifierFlags] & NSCommandKeyMask)
1046         modifiers |= WebEvent::MetaKey;
1047     return (WebEvent::Modifiers)modifiers;
1048 }
1049
1050 WebMouseEvent WebEventFactory::createWebMouseEvent(NSEvent *event, NSView *windowView)
1051 {
1052     NSPoint position = pointForEvent(event, windowView);
1053     NSPoint globalPosition = globalPointForEvent(event);
1054
1055     WebEvent::Type type                     = mouseEventTypeForEvent(event);
1056     WebMouseEvent::Button button            = mouseButtonForEvent(event);
1057     float deltaX                            = [event deltaX];
1058     float deltaY                            = [event deltaY];
1059     float deltaZ                            = [event deltaZ];
1060     int clickCount                          = clickCountForEvent(event);
1061     WebEvent::Modifiers modifiers           = modifiersForEvent(event);
1062     double timestamp                        = [event timestamp];
1063
1064     return WebMouseEvent(type, button, IntPoint(position), IntPoint(globalPosition), deltaX, deltaY, deltaZ, clickCount, modifiers, timestamp);
1065 }
1066
1067 WebWheelEvent WebEventFactory::createWebWheelEvent(NSEvent *event, NSView *windowView)
1068 {
1069     NSPoint position = pointForEvent(event, windowView);
1070     NSPoint globalPosition = globalPointForEvent(event);
1071
1072     WebWheelEvent::Granularity granularity  = WebWheelEvent::ScrollByPixelWheelEvent;
1073
1074     BOOL continuous;
1075     float deltaX = 0;
1076     float deltaY = 0;
1077     float wheelTicksX = 0;
1078     float wheelTicksY = 0;
1079
1080     WKGetWheelEventDeltas(event, &deltaX, &deltaY, &continuous);
1081     
1082     if (continuous) {
1083         // smooth scroll events
1084         wheelTicksX = deltaX / static_cast<float>(Scrollbar::pixelsPerLineStep());
1085         wheelTicksY = deltaY / static_cast<float>(Scrollbar::pixelsPerLineStep());
1086     } else {
1087         // plain old wheel events
1088         wheelTicksX = deltaX;
1089         wheelTicksY = deltaY;
1090         deltaX *= static_cast<float>(Scrollbar::pixelsPerLineStep());
1091         deltaY *= static_cast<float>(Scrollbar::pixelsPerLineStep());
1092     }
1093
1094     WebWheelEvent::Phase phase              = phaseForEvent(event);
1095     WebWheelEvent::Phase momentumPhase      = momentumPhaseForEvent(event);
1096     bool hasPreciseScrollingDeltas          = continuous;
1097     WebEvent::Modifiers modifiers           = modifiersForEvent(event);
1098     double timestamp                        = [event timestamp];
1099     
1100     return WebWheelEvent(WebEvent::Wheel, IntPoint(position), IntPoint(globalPosition), FloatSize(deltaX, deltaY), FloatSize(wheelTicksX, wheelTicksY), granularity, phase, momentumPhase, hasPreciseScrollingDeltas, modifiers, timestamp);
1101 }
1102
1103 WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(NSEvent *event, NSView *)
1104 {
1105     WebEvent::Type type             = isKeyUpEvent(event) ? WebEvent::KeyUp : WebEvent::KeyDown;
1106     String text                     = textFromEvent(event);
1107     String unmodifiedText           = unmodifiedTextFromEvent(event);
1108     String keyIdentifier            = keyIdentifierForKeyEvent(event);
1109     int windowsVirtualKeyCode       = windowsKeyCodeForKeyEvent(event);
1110     int nativeVirtualKeyCode        = [event keyCode];
1111     int macCharCode                 = WKGetNSEventKeyChar(event);
1112     bool autoRepeat                 = ([event type] != NSFlagsChanged) && [event isARepeat];
1113     bool isKeypad                   = isKeypadEvent(event);
1114     bool isSystemKey                = false; // SystemKey is always false on the Mac.
1115     WebEvent::Modifiers modifiers   = modifiersForEvent(event);
1116     double timestamp                = [event timestamp];
1117
1118     // Always use 13 for Enter/Return -- we don't want to use AppKit's different character for Enter.
1119     if (windowsVirtualKeyCode == VK_RETURN) {
1120         text = "\r";
1121         unmodifiedText = "\r";
1122     }
1123
1124     // AppKit sets text to "\x7F" for backspace, but the correct KeyboardEvent character code is 8.
1125     if (windowsVirtualKeyCode == VK_BACK) {
1126         text = "\x8";
1127         unmodifiedText = "\x8";
1128     }
1129
1130     // Always use 9 for Tab -- we don't want to use AppKit's different character for shift-tab.
1131     if (windowsVirtualKeyCode == VK_TAB) {
1132         text = "\x9";
1133         unmodifiedText = "\x9";
1134     }
1135
1136     return WebKeyboardEvent(type, text, unmodifiedText, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, macCharCode, autoRepeat, isKeypad, isSystemKey, modifiers, timestamp);
1137 }
1138
1139 #if ENABLE(GESTURE_EVENTS)
1140 WebGestureEvent WebEventFactory::createWebGestureEvent(NSEvent *event, NSView *windowView)
1141 {
1142     WebEvent::Type type             = gestureEventTypeForEvent(event);
1143     NSPoint position                = pointForEvent(event, windowView);
1144     NSPoint globalPosition          = globalPointForEvent(event);
1145     WebEvent::Modifiers modifiers   = modifiersForEvent(event);
1146     double timestamp                = [event timestamp];
1147
1148     return WebGestureEvent(type, IntPoint(position), IntPoint(globalPosition), modifiers, timestamp);
1149 }
1150 #endif
1151
1152 } // namespace WebKit