Bug 412486 - widget/event-detection support for multi-touch trackpad gestures, r=smaug,josh, sr=roc

This commit is contained in:
tdyas@zecador.org 2008-10-23 23:15:20 +03:00
parent e50b75ec73
commit 479713d218
19 changed files with 809 additions and 4 deletions

View File

@ -479,7 +479,16 @@ nsContentUtils::InitializeEventTable() {
{ &nsGkAtoms::ondurationchange, { NS_DURATIONCHANGE, EventNameType_HTML }},
{ &nsGkAtoms::onvolumechange, { NS_VOLUMECHANGE, EventNameType_HTML }},
#endif //MOZ_MEDIA
{ &nsGkAtoms::onMozAfterPaint, { NS_AFTERPAINT, EventNameType_None }}
{ &nsGkAtoms::onMozAfterPaint, { NS_AFTERPAINT, EventNameType_None }},
// Simple gesture events
{ &nsGkAtoms::onMozSwipeGesture, { NS_SIMPLE_GESTURE_SWIPE, EventNameType_None } },
{ &nsGkAtoms::onMozMagnifyGestureStart, { NS_SIMPLE_GESTURE_MAGNIFY_START, EventNameType_None } },
{ &nsGkAtoms::onMozMagnifyGestureUpdate, { NS_SIMPLE_GESTURE_MAGNIFY_UPDATE, EventNameType_None } },
{ &nsGkAtoms::onMozMagnifyGesture, { NS_SIMPLE_GESTURE_MAGNIFY, EventNameType_None } },
{ &nsGkAtoms::onMozRotateGestureStart, { NS_SIMPLE_GESTURE_ROTATE_START, EventNameType_None } },
{ &nsGkAtoms::onMozRotateGestureUpdate, { NS_SIMPLE_GESTURE_ROTATE_UPDATE, EventNameType_None } },
{ &nsGkAtoms::onMozRotateGesture, { NS_SIMPLE_GESTURE_ROTATE, EventNameType_None } }
};
sEventTable = new nsDataHashtable<nsISupportsHashKey, EventNameMapping>;

View File

@ -1457,6 +1457,16 @@ GK_ATOM(seconds, "seconds")
GK_ATOM(secondsFromDateTime, "seconds-from-dateTime")
#endif
// Simple gestures support
GK_ATOM(onMozSwipeGesture, "onMozSwipeGesture")
GK_ATOM(onMozMagnifyGestureStart, "onMozMagnifyGestureStart")
GK_ATOM(onMozMagnifyGestureUpdate, "onMozMagnifyGestureUpdate")
GK_ATOM(onMozMagnifyGesture, "onMozMagnifyGesture")
GK_ATOM(onMozRotateGestureStart, "onMozRotateGestureStart")
GK_ATOM(onMozRotateGestureUpdate, "onMozRotateGestureUpdate")
GK_ATOM(onMozRotateGesture, "onMozRotateGesture")
//---------------------------------------------------------------------------
// Special atoms
//---------------------------------------------------------------------------

View File

@ -112,4 +112,6 @@ nsresult
NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
nsresult
NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsNotifyPaintEvent* aEvent);
nsresult
NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsSimpleGestureEvent* aEvent);
#endif // nsIPrivateDOMEvent_h__

View File

@ -95,6 +95,7 @@ CPPSRCS = \
nsDOMProgressEvent.cpp \
nsDOMDataTransfer.cpp \
nsDOMNotifyPaintEvent.cpp \
nsDOMSimpleGestureEvent.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.

View File

@ -83,7 +83,14 @@ static const char* const sEventNames[] = {
"canshowcurrentframe", "canplay", "canplaythrough", "ratechange",
"durationchange", "volumechange",
#endif // MOZ_MEDIA
"MozAfterPaint"
"MozAfterPaint",
"MozSwipeGesture",
"MozMagnifyGestureStart",
"MozMagnifyGestureUpdate",
"MozMagnifyGesture",
"MozRotateGestureStart",
"MozRotateGestureUpdate",
"MozRotateGesture"
};
static char *sPopupAllowedEvents;
@ -650,6 +657,22 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
if (atom == nsGkAtoms::onMozAfterPaint)
mEvent->message = NS_AFTERPAINT;
}
else if (mEvent->eventStructType == NS_SIMPLE_GESTURE_EVENT) {
if (atom == nsGkAtoms::onMozSwipeGesture)
mEvent->message = NS_SIMPLE_GESTURE_SWIPE;
else if (atom == nsGkAtoms::onMozMagnifyGestureStart)
mEvent->message = NS_SIMPLE_GESTURE_MAGNIFY_START;
else if (atom == nsGkAtoms::onMozMagnifyGestureUpdate)
mEvent->message = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
else if (atom == nsGkAtoms::onMozMagnifyGesture)
mEvent->message = NS_SIMPLE_GESTURE_MAGNIFY;
else if (atom == nsGkAtoms::onMozRotateGestureStart)
mEvent->message = NS_SIMPLE_GESTURE_ROTATE_START;
else if (atom == nsGkAtoms::onMozRotateGestureUpdate)
mEvent->message = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
else if (atom == nsGkAtoms::onMozRotateGesture)
mEvent->message = NS_SIMPLE_GESTURE_ROTATE;
}
if (mEvent->message == NS_USER_DEFINED_EVENT)
mEvent->userType = atom;
@ -972,6 +995,22 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
event->sameDocRegion, event->crossDocRegion);
break;
}
case NS_SIMPLE_GESTURE_EVENT:
{
nsSimpleGestureEvent* oldSimpleGestureEvent = static_cast<nsSimpleGestureEvent*>(mEvent);
nsSimpleGestureEvent* simpleGestureEvent =
new nsSimpleGestureEvent(PR_FALSE, msg, nsnull, 0, 0.0);
NS_ENSURE_TRUE(simpleGestureEvent, NS_ERROR_OUT_OF_MEMORY);
isInputEvent = PR_TRUE;
simpleGestureEvent->direction = oldSimpleGestureEvent->direction;
simpleGestureEvent->delta = oldSimpleGestureEvent->delta;
simpleGestureEvent->isAlt = oldSimpleGestureEvent->isAlt;
simpleGestureEvent->isControl = oldSimpleGestureEvent->isControl;
simpleGestureEvent->isShift = oldSimpleGestureEvent->isShift;
simpleGestureEvent->isMeta = oldSimpleGestureEvent->isMeta;
newEvent = simpleGestureEvent;
break;
}
default:
{
NS_WARNING("Unknown event type!!!");
@ -1471,6 +1510,20 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
#endif
case NS_AFTERPAINT:
return sEventNames[eDOMEvents_afterpaint];
case NS_SIMPLE_GESTURE_SWIPE:
return sEventNames[eDOMEvents_MozSwipeGesture];
case NS_SIMPLE_GESTURE_MAGNIFY_START:
return sEventNames[eDOMEvents_MozMagnifyGestureStart];
case NS_SIMPLE_GESTURE_MAGNIFY_UPDATE:
return sEventNames[eDOMEvents_MozMagnifyGestureUpdate];
case NS_SIMPLE_GESTURE_MAGNIFY:
return sEventNames[eDOMEvents_MozMagnifyGesture];
case NS_SIMPLE_GESTURE_ROTATE_START:
return sEventNames[eDOMEvents_MozRotateGestureStart];
case NS_SIMPLE_GESTURE_ROTATE_UPDATE:
return sEventNames[eDOMEvents_MozRotateGestureUpdate];
case NS_SIMPLE_GESTURE_ROTATE:
return sEventNames[eDOMEvents_MozRotateGesture];
default:
break;
}

View File

@ -161,7 +161,14 @@ public:
eDOMEvents_durationchange,
eDOMEvents_volumechange,
#endif
eDOMEvents_afterpaint
eDOMEvents_afterpaint,
eDOMEvents_MozSwipeGesture,
eDOMEvents_MozMagnifyGestureStart,
eDOMEvents_MozMagnifyGestureUpdate,
eDOMEvents_MozMagnifyGesture,
eDOMEvents_MozRotateGestureStart,
eDOMEvents_MozRotateGestureUpdate,
eDOMEvents_MozRotateGesture
};
nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent);

View File

@ -0,0 +1,153 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Thomas K. Dyas <tdyas@zecador.org>.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsDOMSimpleGestureEvent.h"
#include "nsGUIEvent.h"
#include "nsContentUtils.h"
nsDOMSimpleGestureEvent::nsDOMSimpleGestureEvent(nsPresContext* aPresContext, nsSimpleGestureEvent* aEvent)
: nsDOMUIEvent(aPresContext, aEvent ? aEvent : new nsSimpleGestureEvent(PR_FALSE, 0, nsnull, 0, 0.0))
{
NS_ASSERTION(mEvent->eventStructType == NS_SIMPLE_GESTURE_EVENT, "event type mismatch");
if (aEvent) {
mEventIsInternal = PR_FALSE;
} else {
mEventIsInternal = PR_TRUE;
mEvent->time = PR_Now();
}
}
nsDOMSimpleGestureEvent::~nsDOMSimpleGestureEvent()
{
if (mEventIsInternal) {
delete static_cast<nsSimpleGestureEvent*>(mEvent);
mEvent = nsnull;
}
}
NS_IMPL_ADDREF_INHERITED(nsDOMSimpleGestureEvent, nsDOMUIEvent)
NS_IMPL_RELEASE_INHERITED(nsDOMSimpleGestureEvent, nsDOMUIEvent)
NS_INTERFACE_MAP_BEGIN(nsDOMSimpleGestureEvent)
NS_INTERFACE_MAP_ENTRY(nsIDOMSimpleGestureEvent)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SimpleGestureEvent)
NS_INTERFACE_MAP_END_INHERITING(nsDOMUIEvent)
/* readonly attribute unsigned long direction; */
NS_IMETHODIMP
nsDOMSimpleGestureEvent::GetDirection(PRUint32 *aDirection)
{
NS_ENSURE_ARG_POINTER(aDirection);
*aDirection = static_cast<nsSimpleGestureEvent*>(mEvent)->direction;
return NS_OK;
}
/* readonly attribute float delta; */
NS_IMETHODIMP
nsDOMSimpleGestureEvent::GetDelta(PRFloat64 *aDelta)
{
NS_ENSURE_ARG_POINTER(aDelta);
*aDelta = static_cast<nsSimpleGestureEvent*>(mEvent)->delta;
return NS_OK;
}
/* readonly attribute boolean altKey; */
NS_IMETHODIMP
nsDOMSimpleGestureEvent::GetAltKey(PRBool* aIsDown)
{
NS_ENSURE_ARG_POINTER(aIsDown);
*aIsDown = static_cast<nsInputEvent*>(mEvent)->isAlt;
return NS_OK;
}
/* readonly attribute boolean ctrlKey; */
NS_IMETHODIMP
nsDOMSimpleGestureEvent::GetCtrlKey(PRBool* aIsDown)
{
NS_ENSURE_ARG_POINTER(aIsDown);
*aIsDown = static_cast<nsInputEvent*>(mEvent)->isControl;
return NS_OK;
}
/* readonly attribute boolean shiftKey; */
NS_IMETHODIMP
nsDOMSimpleGestureEvent::GetShiftKey(PRBool* aIsDown)
{
NS_ENSURE_ARG_POINTER(aIsDown);
*aIsDown = static_cast<nsInputEvent*>(mEvent)->isShift;
return NS_OK;
}
/* readonly attribute boolean metaKey; */
NS_IMETHODIMP
nsDOMSimpleGestureEvent::GetMetaKey(PRBool* aIsDown)
{
NS_ENSURE_ARG_POINTER(aIsDown);
*aIsDown = static_cast<nsInputEvent*>(mEvent)->isMeta;
return NS_OK;
}
NS_IMETHODIMP
nsDOMSimpleGestureEvent::InitSimpleGestureEvent(const nsAString & typeArg, PRBool canBubbleArg, PRBool cancelableArg, nsIDOMAbstractView *viewArg, PRInt32 detailArg, PRUint32 directionArg, PRFloat64 deltaArg, PRBool altKeyArg, PRBool ctrlKeyArg, PRBool shiftKeyArg, PRBool metaKeyArg)
{
nsresult rv = nsDOMUIEvent::InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg);
NS_ENSURE_SUCCESS(rv, rv);
nsSimpleGestureEvent* simpleGestureEvent = static_cast<nsSimpleGestureEvent*>(mEvent);
simpleGestureEvent->direction = directionArg;
simpleGestureEvent->delta = deltaArg;
simpleGestureEvent->isAlt = altKeyArg;
simpleGestureEvent->isControl = ctrlKeyArg;
simpleGestureEvent->isShift = shiftKeyArg;
simpleGestureEvent->isMeta = metaKeyArg;
return NS_OK;
}
nsresult NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsSimpleGestureEvent *aEvent)
{
nsDOMSimpleGestureEvent *it = new nsDOMSimpleGestureEvent(aPresContext, aEvent);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return CallQueryInterface(it, aInstancePtrResult);
}

View File

@ -0,0 +1,60 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Thomas K. Dyas <tdyas@zecador.org>.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsDOMSimpleGestureEvent_h__
#define nsDOMSimpleGestureEvent_h__
#include "nsIDOMSimpleGestureEvent.h"
#include "nsDOMUIEvent.h"
class nsPresContext;
class nsDOMSimpleGestureEvent : public nsIDOMSimpleGestureEvent,
public nsDOMUIEvent
{
public:
nsDOMSimpleGestureEvent(nsPresContext*, nsSimpleGestureEvent*);
virtual ~nsDOMSimpleGestureEvent();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMSIMPLEGESTUREEVENT
// Forward to base class
NS_FORWARD_TO_NSDOMUIEVENT
};
#endif

View File

@ -649,6 +649,9 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
return NS_NewDOMNotifyPaintEvent(aDOMEvent, aPresContext,
static_cast<nsNotifyPaintEvent*>
(aEvent));
case NS_SIMPLE_GESTURE_EVENT:
return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext,
static_cast<nsSimpleGestureEvent*>(aEvent));
}
// For all other types of events, create a vanilla event object.
@ -707,6 +710,8 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
return NS_NewDOMProgressEvent(aDOMEvent, aPresContext, nsnull);
if (aEventType.LowerCaseEqualsLiteral("notifypaintevent"))
return NS_NewDOMNotifyPaintEvent(aDOMEvent, aPresContext, nsnull);
if (aEventType.LowerCaseEqualsLiteral("simplegestureevent"))
return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext, nsnull);
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}

View File

@ -47,7 +47,7 @@
interface nsIDOMElement;
[scriptable, uuid(9a1ff4e0-5e31-46af-b393-2cbab8093442)]
[scriptable, uuid(3fe733aa-823b-443a-9945-b02f973ab439)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -240,4 +240,24 @@ interface nsIDOMWindowUtils : nsISupports {
*/
void processUpdates();
/** Synthesize a simple gesture event for a window. The event types
* supported are: MozSwipeGesture, MozMagnifyGestureStart,
* MozMagnifyGestureUpdate, MozMagnifyGesture,
* MozRotateGestureStart, MozRotateGestureUpdate, and
* MozRotateGesture.
*
* Cannot be accessed from unprivileged context (not
* content-accessible) Will throw a DOM security error if called
* without UniversalXPConnect privileges.
*
* @param aType event type
* @param aDirection direction, using constants defined in nsIDOMSimpleGestureEvent
* @param aDelta amount of magnification or rotation for magnify and rotation events
* @param aModifiers modifiers pressed, using constants defined in nsIDOMNSEvent
*/
void sendSimpleGestureEvent(in AString aType,
in unsigned long aDirection,
in double aDelta,
in long aModifiers);
};

View File

@ -76,6 +76,7 @@ XPIDLSRCS = \
nsIDOMCommandEvent.idl \
nsIDOMMessageEvent.idl \
nsIDOMNotifyPaintEvent.idl \
nsIDOMSimpleGestureEvent.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,141 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Thomas K. Dyas <tdyas@zecador.org>.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMUIEvent.idl"
/**
* The nsIDOMSimpleGestureEvent interface is the datatype for all
* Mozila-specific simple gesture events in the Document Object Model.
*
* The following events are generated:
*
* MozSwipeGesture - Generated when the user swipes their fingers
* across the input device.
*
* MozMagnifyGestureStart - Generated when the user begins the magnify
* ("pinch") gesture. The "delta" value represents the initial
* movement.
*
* MozMagnifyGestureUpdate - Generated periodically while the user is
* continuing the magnify ("pinch") gesture. The "delta" value
* represents the movement since the last MozMagnifyGestureStart or
* MozMagnifyGestureUpdate event.
*
* MozMagnifyGesture - Generated when the user has completed the
* magnify ("pinch") gesture. If you only want to receive a single
* event when the magnify gesture is complete, you only need to hook
* this event and can safely ignore the MozMagnifyGestureStart and the
* MozMagnifyGestureUpdate events. The "delta" value is the cumulative
* amount represented by the user's gesture.
*
* MozRotateGestureStart - Generated when the user begins the rotation
* gesture. The "delta" value represents the initial rotation.
*
* MozRotateGestureUpdate - Generated periodically while the user is
* continuing the rotation gesture. The "delta" value represents the
* rotation since the last MozRotateGestureStart or
* MozRotateGestureUpdate event.
*
* MozRotateGesture - Generated when the user has completed the
* rotation gesture. If you only want to receive a single event when
* the rotation gesture is complete, you only need to hook this event
* and can safely ignore the MozRotateGestureStart and the
* MozRotateGestureUpdate events. The "delta" value is the cumulative
* amount of rotation represented by the user's gesture.
*/
[scriptable, uuid(20AB8E74-BF9B-4D1D-8A18-B5EE0F3C0A36)]
interface nsIDOMSimpleGestureEvent : nsIDOMUIEvent
{
/* Direction constants */
const unsigned long DIRECTION_UP = 1;
const unsigned long DIRECTION_DOWN = 2;
const unsigned long DIRECTION_LEFT = 4;
const unsigned long DIRECTION_RIGHT = 8;
/* Direction of a gesture. Diagonals are indicated by OR'ing the
* applicable constants together.
*
* Swipes gestures may occur in any direction.
*
* Magnify gestures do not have a direction.
*
* Rotation gestures will be either DIRECTION_LEFT or
* DIRECTION_RIGHT (i.e., counter-clockwise and clockwise).
*/
readonly attribute unsigned long direction;
/* Delta value for magnify and rotate gestures.
*
* For rotation, the value is in degrees and is positive for
* clockwise rotation and negative for counterclockwise
* rotation. The "direction" attribute also denotes the direction of
* the rotation: clockwise is DIRECTION_RIGHT and counterclockwise
* is DIRECTION_LEFT.
*
* For magnification, the value will be positive for a "zoom in"
* (i.e, increased magnification) and negative for a "zoom out"
* (i.e., decreased magnification). The particular units
* represented by the "delta" are currently implementation specific.
*
* XXX - The units for measuring magnification are currently
* unspecified because the units used by Mac OS X are currently
* undocumented. The values are typically in the range of 0.0 to
* 100.0, but it is only safe currently to rely on the delta being
* positive or negative.
*/
readonly attribute double delta;
/* Modifier keys that may have been pressed during the gesture. */
readonly attribute boolean altKey;
readonly attribute boolean ctrlKey;
readonly attribute boolean shiftKey;
readonly attribute boolean metaKey;
void initSimpleGestureEvent(in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg,
in nsIDOMAbstractView viewArg,
in long detailArg,
in unsigned long directionArg,
in double deltaArg,
in boolean altKeyArg,
in boolean ctrlKeyArg,
in boolean shiftKeyArg,
in boolean metaKeyArg);
};

View File

@ -452,6 +452,8 @@ enum nsDOMClassInfoID {
eDOMClassInfo_NotifyPaintEvent_id,
eDOMClassInfo_SimpleGestureEvent_id,
// This one better be the last one in this list
eDOMClassInfoIDCount
};

View File

@ -465,6 +465,9 @@
#include "nsDOMFile.h"
#include "nsIDOMFileException.h"
// Simple gestures include
#include "nsIDOMSimpleGestureEvent.h"
static NS_DEFINE_CID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
@ -1293,6 +1296,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(NotifyPaintEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(SimpleGestureEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
};
// Objects that shuld be constructable through |new Name();|
@ -3531,6 +3537,11 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(SimpleGestureEvent, nsIDOMSimpleGestureEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMSimpleGestureEvent)
DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
#ifdef NS_DEBUG
{
PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);

View File

@ -493,3 +493,48 @@ nsDOMWindowUtils::ProcessUpdates()
batch.EndUpdateViewBatch(NS_VMREFRESH_IMMEDIATE);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType,
PRUint32 aDirection,
PRFloat64 aDelta,
PRInt32 aModifiers)
{
PRBool hasCap = PR_FALSE;
if (NS_FAILED(nsContentUtils::GetSecurityManager()->IsCapabilityEnabled("UniversalXPConnect", &hasCap))
|| !hasCap)
return NS_ERROR_DOM_SECURITY_ERR;
// get the widget to send the event to
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
PRInt32 msg;
if (aType.EqualsLiteral("MozSwipeGesture"))
msg = NS_SIMPLE_GESTURE_SWIPE;
else if (aType.EqualsLiteral("MozMagnifyGestureStart"))
msg = NS_SIMPLE_GESTURE_MAGNIFY_START;
else if (aType.EqualsLiteral("MozMagnifyGestureUpdate"))
msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
else if (aType.EqualsLiteral("MozMagnifyGesture"))
msg = NS_SIMPLE_GESTURE_MAGNIFY;
else if (aType.EqualsLiteral("MozRotateGestureStart"))
msg = NS_SIMPLE_GESTURE_ROTATE_START;
else if (aType.EqualsLiteral("MozRotateGestureUpdate"))
msg = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
else if (aType.EqualsLiteral("MozRotateGesture"))
msg = NS_SIMPLE_GESTURE_ROTATE;
else
return NS_ERROR_FAILURE;
nsSimpleGestureEvent event(PR_TRUE, msg, widget, aDirection, aDelta);
event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? PR_TRUE : PR_FALSE;
event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? PR_TRUE : PR_FALSE;
event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? PR_TRUE : PR_FALSE;
event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? PR_TRUE : PR_FALSE;
event.time = PR_IntervalNow();
nsEventStatus status;
return widget->DispatchEvent(&event, status);
}

View File

@ -76,6 +76,7 @@ class nsMouseScrollEvent;
class nsReconversionEvent;
class nsTooltipEvent;
class nsMenuEvent;
class nsSimpleGestureEvent;
struct nsTextEventReply;

View File

@ -22,6 +22,7 @@
* Contributor(s):
* Makoto Kato <m_kato@ga2.so-net.ne.jp>
* Dean Tessman <dean_tessman@hotmail.com>
* Thomas K. Dyas <tdyas@zecador.org> (simple gestures support)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -103,6 +104,7 @@ class nsHashKey;
#endif // MOZ_MEDIA
#define NS_DRAG_EVENT 35
#define NS_NOTIFYPAINT_EVENT 36
#define NS_SIMPLE_GESTURE_EVENT 37
// These flags are sort of a mess. They're sort of shared between event
// listener flags and event flags, but only some of them. You've been
@ -382,6 +384,16 @@ class nsHashKey;
#define NS_NOTIFYPAINT_START 3400
#define NS_AFTERPAINT (NS_NOTIFYPAINT_START)
// Simple gesture events
#define NS_SIMPLE_GESTURE_EVENT_START 3500
#define NS_SIMPLE_GESTURE_SWIPE (NS_SIMPLE_GESTURE_EVENT_START)
#define NS_SIMPLE_GESTURE_MAGNIFY_START (NS_SIMPLE_GESTURE_EVENT_START+1)
#define NS_SIMPLE_GESTURE_MAGNIFY_UPDATE (NS_SIMPLE_GESTURE_EVENT_START+2)
#define NS_SIMPLE_GESTURE_MAGNIFY (NS_SIMPLE_GESTURE_EVENT_START+3)
#define NS_SIMPLE_GESTURE_ROTATE_START (NS_SIMPLE_GESTURE_EVENT_START+4)
#define NS_SIMPLE_GESTURE_ROTATE_UPDATE (NS_SIMPLE_GESTURE_EVENT_START+5)
#define NS_SIMPLE_GESTURE_ROTATE (NS_SIMPLE_GESTURE_EVENT_START+6)
/**
* Return status for event processors, nsEventStatus, is defined in
* nsEvent.h.
@ -1120,6 +1132,23 @@ public:
nsCOMPtr<nsIDOMEvent> sourceEvent;
};
/**
* Simple gesture event
*/
class nsSimpleGestureEvent : public nsInputEvent
{
public:
nsSimpleGestureEvent(PRBool isTrusted, PRUint32 msg, nsIWidget* w,
PRUint32 directionArg, PRFloat64 deltaArg)
: nsInputEvent(isTrusted, msg, w, NS_SIMPLE_GESTURE_EVENT),
direction(directionArg), delta(deltaArg)
{
}
PRUint32 direction; // See nsIDOMSimpleGestureEvent for values
PRFloat64 delta; // Delta for magnify and rotate events
};
/**
* Event status for D&D Event
*/

View File

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Thomas K. Dyas <tdyas@zecador.org> (simple gestures support)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -182,6 +183,29 @@ enum {
// Cocoa TSM documents (those created and managed by the NSTSMInputContext
// class) -- for some reason TSMProcessRawKeyEvent() doesn't work with them.
TSMDocumentID mPluginTSMDoc;
// Simple gestures support
//
// mGestureState is used to detect when Cocoa has called both
// magnifyWithEvent and rotateWithEvent within the same
// beginGestureWithEvent and endGestureWithEvent sequence. We
// discard the spurious gesture event so as not to confuse Gecko.
//
// mCumulativeMagnification keeps track of the total amount of
// magnification peformed during a magnify gesture so that we can
// send that value with the final MozMagnifyGesture event.
//
// mCumulativeRotation keeps track of the total amount of rotation
// performed during a rotate gesture so we can send that value with
// the final MozRotateGesture event.
enum {
eGestureState_None,
eGestureState_StartGesture,
eGestureState_MagnifyGesture,
eGestureState_RotateGesture
} mGestureState;
float mCumulativeMagnification;
float mCumulativeRotation;
}
// these are sent to the first responder when the window key status changes
@ -196,6 +220,22 @@ enum {
- (void)sendFocusEvent:(PRUint32)eventType;
- (void) processPluginKeyEvent:(EventRef)aKeyEvent;
// Simple gestures support
//
// XXX - The swipeWithEvent, beginGestureWithEvent, magnifyWithEvent,
// rotateWithEvent, and endGestureWithEvent methods are part of a
// PRIVATE interface exported by nsResponder and reverse-engineering
// was necessary to obtain the methods' prototypes. Thus, Apple may
// change the interface in the future without notice.
//
// The prototypes were obtained from the following link:
// http://cocoadex.com/2008/02/nsevent-modifications-swipe-ro.html
- (void)swipeWithEvent:(NSEvent *)anEvent;
- (void)beginGestureWithEvent:(NSEvent *)anEvent;
- (void)magnifyWithEvent:(NSEvent *)anEvent;
- (void)rotateWithEvent:(NSEvent *)anEvent;
- (void)endGestureWithEvent:(NSEvent *)anEvent;
@end

View File

@ -25,6 +25,7 @@
* Håkan Waara <hwaara@gmail.com>
* Stuart Morgan <stuart.morgan@alumni.case.edu>
* Mats Palmgren <mats.palmgren@bredband.net>
* Thomas K. Dyas <tdyas@zecador.org> (simple gestures support)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -72,6 +73,8 @@
#include "nsCocoaUtils.h"
#include "nsMenuBarX.h"
#include "nsIDOMSimpleGestureEvent.h"
#include "gfxContext.h"
#include "gfxQuartzSurface.h"
@ -2358,6 +2361,10 @@ NSEvent* gLastDragEvent = nil;
mDragService = nsnull;
mPluginTSMDoc = nil;
mGestureState = eGestureState_None;
mCumulativeMagnification = 0.0;
mCumulativeRotation = 0.0;
}
// register for things we'll take from other applications
@ -3235,6 +3242,214 @@ static const PRInt32 sShadowInvalidationInterval = 100;
}
/*
* XXX - The swipeWithEvent, beginGestureWithEvent, magnifyWithEvent,
* rotateWithEvent, and endGestureWithEvent methods are part of a
* PRIVATE interface exported by nsResponder and reverse-engineering
* was necessary to obtain the methods' prototypes. Thus, Apple may
* change the interface in the future without notice.
*
* The prototypes were obtained from the following link:
* http://cocoadex.com/2008/02/nsevent-modifications-swipe-ro.html
*/
- (void)swipeWithEvent:(NSEvent *)anEvent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (!anEvent || !mGeckoChild)
return;
nsAutoRetainCocoaObject kungFuDeathGrip(self);
float deltaX = [anEvent deltaX]; // left=1.0, right=-1.0
float deltaY = [anEvent deltaY]; // up=1.0, down=-1.0
// Setup the "swipe" event.
nsSimpleGestureEvent geckoEvent(PR_TRUE, NS_SIMPLE_GESTURE_SWIPE, mGeckoChild, 0, 0.0);
[self convertGenericCocoaEvent:anEvent toGeckoEvent:&geckoEvent];
// Record the left/right direction.
if (deltaX > 0.0)
geckoEvent.direction |= nsIDOMSimpleGestureEvent::DIRECTION_LEFT;
else if (deltaX < 0.0)
geckoEvent.direction |= nsIDOMSimpleGestureEvent::DIRECTION_RIGHT;
// Record the up/down direction.
if (deltaY > 0.0)
geckoEvent.direction |= nsIDOMSimpleGestureEvent::DIRECTION_UP;
else if (deltaY < 0.0)
geckoEvent.direction |= nsIDOMSimpleGestureEvent::DIRECTION_DOWN;
// Send the event.
mGeckoChild->DispatchWindowEvent(geckoEvent);
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (void)beginGestureWithEvent:(NSEvent *)anEvent
{
NS_ASSERTION(mGestureState == eGestureState_None, "mGestureState should be eGestureState_None");
if (!anEvent)
return;
mGestureState = eGestureState_StartGesture;
mCumulativeMagnification = 0;
mCumulativeRotation = 0.0;
}
- (void)magnifyWithEvent:(NSEvent *)anEvent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (!anEvent || !mGeckoChild)
return;
nsAutoRetainCocoaObject kungFuDeathGrip(self);
float deltaZ = [anEvent deltaZ];
PRUint32 msg;
switch (mGestureState) {
case eGestureState_StartGesture:
msg = NS_SIMPLE_GESTURE_MAGNIFY_START;
mGestureState = eGestureState_MagnifyGesture;
break;
case eGestureState_MagnifyGesture:
msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
break;
case eGestureState_None:
case eGestureState_RotateGesture:
default:
return;
}
// Setup the event.
nsSimpleGestureEvent geckoEvent(PR_TRUE, msg, mGeckoChild, 0, deltaZ);
[self convertGenericCocoaEvent:anEvent toGeckoEvent:&geckoEvent];
// Send the event.
mGeckoChild->DispatchWindowEvent(geckoEvent);
// Keep track of the cumulative magnification for the final "magnify" event.
mCumulativeMagnification += deltaZ;
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (void)rotateWithEvent:(NSEvent *)anEvent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (!anEvent || !mGeckoChild)
return;
nsAutoRetainCocoaObject kungFuDeathGrip(self);
float rotation = [anEvent rotation];
PRUint32 msg;
switch (mGestureState) {
case eGestureState_StartGesture:
msg = NS_SIMPLE_GESTURE_ROTATE_START;
mGestureState = eGestureState_RotateGesture;
break;
case eGestureState_RotateGesture:
msg = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
break;
case eGestureState_None:
case eGestureState_MagnifyGesture:
default:
return;
}
// Setup the event.
nsSimpleGestureEvent geckoEvent(PR_TRUE, msg, mGeckoChild, 0, 0.0);
[self convertGenericCocoaEvent:anEvent toGeckoEvent:&geckoEvent];
geckoEvent.delta = -rotation;
if (rotation > 0.0) {
geckoEvent.direction = nsIDOMSimpleGestureEvent::DIRECTION_LEFT;
} else {
geckoEvent.direction = nsIDOMSimpleGestureEvent::DIRECTION_RIGHT;
}
// Send the event.
mGeckoChild->DispatchWindowEvent(geckoEvent);
// Keep track of the cumulative rotation for the final "rotate" event.
mCumulativeRotation += rotation;
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (void)endGestureWithEvent:(NSEvent *)anEvent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (!anEvent || !mGeckoChild) {
// Clear the gestures state if we cannot send an event.
mGestureState = eGestureState_None;
mCumulativeMagnification = 0.0;
mCumulativeRotation = 0.0;
return;
}
nsAutoRetainCocoaObject kungFuDeathGrip(self);
switch (mGestureState) {
case eGestureState_MagnifyGesture:
{
// Setup the "magnify" event.
nsSimpleGestureEvent geckoEvent(PR_TRUE, NS_SIMPLE_GESTURE_MAGNIFY,
mGeckoChild, 0, mCumulativeMagnification);
[self convertGenericCocoaEvent:anEvent toGeckoEvent:&geckoEvent];
// Send the event.
mGeckoChild->DispatchWindowEvent(geckoEvent);
}
break;
case eGestureState_RotateGesture:
{
// Setup the "rotate" event.
nsSimpleGestureEvent geckoEvent(PR_TRUE, NS_SIMPLE_GESTURE_ROTATE, mGeckoChild, 0, 0.0);
[self convertGenericCocoaEvent:anEvent toGeckoEvent:&geckoEvent];
geckoEvent.delta = -mCumulativeRotation;
if (mCumulativeRotation > 0.0) {
geckoEvent.direction = nsIDOMSimpleGestureEvent::DIRECTION_LEFT;
} else {
geckoEvent.direction = nsIDOMSimpleGestureEvent::DIRECTION_RIGHT;
}
// Send the event.
mGeckoChild->DispatchWindowEvent(geckoEvent);
}
break;
case eGestureState_None:
case eGestureState_StartGesture:
default:
break;
}
// Clear the gestures state.
mGestureState = eGestureState_None;
mCumulativeMagnification = 0.0;
mCumulativeRotation = 0.0;
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (void)mouseDown:(NSEvent*)theEvent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;