Home | History | Annotate | Download | only in gtk
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
      4  * Copyright (C) 2011 Igalia S.L.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     25  * THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "config.h"
     29 #include "WebEventFactory.h"
     30 
     31 #include "GtkVersioning.h"
     32 #include "PlatformKeyboardEvent.h"
     33 #include "Scrollbar.h"
     34 #include "WindowsKeyboardCodes.h"
     35 #include <gdk/gdk.h>
     36 #include <gdk/gdkkeysyms.h>
     37 #include <wtf/ASCIICType.h>
     38 
     39 using namespace WebCore;
     40 
     41 namespace WebKit {
     42 
     43 static inline bool isGdkKeyCodeFromKeyPad(unsigned keyval)
     44 {
     45     return keyval >= GDK_KP_Space && keyval <= GDK_KP_9;
     46 }
     47 
     48 static inline WebEvent::Modifiers modifiersForEvent(const GdkEvent* event)
     49 {
     50     unsigned modifiers = 0;
     51     GdkModifierType state;
     52 
     53     ASSERT(gdk_event_get_state(event, &state));
     54 
     55     if (state & GDK_CONTROL_MASK)
     56         modifiers |= WebEvent::ControlKey;
     57     if (state & GDK_SHIFT_MASK)
     58         modifiers |= WebEvent::ShiftKey;
     59     if (state & GDK_MOD1_MASK)
     60         modifiers |= WebEvent::AltKey;
     61     if (state & GDK_META_MASK)
     62         modifiers |= WebEvent::MetaKey;
     63 
     64     return static_cast<WebEvent::Modifiers>(modifiers);
     65 }
     66 
     67 static inline WebMouseEvent::Button buttonForEvent(GdkEvent* event)
     68 {
     69     unsigned button = 0;
     70 
     71     switch (event->type) {
     72     case GDK_MOTION_NOTIFY:
     73         button = WebMouseEvent::NoButton;
     74         if (event->motion.state & GDK_BUTTON1_MASK)
     75             button = WebMouseEvent::LeftButton;
     76         else if (event->motion.state & GDK_BUTTON2_MASK)
     77             button = WebMouseEvent::MiddleButton;
     78         else if (event->motion.state & GDK_BUTTON3_MASK)
     79             button = WebMouseEvent::RightButton;
     80         break;
     81     case GDK_BUTTON_PRESS:
     82     case GDK_2BUTTON_PRESS:
     83     case GDK_3BUTTON_PRESS:
     84     case GDK_BUTTON_RELEASE:
     85         if (event->button.button == 1)
     86             button = WebMouseEvent::LeftButton;
     87         else if (event->button.button == 2)
     88             button = WebMouseEvent::MiddleButton;
     89         else if (event->button.button == 3)
     90             button = WebMouseEvent::RightButton;
     91         break;
     92     default:
     93         ASSERT_NOT_REACHED();
     94     }
     95 
     96     return static_cast<WebMouseEvent::Button>(button);
     97 }
     98 
     99 WebMouseEvent WebEventFactory::createWebMouseEvent(GdkEvent *event, int currentClickCount)
    100 {
    101     double x, y, xRoot, yRoot;
    102     gdk_event_get_coords(event, &x, &y);
    103     gdk_event_get_root_coords(event, &xRoot, &yRoot);
    104 
    105     WebEvent::Type type = static_cast<WebEvent::Type>(0);
    106     switch (event->type) {
    107     case GDK_MOTION_NOTIFY:
    108         type = WebEvent::MouseMove;
    109         break;
    110     case GDK_BUTTON_PRESS:
    111     case GDK_2BUTTON_PRESS:
    112     case GDK_3BUTTON_PRESS:
    113         type = WebEvent::MouseDown;
    114         break;
    115     case GDK_BUTTON_RELEASE:
    116         type = WebEvent::MouseUp;
    117         break;
    118     default :
    119         ASSERT_NOT_REACHED();
    120     }
    121 
    122     return WebMouseEvent(type,
    123                          buttonForEvent(event),
    124                          IntPoint(x, y),
    125                          IntPoint(xRoot, yRoot),
    126                          0 /* deltaX */,
    127                          0 /* deltaY */,
    128                          0 /* deltaZ */,
    129                          currentClickCount,
    130                          static_cast<WebEvent::Modifiers>(0),
    131                          gdk_event_get_time(event));
    132 }
    133 
    134 WebWheelEvent WebEventFactory::createWebWheelEvent(GdkEventScroll* scrollEvent)
    135 {
    136     GdkEvent* event(reinterpret_cast<GdkEvent*>(scrollEvent));
    137     double x, y, xRoot, yRoot;
    138     gdk_event_get_coords(event, &x, &y);
    139     gdk_event_get_root_coords(event, &xRoot, &yRoot);
    140 
    141     FloatSize wheelTicks;
    142     switch (scrollEvent->direction) {
    143     case GDK_SCROLL_UP:
    144         wheelTicks = FloatSize(0, 1);
    145         break;
    146     case GDK_SCROLL_DOWN:
    147         wheelTicks = FloatSize(0, -1);
    148         break;
    149     case GDK_SCROLL_LEFT:
    150         wheelTicks = FloatSize(1, 0);
    151         break;
    152     case GDK_SCROLL_RIGHT:
    153         wheelTicks = FloatSize(-1, 0);
    154         break;
    155     default:
    156         ASSERT_NOT_REACHED();
    157     }
    158 
    159     // FIXME: [GTK] Add a setting to change the pixels per line used for scrolling
    160     // https://bugs.webkit.org/show_bug.cgi?id=54826
    161     float step = static_cast<float>(Scrollbar::pixelsPerLineStep());
    162     FloatSize delta(wheelTicks.width() * step, wheelTicks.height() * step);
    163 
    164     return WebWheelEvent(WebEvent::Wheel,
    165                          IntPoint(x, y),
    166                          IntPoint(xRoot, yRoot),
    167                          delta,
    168                          wheelTicks,
    169                          WebWheelEvent::ScrollByPixelWheelEvent,
    170                          modifiersForEvent(event),
    171                          gdk_event_get_time(event));
    172 }
    173 
    174 WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(const GdkEventKey* event)
    175 {
    176     return WebKeyboardEvent((event->type == GDK_KEY_RELEASE) ? WebEvent::KeyUp : WebEvent::KeyDown,
    177                             PlatformKeyboardEvent::singleCharacterString(event->keyval),
    178                             PlatformKeyboardEvent::singleCharacterString(event->keyval),
    179                             PlatformKeyboardEvent::keyIdentifierForGdkKeyCode(event->keyval),
    180                             PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(event->keyval),
    181                             static_cast<int>(event->keyval),
    182                             0 /* macCharCode */,
    183                             false /* isAutoRepeat */,
    184                             isGdkKeyCodeFromKeyPad(event->keyval),
    185                             false /* isSystemKey */,
    186                             modifiersForEvent(reinterpret_cast<const GdkEvent*>(event)),
    187                             gdk_event_get_time(reinterpret_cast<const GdkEvent*>(event)));
    188 }
    189 
    190 } // namespace WebKit
    191