Home | History | Annotate | Download | only in qt
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     24  * THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "WebPage.h"
     29 
     30 #include "WebEvent.h"
     31 #include <WebCore/FocusController.h>
     32 #include <WebCore/Frame.h>
     33 #include <WebCore/KeyboardEvent.h>
     34 #include <WebCore/Page.h>
     35 #include <WebCore/PlatformKeyboardEvent.h>
     36 #include <WebCore/Settings.h>
     37 
     38 #ifndef VK_UNKNOWN
     39 #define VK_UNKNOWN 0
     40 #define VK_BACK 0x08
     41 #define VK_TAB 0x09
     42 #define VK_CLEAR 0x0C
     43 #define VK_RETURN 0x0D
     44 #define VK_SHIFT 0x10
     45 #define VK_CONTROL 0x11 // CTRL key
     46 #define VK_MENU 0x12 // ALT key
     47 #define VK_PAUSE 0x13 // PAUSE key
     48 #define VK_CAPITAL 0x14 // CAPS LOCK key
     49 #define VK_KANA 0x15 // Input Method Editor (IME) Kana mode
     50 #define VK_HANGUL 0x15 // IME Hangul mode
     51 #define VK_JUNJA 0x17 // IME Junja mode
     52 #define VK_FINAL 0x18 // IME final mode
     53 #define VK_HANJA 0x19 // IME Hanja mode
     54 #define VK_KANJI 0x19 // IME Kanji mode
     55 #define VK_ESCAPE 0x1B // ESC key
     56 #define VK_CONVERT 0x1C // IME convert
     57 #define VK_NONCONVERT 0x1D // IME nonconvert
     58 #define VK_ACCEPT 0x1E // IME accept
     59 #define VK_MODECHANGE 0x1F // IME mode change request
     60 #define VK_SPACE 0x20 // SPACE key
     61 #define VK_PRIOR 0x21 // PAGE UP key
     62 #define VK_NEXT 0x22 // PAGE DOWN key
     63 #define VK_END 0x23 // END key
     64 #define VK_HOME 0x24 // HOME key
     65 #define VK_LEFT 0x25 // LEFT ARROW key
     66 #define VK_UP 0x26 // UP ARROW key
     67 #define VK_RIGHT 0x27 // RIGHT ARROW key
     68 #define VK_DOWN 0x28 // DOWN ARROW key
     69 #define VK_SELECT 0x29 // SELECT key
     70 #define VK_PRINT 0x2A // PRINT key
     71 #define VK_EXECUTE 0x2B // EXECUTE key
     72 #define VK_SNAPSHOT 0x2C // PRINT SCREEN key
     73 #define VK_INSERT 0x2D // INS key
     74 #define VK_DELETE 0x2E // DEL key
     75 #define VK_HELP 0x2F // HELP key
     76 // Windows 2000/XP: For any country/region, the '.' key
     77 #define VK_OEM_PERIOD 0xBE
     78 #endif
     79 
     80 using namespace WebCore;
     81 
     82 namespace WebKit {
     83 
     84 void WebPage::platformInitialize()
     85 {
     86 }
     87 
     88 void WebPage::platformPreferencesDidChange(const WebPreferencesStore&)
     89 {
     90 }
     91 
     92 static const unsigned CtrlKey = 1 << 0;
     93 static const unsigned AltKey = 1 << 1;
     94 static const unsigned ShiftKey = 1 << 2;
     95 
     96 struct KeyDownEntry {
     97     unsigned virtualKey;
     98     unsigned modifiers;
     99     const char* name;
    100 };
    101 
    102 struct KeyPressEntry {
    103     unsigned charCode;
    104     unsigned modifiers;
    105     const char* name;
    106 };
    107 
    108 static const KeyDownEntry keyDownEntries[] = {
    109     { VK_LEFT,   0,                  "MoveLeft"                                    },
    110     { VK_LEFT,   ShiftKey,           "MoveLeftAndModifySelection"                  },
    111     { VK_LEFT,   CtrlKey,            "MoveWordLeft"                                },
    112     { VK_LEFT,   CtrlKey | ShiftKey, "MoveWordLeftAndModifySelection"              },
    113     { VK_RIGHT,  0,                  "MoveRight"                                   },
    114     { VK_RIGHT,  ShiftKey,           "MoveRightAndModifySelection"                 },
    115     { VK_RIGHT,  CtrlKey,            "MoveWordRight"                               },
    116     { VK_RIGHT,  CtrlKey | ShiftKey, "MoveWordRightAndModifySelection"             },
    117     { VK_UP,     0,                  "MoveUp"                                      },
    118     { VK_UP,     ShiftKey,           "MoveUpAndModifySelection"                    },
    119     { VK_PRIOR,  ShiftKey,           "MovePageUpAndModifySelection"                },
    120     { VK_DOWN,   0,                  "MoveDown"                                    },
    121     { VK_DOWN,   ShiftKey,           "MoveDownAndModifySelection"                  },
    122     { VK_NEXT,   ShiftKey,           "MovePageDownAndModifySelection"              },
    123     { VK_PRIOR,  0,                  "MovePageUp"                                  },
    124     { VK_NEXT,   0,                  "MovePageDown"                                },
    125     { VK_HOME,   0,                  "MoveToBeginningOfLine"                       },
    126     { VK_HOME,   ShiftKey,           "MoveToBeginningOfLineAndModifySelection"     },
    127     { VK_HOME,   CtrlKey,            "MoveToBeginningOfDocument"                   },
    128     { VK_HOME,   CtrlKey | ShiftKey, "MoveToBeginningOfDocumentAndModifySelection" },
    129 
    130     { VK_END,    0,                  "MoveToEndOfLine"                             },
    131     { VK_END,    ShiftKey,           "MoveToEndOfLineAndModifySelection"           },
    132     { VK_END,    CtrlKey,            "MoveToEndOfDocument"                         },
    133     { VK_END,    CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection"       },
    134 
    135     { VK_BACK,   0,                  "DeleteBackward"                              },
    136     { VK_BACK,   ShiftKey,           "DeleteBackward"                              },
    137     { VK_DELETE, 0,                  "DeleteForward"                               },
    138     { VK_BACK,   CtrlKey,            "DeleteWordBackward"                          },
    139     { VK_DELETE, CtrlKey,            "DeleteWordForward"                           },
    140 
    141     { 'B',       CtrlKey,            "ToggleBold"                                  },
    142     { 'I',       CtrlKey,            "ToggleItalic"                                },
    143 
    144     { VK_ESCAPE, 0,                  "Cancel"                                      },
    145     { VK_OEM_PERIOD, CtrlKey,        "Cancel"                                      },
    146     { VK_TAB,    0,                  "InsertTab"                                   },
    147     { VK_TAB,    ShiftKey,           "InsertBacktab"                               },
    148     { VK_RETURN, 0,                  "InsertNewline"                               },
    149     { VK_RETURN, CtrlKey,            "InsertNewline"                               },
    150     { VK_RETURN, AltKey,             "InsertNewline"                               },
    151     { VK_RETURN, ShiftKey,           "InsertNewline"                               },
    152     { VK_RETURN, AltKey | ShiftKey,  "InsertNewline"                               },
    153 
    154     // It's not quite clear whether clipboard shortcuts and Undo/Redo should be handled
    155     // in the application or in WebKit. We chose WebKit.
    156     { 'C',       CtrlKey,            "Copy"                                        },
    157     { 'V',       CtrlKey,            "Paste"                                       },
    158     { 'X',       CtrlKey,            "Cut"                                         },
    159     { 'A',       CtrlKey,            "SelectAll"                                   },
    160     { VK_INSERT, CtrlKey,            "Copy"                                        },
    161     { VK_DELETE, ShiftKey,           "Cut"                                         },
    162     { VK_INSERT, ShiftKey,           "Paste"                                       },
    163     { 'Z',       CtrlKey,            "Undo"                                        },
    164     { 'Z',       CtrlKey | ShiftKey, "Redo"                                        },
    165 };
    166 
    167 static const KeyPressEntry keyPressEntries[] = {
    168     { '\t',   0,                  "InsertTab"                                   },
    169     { '\t',   ShiftKey,           "InsertBacktab"                               },
    170     { '\r',   0,                  "InsertNewline"                               },
    171     { '\r',   CtrlKey,            "InsertNewline"                               },
    172     { '\r',   AltKey,             "InsertNewline"                               },
    173     { '\r',   ShiftKey,           "InsertNewline"                               },
    174     { '\r',   AltKey | ShiftKey,  "InsertNewline"                               },
    175 };
    176 
    177 const char* WebPage::interpretKeyEvent(const KeyboardEvent* evt)
    178 {
    179     ASSERT(evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
    180 
    181     static HashMap<int, const char*>* keyDownCommandsMap = 0;
    182     static HashMap<int, const char*>* keyPressCommandsMap = 0;
    183 
    184     if (!keyDownCommandsMap) {
    185         keyDownCommandsMap = new HashMap<int, const char*>;
    186         keyPressCommandsMap = new HashMap<int, const char*>;
    187 
    188         for (unsigned i = 0; i < (sizeof(keyDownEntries) / sizeof(keyDownEntries[0])); i++)
    189             keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
    190 
    191         for (unsigned i = 0; i < (sizeof(keyPressEntries) / sizeof(keyPressEntries[0])); i++)
    192             keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
    193     }
    194 
    195     unsigned modifiers = 0;
    196     if (evt->shiftKey())
    197         modifiers |= ShiftKey;
    198     if (evt->altKey())
    199         modifiers |= AltKey;
    200     if (evt->ctrlKey())
    201         modifiers |= CtrlKey;
    202 
    203     if (evt->type() == eventNames().keydownEvent) {
    204         int mapKey = modifiers << 16 | evt->keyEvent()->windowsVirtualKeyCode();
    205         return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
    206     }
    207 
    208     int mapKey = modifiers << 16 | evt->charCode();
    209     return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
    210 }
    211 
    212 static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
    213 {
    214     page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
    215 }
    216 
    217 static inline void logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
    218 {
    219     page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity);
    220 }
    221 
    222 bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent)
    223 {
    224     if (keyboardEvent.type() != WebEvent::KeyDown && keyboardEvent.type() != WebEvent::RawKeyDown)
    225         return false;
    226 
    227     switch (keyboardEvent.windowsVirtualKeyCode()) {
    228     case VK_BACK:
    229         if (keyboardEvent.shiftKey())
    230             m_page->goForward();
    231         else
    232             m_page->goBack();
    233         break;
    234     case VK_SPACE:
    235         logicalScroll(m_page.get(), keyboardEvent.shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward, ScrollByPage);
    236         break;
    237     case VK_LEFT:
    238         scroll(m_page.get(), ScrollLeft, ScrollByLine);
    239         break;
    240     case VK_RIGHT:
    241         scroll(m_page.get(), ScrollRight, ScrollByLine);
    242         break;
    243     case VK_UP:
    244         scroll(m_page.get(), ScrollUp, ScrollByLine);
    245         break;
    246     case VK_DOWN:
    247         scroll(m_page.get(), ScrollDown, ScrollByLine);
    248         break;
    249     case VK_HOME:
    250         logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument);
    251         break;
    252     case VK_END:
    253         logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument);
    254         break;
    255     case VK_PRIOR:
    256         logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage);
    257         break;
    258     case VK_NEXT:
    259         logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage);
    260         break;
    261     default:
    262         return false;
    263     }
    264 
    265     return true;
    266 }
    267 
    268 bool WebPage::platformHasLocalDataForURL(const WebCore::KURL&)
    269 {
    270     // FIXME: Implement
    271     return false;
    272 }
    273 
    274 String WebPage::cachedResponseMIMETypeForURL(const WebCore::KURL&)
    275 {
    276     // FIXME: Implement
    277     return String();
    278 }
    279 
    280 bool WebPage::platformCanHandleRequest(const WebCore::ResourceRequest&)
    281 {
    282     // FIXME: Implement
    283     return true;
    284 }
    285 
    286 } // namespace WebKit
    287