blob: c784c09e7a85e639275e8d97d3a79e243f25a003 [file] [log] [blame]
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef WebInputEvent_h
#define WebInputEvent_h
#include "../../../Platform/chromium/public/WebCommon.h"
#include "../../../Platform/chromium/public/WebRect.h"
#include "WebTouchPoint.h"
#include <string.h>
namespace WebKit {
// The classes defined in this file are intended to be used with
// WebWidget's handleInputEvent method. These event types are cross-
// platform and correspond closely to WebCore's Platform*Event classes.
//
// WARNING! These classes must remain PODs (plain old data). They are
// intended to be "serializable" by copying their raw bytes, so they must
// not contain any non-bit-copyable member variables!
//
// Furthermore, the class members need to be packed so they are aligned
// properly and don't have paddings/gaps, otherwise memory check tools
// like Valgrind will complain about uninitialized memory usage when
// transferring these classes over the wire.
#pragma pack(push, 4)
// WebInputEvent --------------------------------------------------------------
class WebInputEvent {
public:
WebInputEvent(unsigned sizeParam = sizeof(WebInputEvent))
{
memset(this, 0, sizeParam);
timeStampSeconds = 0.0;
size = sizeParam;
type = Undefined;
modifiers = 0;
}
// When we use an input method (or an input method editor), we receive
// two events for a keypress. The former event is a keydown, which
// provides a keycode, and the latter is a textinput, which provides
// a character processed by an input method. (The mapping from a
// keycode to a character code is not trivial for non-English
// keyboards.)
// To support input methods, Safari sends keydown events to WebKit for
// filtering. WebKit sends filtered keydown events back to Safari,
// which sends them to input methods.
// Unfortunately, it is hard to apply this design to Chrome because of
// our multiprocess architecture. An input method is running in a
// browser process. On the other hand, WebKit is running in a renderer
// process. So, this design results in increasing IPC messages.
// To support input methods without increasing IPC messages, Chrome
// handles keyboard events in a browser process and send asynchronous
// input events (to be translated to DOM events) to a renderer
// process.
// This design is mostly the same as the one of Windows and Mac Carbon.
// So, for what it's worth, our Linux and Mac front-ends emulate our
// Windows front-end. To emulate our Windows front-end, we can share
// our back-end code among Windows, Linux, and Mac.
// TODO(hbono): Issue 18064: remove the KeyDown type since it isn't
// used in Chrome any longer.
enum Type {
Undefined = -1,
// WebMouseEvent
MouseDown,
MouseUp,
MouseMove,
MouseEnter,
MouseLeave,
ContextMenu,
// WebMouseWheelEvent
MouseWheel,
// WebKeyboardEvent
RawKeyDown,
KeyDown,
KeyUp,
Char,
// WebGestureEvent
GestureScrollBegin,
GestureScrollEnd,
GestureScrollUpdate,
GestureScrollUpdateWithoutPropagation,
GestureFlingStart,
GestureFlingCancel,
GestureTap,
GestureTapDown,
GestureTapCancel,
GestureDoubleTap,
GestureTwoFingerTap,
GestureLongPress,
GestureLongTap,
GesturePinchBegin,
GesturePinchEnd,
GesturePinchUpdate,
// WebTouchEvent
TouchStart,
TouchMove,
TouchEnd,
TouchCancel,
};
enum Modifiers {
// modifiers for all events:
ShiftKey = 1 << 0,
ControlKey = 1 << 1,
AltKey = 1 << 2,
MetaKey = 1 << 3,
// modifiers for keyboard events:
IsKeyPad = 1 << 4,
IsAutoRepeat = 1 << 5,
// modifiers for mouse events:
LeftButtonDown = 1 << 6,
MiddleButtonDown = 1 << 7,
RightButtonDown = 1 << 8,
// Toggle modifiers for all events. Danger: these are not reflected
// into WebCore, so round-tripping from WebInputEvent to a WebCore
// event and back will not preserve these flags.
CapsLockOn = 1 << 9,
NumLockOn = 1 << 10,
// Left/right modifiers for keyboard events.
IsLeft = 1 << 11,
IsRight = 1 << 12,
// Last input event to be sent for the current vsync interval. If this
// flag is set, the sender guarantees that no more input events will be
// delivered until the next vsync and the receiver can schedule
// rendering accordingly. If it isn't set, the receiver should not make
// any assumptions about the delivery times of future input events
// w.r.t. vsync.
IsLastInputEventForCurrentVSync = 1 << 13,
};
static const int InputModifiers = ShiftKey | ControlKey | AltKey | MetaKey;
double timeStampSeconds; // Seconds since epoch.
unsigned size; // The size of this structure, for serialization.
Type type;
int modifiers;
// Returns true if the WebInputEvent |type| is a mouse event.
static bool isMouseEventType(int type)
{
return type == MouseDown
|| type == MouseUp
|| type == MouseMove
|| type == MouseEnter
|| type == MouseLeave
|| type == ContextMenu;
}
// Returns true if the WebInputEvent |type| is a keyboard event.
static bool isKeyboardEventType(int type)
{
return type == RawKeyDown
|| type == KeyDown
|| type == KeyUp
|| type == Char;
}
// Returns true if the WebInputEvent |type| is a touch event.
static bool isTouchEventType(int type)
{
return type == TouchStart
|| type == TouchMove
|| type == TouchEnd
|| type == TouchCancel;
}
// Returns true if the WebInputEvent |type| should be handled as user gesture.
static bool isUserGestureEventType(int type)
{
return isKeyboardEventType(type)
|| type == MouseDown
|| type == MouseUp
|| type == TouchStart
|| type == TouchEnd;
}
// Returns true if the WebInputEvent is a gesture event.
static bool isGestureEventType(int type)
{
return type == GestureScrollBegin
|| type == GestureScrollEnd
|| type == GestureScrollUpdate
|| type == GestureScrollUpdateWithoutPropagation
|| type == GestureFlingStart
|| type == GestureFlingCancel
|| type == GesturePinchBegin
|| type == GesturePinchEnd
|| type == GesturePinchUpdate
|| type == GestureTap
|| type == GestureTapDown
|| type == GestureTapCancel
|| type == GestureDoubleTap
|| type == GestureTwoFingerTap
|| type == GestureLongPress
|| type == GestureLongTap;
}
};
// WebKeyboardEvent -----------------------------------------------------------
class WebKeyboardEvent : public WebInputEvent {
public:
// Caps on string lengths so we can make them static arrays and keep
// them PODs.
static const size_t textLengthCap = 4;
// http://www.w3.org/TR/DOM-Level-3-Events/keyset.html lists the
// identifiers. The longest is 18 characters, so we round up to the
// next multiple of 4.
static const size_t keyIdentifierLengthCap = 20;
// |windowsKeyCode| is the Windows key code associated with this key
// event. Sometimes it's direct from the event (i.e. on Windows),
// sometimes it's via a mapping function. If you want a list, see
// WebCore/platform/chromium/KeyboardCodes* . Note that this should
// ALWAYS store the non-locational version of a keycode as this is
// what is returned by the Windows API. For example, it should
// store VK_SHIFT instead of VK_RSHIFT. The location information
// should be stored in |modifiers|.
int windowsKeyCode;
// The actual key code genenerated by the platform. The DOM spec runs
// on Windows-equivalent codes (thus |windowsKeyCode| above) but it
// doesn't hurt to have this one around.
int nativeKeyCode;
// This identifies whether this event was tagged by the system as being
// a "system key" event (see
// http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx for
// details). Other platforms don't have this concept, but it's just
// easier to leave it always false than ifdef.
// See comment at the top of the file for why an int is used here.
bool isSystemKey;
// |text| is the text generated by this keystroke. |unmodifiedText| is
// |text|, but unmodified by an concurrently-held modifiers (except
// shift). This is useful for working out shortcut keys. Linux and
// Windows guarantee one character per event. The Mac does not, but in
// reality that's all it ever gives. We're generous, and cap it a bit
// longer.
WebUChar text[textLengthCap];
WebUChar unmodifiedText[textLengthCap];
// This is a string identifying the key pressed.
char keyIdentifier[keyIdentifierLengthCap];
WebKeyboardEvent(unsigned sizeParam = sizeof(WebKeyboardEvent))
: WebInputEvent(sizeParam)
, windowsKeyCode(0)
, nativeKeyCode(0)
, isSystemKey(false)
{
memset(&text, 0, sizeof(text));
memset(&unmodifiedText, 0, sizeof(unmodifiedText));
memset(&keyIdentifier, 0, sizeof(keyIdentifier));
}
// Sets keyIdentifier based on the value of windowsKeyCode. This is
// handy for generating synthetic keyboard events.
WEBKIT_EXPORT void setKeyIdentifierFromWindowsKeyCode();
static int windowsKeyCodeWithoutLocation(int keycode);
static int locationModifiersFromWindowsKeyCode(int keycode);
};
// WebMouseEvent --------------------------------------------------------------
class WebMouseEvent : public WebInputEvent {
public:
// These values defined for WebCore::MouseButton
enum Button {
ButtonNone = -1,
ButtonLeft,
ButtonMiddle,
ButtonRight
};
Button button;
int x;
int y;
int windowX;
int windowY;
int globalX;
int globalY;
int movementX;
int movementY;
int clickCount;
WebMouseEvent(unsigned sizeParam = sizeof(WebMouseEvent))
: WebInputEvent(sizeParam)
, button(ButtonNone)
, x(0)
, y(0)
, windowX(0)
, windowY(0)
, globalX(0)
, globalY(0)
, movementX(0)
, movementY(0)
, clickCount(0)
{
}
};
// WebMouseWheelEvent ---------------------------------------------------------
class WebMouseWheelEvent : public WebMouseEvent {
public:
enum Phase {
PhaseNone = 0,
PhaseBegan = 1 << 0,
PhaseStationary = 1 << 1,
PhaseChanged = 1 << 2,
PhaseEnded = 1 << 3,
PhaseCancelled = 1 << 4,
PhaseMayBegin = 1 << 5,
};
float deltaX;
float deltaY;
float wheelTicksX;
float wheelTicksY;
float accelerationRatioX;
float accelerationRatioY;
// See comment at the top of the file for why an int is used here.
int scrollByPage;
// See comment at the top of the file for why an int is used here.
int hasPreciseScrollingDeltas;
Phase phase;
Phase momentumPhase;
WebMouseWheelEvent(unsigned sizeParam = sizeof(WebMouseWheelEvent))
: WebMouseEvent(sizeParam)
, deltaX(0.0f)
, deltaY(0.0f)
, wheelTicksX(0.0f)
, wheelTicksY(0.0f)
, accelerationRatioX(1.0f)
, accelerationRatioY(1.0f)
, scrollByPage(false)
, hasPreciseScrollingDeltas(false)
, phase(PhaseNone)
, momentumPhase(PhaseNone)
{
}
};
// WebGestureEvent --------------------------------------------------------------
class WebGestureEvent : public WebInputEvent {
public:
enum SourceDevice {
Touchpad,
Touchscreen,
};
int x;
int y;
int globalX;
int globalY;
SourceDevice sourceDevice;
union {
struct {
int tapCount;
float width;
float height;
} tap;
struct {
float width;
float height;
} tapDown;
struct {
float width;
float height;
} longPress;
struct {
float firstFingerWidth;
float firstFingerHeight;
} twoFingerTap;
struct {
float deltaX;
float deltaY;
float velocityX;
float velocityY;
} scrollUpdate;
struct {
float velocityX;
float velocityY;
} flingStart;
struct {
float scale;
} pinchUpdate;
} data;
WebGestureEvent(unsigned sizeParam = sizeof(WebGestureEvent))
: WebInputEvent(sizeParam)
, x(0)
, y(0)
, globalX(0)
, globalY(0)
{
memset(&data, 0, sizeof(data));
}
};
// WebTouchEvent --------------------------------------------------------------
class WebTouchEvent : public WebInputEvent {
public:
// Maximum number of simultaneous touches supported on
// Ash/Aura.
enum { touchesLengthCap = 12 };
unsigned touchesLength;
// List of all touches which are currently down.
WebTouchPoint touches[touchesLengthCap];
unsigned changedTouchesLength;
// List of all touches whose state has changed since the last WebTouchEvent
WebTouchPoint changedTouches[touchesLengthCap];
unsigned targetTouchesLength;
// List of all touches which are currently down and are targeting the event recipient.
WebTouchPoint targetTouches[touchesLengthCap];
WebTouchEvent(unsigned sizeParam = sizeof(WebTouchEvent))
: WebInputEvent(sizeParam)
, touchesLength(0)
, changedTouchesLength(0)
, targetTouchesLength(0)
{
}
};
#pragma pack(pop)
} // namespace WebKit
#endif