Follow-on fix for bug 457825. Use sheet principal for agent and user sheets. r=dbaron...
[wine-gecko.git] / content / events / src / nsDOMUIEvent.cpp
blob47765ce909027c5719376acd42de2f5ed27151b7
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
13 * License.
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.
22 * Contributor(s):
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 ***** */
40 #include "nsCOMPtr.h"
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"
50 #include "nsIFrame.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)
60 if (aEvent) {
61 mEventIsInternal = PR_FALSE;
63 else {
64 mEventIsInternal = PR_TRUE;
65 mEvent->time = PR_Now();
68 // Fill mDetail and mView according to the mEvent (widget-generated
69 // event) we've got
70 switch(mEvent->eventStructType)
72 case NS_UI_EVENT:
74 nsUIEvent *event = static_cast<nsUIEvent*>(mEvent);
75 mDetail = event->detail;
76 break;
79 case NS_SCROLLPORT_EVENT:
81 nsScrollPortEvent* scrollEvent = static_cast<nsScrollPortEvent*>(mEvent);
82 mDetail = (PRInt32)scrollEvent->orient;
83 break;
86 default:
87 mDetail = 0;
88 break;
91 mView = nsnull;
92 if (mPresContext)
94 nsCOMPtr<nsISupports> container = mPresContext->GetContainer();
95 if (container)
97 nsCOMPtr<nsIDOMWindowInternal> window = do_GetInterface(container);
98 if (window)
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() {
125 if (!mEvent ||
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));
138 nsRect offset;
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() {
146 if (!mEvent ||
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) ||
151 !mPresContext ||
152 !((nsGUIEvent*)mEvent)->widget) {
153 return mClientPoint;
156 nsPoint pt(0, 0);
157 nsIPresShell* shell = mPresContext->GetPresShell();
158 if (!shell) {
159 return pt;
161 nsIFrame* rootFrame = shell->GetRootFrame();
162 if (rootFrame)
163 pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent, rootFrame);
165 return nsPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
166 nsPresContext::AppUnitsToIntCSSPixels(pt.y));
169 NS_IMETHODIMP
170 nsDOMUIEvent::GetView(nsIDOMAbstractView** aView)
172 *aView = mView;
173 NS_IF_ADDREF(*aView);
174 return NS_OK;
177 NS_IMETHODIMP
178 nsDOMUIEvent::GetDetail(PRInt32* aDetail)
180 *aDetail = mDetail;
181 return NS_OK;
184 NS_IMETHODIMP
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);
190 mDetail = detailArg;
191 mView = viewArg;
193 return NS_OK;
196 // ---- nsDOMNSUIEvent implementation -------------------
197 nsPoint
198 nsDOMUIEvent::GetPagePoint()
200 if (mPrivateDataDuplicated) {
201 return mPagePoint;
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();
210 if (scrollframe) {
211 nsPoint pt = scrollframe->GetScrollPosition();
212 pagePoint += nsPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
213 nsPresContext::AppUnitsToIntCSSPixels(pt.y));
217 return pagePoint;
220 NS_IMETHODIMP
221 nsDOMUIEvent::GetPageX(PRInt32* aPageX)
223 NS_ENSURE_ARG_POINTER(aPageX);
224 *aPageX = GetPagePoint().x;
225 return NS_OK;
228 NS_IMETHODIMP
229 nsDOMUIEvent::GetPageY(PRInt32* aPageY)
231 NS_ENSURE_ARG_POINTER(aPageY);
232 *aPageY = GetPagePoint().y;
233 return NS_OK;
236 NS_IMETHODIMP
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.
241 *aWhich = 0;
242 return NS_OK;
245 NS_IMETHODIMP
246 nsDOMUIEvent::GetRangeParent(nsIDOMNode** aRangeParent)
248 NS_ENSURE_ARG_POINTER(aRangeParent);
249 nsIFrame* targetFrame = nsnull;
251 if (mPresContext) {
252 mPresContext->EventStateManager()->GetEventTarget(&targetFrame);
255 *aRangeParent = nsnull;
257 if (targetFrame) {
258 nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
259 targetFrame);
260 nsCOMPtr<nsIContent> parent = targetFrame->GetContentOffsetsFromPoint(pt).content;
261 if (parent) {
262 return CallQueryInterface(parent, aRangeParent);
266 return NS_OK;
269 NS_IMETHODIMP
270 nsDOMUIEvent::GetRangeOffset(PRInt32* aRangeOffset)
272 NS_ENSURE_ARG_POINTER(aRangeOffset);
273 nsIFrame* targetFrame = nsnull;
275 if (mPresContext) {
276 mPresContext->EventStateManager()->GetEventTarget(&targetFrame);
279 if (targetFrame) {
280 nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
281 targetFrame);
282 *aRangeOffset = targetFrame->GetContentOffsetsFromPoint(pt).offset;
283 return NS_OK;
285 *aRangeOffset = 0;
286 return NS_OK;
289 NS_IMETHODIMP
290 nsDOMUIEvent::GetCancelBubble(PRBool* aCancelBubble)
292 NS_ENSURE_ARG_POINTER(aCancelBubble);
293 *aCancelBubble =
294 (mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH) ? PR_TRUE : PR_FALSE;
295 return NS_OK;
298 NS_IMETHODIMP
299 nsDOMUIEvent::SetCancelBubble(PRBool aCancelBubble)
301 if (aCancelBubble) {
302 mEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
303 } else {
304 mEvent->flags &= ~NS_EVENT_FLAG_STOP_DISPATCH;
306 return NS_OK;
309 nsPoint nsDOMUIEvent::GetLayerPoint() {
310 if (!mEvent ||
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) ||
315 !mPresContext ||
316 mEventIsInternal) {
317 return mLayerPoint;
319 // XXX I'm not really sure this is correct; it's my best shot, though
320 nsIFrame* targetFrame;
321 mPresContext->EventStateManager()->GetEventTarget(&targetFrame);
322 if (!targetFrame)
323 return mLayerPoint;
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);
328 return pt;
331 NS_IMETHODIMP
332 nsDOMUIEvent::GetLayerX(PRInt32* aLayerX)
334 NS_ENSURE_ARG_POINTER(aLayerX);
335 *aLayerX = GetLayerPoint().x;
336 return NS_OK;
339 NS_IMETHODIMP
340 nsDOMUIEvent::GetLayerY(PRInt32* aLayerY)
342 NS_ENSURE_ARG_POINTER(aLayerY);
343 *aLayerY = GetLayerPoint().y;
344 return NS_OK;
347 NS_IMETHODIMP
348 nsDOMUIEvent::GetIsChar(PRBool* aIsChar)
350 switch(mEvent->eventStructType)
352 case NS_KEY_EVENT:
353 *aIsChar = ((nsKeyEvent*)mEvent)->isChar;
354 return NS_OK;
355 case NS_TEXT_EVENT:
356 *aIsChar = ((nsTextEvent*)mEvent)->isChar;
357 return NS_OK;
358 default:
359 *aIsChar = PR_FALSE;
360 return NS_OK;
364 NS_IMETHODIMP
365 nsDOMUIEvent::GetPreventDefault(PRBool* aReturn)
367 NS_ENSURE_ARG_POINTER(aReturn);
368 *aReturn = mEvent && (mEvent->flags & NS_EVENT_FLAG_NO_DEFAULT);
370 return NS_OK;
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);
379 return NS_OK;
381 *aReply = nsnull;
382 return NS_ERROR_FAILURE;
385 NS_METHOD
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;
397 return rv;
400 nsresult NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
401 nsPresContext* aPresContext,
402 nsGUIEvent *aEvent)
404 nsDOMUIEvent* it = new nsDOMUIEvent(aPresContext, aEvent);
405 if (nsnull == it) {
406 return NS_ERROR_OUT_OF_MEMORY;
409 return CallQueryInterface(it, aInstancePtrResult);