1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Steve Clark (buster@netscape.com)
24 * Ilya Konstantinov (mozilla-code@future.shiny.co.il)
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 #include "nsDOMUIEvent.h"
42 #include "nsIPresShell.h"
43 #include "nsIInterfaceRequestorUtils.h"
44 #include "nsIDOMWindowInternal.h"
45 #include "nsIDOMNode.h"
46 #include "nsIContent.h"
47 #include "nsContentUtils.h"
48 #include "nsIPresShell.h"
49 #include "nsIEventStateManager.h"
51 #include "nsLayoutUtils.h"
52 #include "nsIScrollableFrame.h"
54 nsDOMUIEvent::nsDOMUIEvent(nsPresContext
* aPresContext
, nsGUIEvent
* aEvent
)
55 : nsDOMEvent(aPresContext
, aEvent
?
56 static_cast<nsEvent
*>(aEvent
) :
57 static_cast<nsEvent
*>(new nsUIEvent(PR_FALSE
, 0, 0)))
58 , mClientPoint(0, 0), mLayerPoint(0, 0), mPagePoint(0, 0)
61 mEventIsInternal
= PR_FALSE
;
64 mEventIsInternal
= PR_TRUE
;
65 mEvent
->time
= PR_Now();
68 // Fill mDetail and mView according to the mEvent (widget-generated
70 switch(mEvent
->eventStructType
)
74 nsUIEvent
*event
= static_cast<nsUIEvent
*>(mEvent
);
75 mDetail
= event
->detail
;
79 case NS_SCROLLPORT_EVENT
:
81 nsScrollPortEvent
* scrollEvent
= static_cast<nsScrollPortEvent
*>(mEvent
);
82 mDetail
= (PRInt32
)scrollEvent
->orient
;
94 nsCOMPtr
<nsISupports
> container
= mPresContext
->GetContainer();
97 nsCOMPtr
<nsIDOMWindowInternal
> window
= do_GetInterface(container
);
99 mView
= do_QueryInterface(window
);
104 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMUIEvent
)
106 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMUIEvent
, nsDOMEvent
)
107 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mView
)
108 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
110 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMUIEvent
, nsDOMEvent
)
111 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mView
)
112 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
114 NS_IMPL_ADDREF_INHERITED(nsDOMUIEvent
, nsDOMEvent
)
115 NS_IMPL_RELEASE_INHERITED(nsDOMUIEvent
, nsDOMEvent
)
117 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMUIEvent
)
118 NS_INTERFACE_MAP_ENTRY(nsIDOMUIEvent
)
119 NS_INTERFACE_MAP_ENTRY(nsIDOMNSUIEvent
)
120 NS_INTERFACE_MAP_ENTRY(nsIPrivateCompositionEvent
)
121 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(UIEvent
)
122 NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent
)
124 nsPoint
nsDOMUIEvent::GetScreenPoint() {
126 (mEvent
->eventStructType
!= NS_MOUSE_EVENT
&&
127 mEvent
->eventStructType
!= NS_POPUP_EVENT
&&
128 mEvent
->eventStructType
!= NS_MOUSE_SCROLL_EVENT
&&
129 mEvent
->eventStructType
!= NS_DRAG_EVENT
)) {
130 return nsPoint(0, 0);
133 if (!((nsGUIEvent
*)mEvent
)->widget
) {
134 return mEvent
->refPoint
;
137 nsRect
bounds(mEvent
->refPoint
, nsSize(1, 1));
139 ((nsGUIEvent
*)mEvent
)->widget
->WidgetToScreen ( bounds
, offset
);
140 PRInt32 factor
= mPresContext
->DeviceContext()->UnscaledAppUnitsPerDevPixel();
141 return nsPoint(nsPresContext::AppUnitsToIntCSSPixels(offset
.x
* factor
),
142 nsPresContext::AppUnitsToIntCSSPixels(offset
.y
* factor
));
145 nsPoint
nsDOMUIEvent::GetClientPoint() {
147 (mEvent
->eventStructType
!= NS_MOUSE_EVENT
&&
148 mEvent
->eventStructType
!= NS_POPUP_EVENT
&&
149 mEvent
->eventStructType
!= NS_MOUSE_SCROLL_EVENT
&&
150 mEvent
->eventStructType
!= NS_DRAG_EVENT
) ||
152 !((nsGUIEvent
*)mEvent
)->widget
) {
157 nsIPresShell
* shell
= mPresContext
->GetPresShell();
161 nsIFrame
* rootFrame
= shell
->GetRootFrame();
163 pt
= nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent
, rootFrame
);
165 return nsPoint(nsPresContext::AppUnitsToIntCSSPixels(pt
.x
),
166 nsPresContext::AppUnitsToIntCSSPixels(pt
.y
));
170 nsDOMUIEvent::GetView(nsIDOMAbstractView
** aView
)
173 NS_IF_ADDREF(*aView
);
178 nsDOMUIEvent::GetDetail(PRInt32
* aDetail
)
185 nsDOMUIEvent::InitUIEvent(const nsAString
& typeArg
, PRBool canBubbleArg
, PRBool cancelableArg
, nsIDOMAbstractView
*viewArg
, PRInt32 detailArg
)
187 nsresult rv
= nsDOMEvent::InitEvent(typeArg
, canBubbleArg
, cancelableArg
);
188 NS_ENSURE_SUCCESS(rv
, rv
);
196 // ---- nsDOMNSUIEvent implementation -------------------
198 nsDOMUIEvent::GetPagePoint()
200 if (mPrivateDataDuplicated
) {
204 nsPoint pagePoint
= GetClientPoint();
206 // If there is some scrolling, add scroll info to client point.
207 if (mPresContext
&& mPresContext
->GetPresShell()) {
208 nsIPresShell
* shell
= mPresContext
->GetPresShell();
209 nsIScrollableFrame
* scrollframe
= shell
->GetRootScrollFrameAsScrollable();
211 nsPoint pt
= scrollframe
->GetScrollPosition();
212 pagePoint
+= nsPoint(nsPresContext::AppUnitsToIntCSSPixels(pt
.x
),
213 nsPresContext::AppUnitsToIntCSSPixels(pt
.y
));
221 nsDOMUIEvent::GetPageX(PRInt32
* aPageX
)
223 NS_ENSURE_ARG_POINTER(aPageX
);
224 *aPageX
= GetPagePoint().x
;
229 nsDOMUIEvent::GetPageY(PRInt32
* aPageY
)
231 NS_ENSURE_ARG_POINTER(aPageY
);
232 *aPageY
= GetPagePoint().y
;
237 nsDOMUIEvent::GetWhich(PRUint32
* aWhich
)
239 NS_ENSURE_ARG_POINTER(aWhich
);
240 // Usually we never reach here, as this is reimplemented for mouse and keyboard events.
246 nsDOMUIEvent::GetRangeParent(nsIDOMNode
** aRangeParent
)
248 NS_ENSURE_ARG_POINTER(aRangeParent
);
249 nsIFrame
* targetFrame
= nsnull
;
252 mPresContext
->EventStateManager()->GetEventTarget(&targetFrame
);
255 *aRangeParent
= nsnull
;
258 nsPoint pt
= nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent
,
260 nsCOMPtr
<nsIContent
> parent
= targetFrame
->GetContentOffsetsFromPoint(pt
).content
;
262 return CallQueryInterface(parent
, aRangeParent
);
270 nsDOMUIEvent::GetRangeOffset(PRInt32
* aRangeOffset
)
272 NS_ENSURE_ARG_POINTER(aRangeOffset
);
273 nsIFrame
* targetFrame
= nsnull
;
276 mPresContext
->EventStateManager()->GetEventTarget(&targetFrame
);
280 nsPoint pt
= nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent
,
282 *aRangeOffset
= targetFrame
->GetContentOffsetsFromPoint(pt
).offset
;
290 nsDOMUIEvent::GetCancelBubble(PRBool
* aCancelBubble
)
292 NS_ENSURE_ARG_POINTER(aCancelBubble
);
294 (mEvent
->flags
& NS_EVENT_FLAG_STOP_DISPATCH
) ? PR_TRUE
: PR_FALSE
;
299 nsDOMUIEvent::SetCancelBubble(PRBool aCancelBubble
)
302 mEvent
->flags
|= NS_EVENT_FLAG_STOP_DISPATCH
;
304 mEvent
->flags
&= ~NS_EVENT_FLAG_STOP_DISPATCH
;
309 nsPoint
nsDOMUIEvent::GetLayerPoint() {
311 (mEvent
->eventStructType
!= NS_MOUSE_EVENT
&&
312 mEvent
->eventStructType
!= NS_POPUP_EVENT
&&
313 mEvent
->eventStructType
!= NS_MOUSE_SCROLL_EVENT
&&
314 mEvent
->eventStructType
!= NS_DRAG_EVENT
) ||
319 // XXX I'm not really sure this is correct; it's my best shot, though
320 nsIFrame
* targetFrame
;
321 mPresContext
->EventStateManager()->GetEventTarget(&targetFrame
);
324 nsIFrame
* layer
= nsLayoutUtils::GetClosestLayer(targetFrame
);
325 nsPoint
pt(nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent
, layer
));
326 pt
.x
= nsPresContext::AppUnitsToIntCSSPixels(pt
.x
);
327 pt
.y
= nsPresContext::AppUnitsToIntCSSPixels(pt
.y
);
332 nsDOMUIEvent::GetLayerX(PRInt32
* aLayerX
)
334 NS_ENSURE_ARG_POINTER(aLayerX
);
335 *aLayerX
= GetLayerPoint().x
;
340 nsDOMUIEvent::GetLayerY(PRInt32
* aLayerY
)
342 NS_ENSURE_ARG_POINTER(aLayerY
);
343 *aLayerY
= GetLayerPoint().y
;
348 nsDOMUIEvent::GetIsChar(PRBool
* aIsChar
)
350 switch(mEvent
->eventStructType
)
353 *aIsChar
= ((nsKeyEvent
*)mEvent
)->isChar
;
356 *aIsChar
= ((nsTextEvent
*)mEvent
)->isChar
;
365 nsDOMUIEvent::GetPreventDefault(PRBool
* aReturn
)
367 NS_ENSURE_ARG_POINTER(aReturn
);
368 *aReturn
= mEvent
&& (mEvent
->flags
& NS_EVENT_FLAG_NO_DEFAULT
);
373 NS_METHOD
nsDOMUIEvent::GetCompositionReply(nsTextEventReply
** aReply
)
375 if((mEvent
->message
== NS_COMPOSITION_START
) ||
376 (mEvent
->message
== NS_COMPOSITION_QUERY
))
378 *aReply
= &(static_cast<nsCompositionEvent
*>(mEvent
)->theReply
);
382 return NS_ERROR_FAILURE
;
386 nsDOMUIEvent::DuplicatePrivateData()
388 mClientPoint
= GetClientPoint();
389 mLayerPoint
= GetLayerPoint();
390 mPagePoint
= GetPagePoint();
391 // GetScreenPoint converts mEvent->refPoint to right coordinates.
392 nsPoint screenPoint
= GetScreenPoint();
393 nsresult rv
= nsDOMEvent::DuplicatePrivateData();
394 if (NS_SUCCEEDED(rv
)) {
395 mEvent
->refPoint
= screenPoint
;
400 nsresult
NS_NewDOMUIEvent(nsIDOMEvent
** aInstancePtrResult
,
401 nsPresContext
* aPresContext
,
404 nsDOMUIEvent
* it
= new nsDOMUIEvent(aPresContext
, aEvent
);
406 return NS_ERROR_OUT_OF_MEMORY
;
409 return CallQueryInterface(it
, aInstancePtrResult
);