2001-11-06 15:35:24 +00:00
|
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
2004-08-25 23:02:50 +00:00
|
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
2001-11-06 15:35:24 +00:00
|
|
|
|
*
|
2004-08-25 23:02:50 +00:00
|
|
|
|
* The contents of this file are subject to the Mozilla Public License
|
2001-11-06 15:35:24 +00:00
|
|
|
|
* 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
|
2004-08-25 23:02:50 +00:00
|
|
|
|
* http://www.mozilla.org/MPL/
|
2001-11-06 15:35:24 +00:00
|
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
|
* Netscape Communications Corporation.
|
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
|
* 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
|
2004-08-25 23:02:50 +00:00
|
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
2001-11-06 15:35:24 +00:00
|
|
|
|
* 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
|
2004-08-25 23:02:50 +00:00
|
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
2001-11-06 15:35:24 +00:00
|
|
|
|
*
|
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
|
|
#include "nsChildView.h"
|
|
|
|
|
#include "nsIFontMetrics.h"
|
|
|
|
|
#include "nsIDeviceContext.h"
|
|
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
|
#include "nsToolkit.h"
|
|
|
|
|
#include "nsIEnumerator.h"
|
|
|
|
|
#include "prmem.h"
|
2002-12-13 08:43:18 +00:00
|
|
|
|
#include "nsCRT.h"
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
#include <Appearance.h>
|
|
|
|
|
#include <Timer.h>
|
|
|
|
|
#include <Icons.h>
|
|
|
|
|
#include <Errors.h>
|
|
|
|
|
|
|
|
|
|
#include "nsplugindefs.h"
|
|
|
|
|
#include "nsMacResources.h"
|
2003-06-17 22:54:50 +00:00
|
|
|
|
#include "nsIRegion.h"
|
2001-11-06 15:35:24 +00:00
|
|
|
|
#include "nsIRollupListener.h"
|
|
|
|
|
#include "nsIEventSink.h"
|
2003-03-13 20:37:32 +00:00
|
|
|
|
#include "nsIScrollableView.h"
|
2004-09-20 12:51:31 +00:00
|
|
|
|
#include "nsIInterfaceRequestor.h"
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
#include "nsCarbonHelpers.h"
|
|
|
|
|
#include "nsGfxUtils.h"
|
|
|
|
|
|
|
|
|
|
#if PINK_PROFILING
|
|
|
|
|
#include "profilerutils.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-04-27 00:19:49 +00:00
|
|
|
|
#include <unistd.h>
|
2004-04-29 03:14:21 +00:00
|
|
|
|
#include "nsCursorManager.h"
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
2004-05-07 01:16:14 +00:00
|
|
|
|
#define NSAppKitVersionNumber10_2 663
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
@interface ChildView(Private)
|
|
|
|
|
|
|
|
|
|
// sends gecko an ime composition event
|
|
|
|
|
- (nsRect) sendCompositionEvent:(PRInt32)aEventType;
|
|
|
|
|
|
|
|
|
|
// sends gecko an ime text event
|
|
|
|
|
- (void) sendTextEvent:(PRUnichar*) aBuffer
|
|
|
|
|
attributedString:(NSAttributedString*) aString
|
|
|
|
|
selectedRange:(NSRange)selRange
|
|
|
|
|
markedRange:(NSRange)markRange
|
|
|
|
|
doCommit:(BOOL)doCommit;
|
|
|
|
|
|
|
|
|
|
// sets up our view, attaching it to its owning gecko view
|
|
|
|
|
- (id) initWithGeckoChild:(nsChildView*)child eventSink:(nsIEventSink*)sink;
|
|
|
|
|
|
|
|
|
|
// convert from one event system to the other for event dispatching
|
|
|
|
|
- (void) convert:(NSEvent*)inEvent message:(PRInt32)inMsg toGeckoEvent:(nsInputEvent*)outGeckoEvent;
|
|
|
|
|
|
|
|
|
|
// create a gecko key event out of a cocoa event
|
|
|
|
|
- (void) convert:(NSEvent*)aKeyEvent message:(PRUint32)aMessage
|
|
|
|
|
isChar:(PRBool*)outIsChar
|
|
|
|
|
toGeckoEvent:(nsKeyEvent*)outGeckoEvent;
|
|
|
|
|
- (void) convert:(NSPoint)inPoint message:(PRInt32)inMsg
|
|
|
|
|
modifiers:(unsigned int)inMods toGeckoEvent:(nsInputEvent*)outGeckoEvent;
|
|
|
|
|
|
|
|
|
|
- (NSMenu*)getContextMenu;
|
|
|
|
|
|
|
|
|
|
- (void)setIsPluginView:(BOOL)aIsPlugin;
|
|
|
|
|
- (BOOL)getIsPluginView;
|
|
|
|
|
|
|
|
|
|
- (BOOL)childViewHasPlugin;
|
|
|
|
|
|
2004-02-18 16:18:38 +00:00
|
|
|
|
#if USE_CLICK_HOLD_CONTEXTMENU
|
2004-01-15 19:01:49 +00:00
|
|
|
|
// called on a timer two seconds after a mouse down to see if we should display
|
|
|
|
|
// a context menu (click-hold)
|
|
|
|
|
- (void)clickHoldCallback:(id)inEvent;
|
2004-02-18 16:18:38 +00:00
|
|
|
|
#endif
|
2004-01-15 19:01:49 +00:00
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
////////////////////////////////////////////////////
|
|
|
|
|
nsIRollupListener * gRollupListener = nsnull;
|
|
|
|
|
nsIWidget * gRollupWidget = nsnull;
|
|
|
|
|
|
|
|
|
|
// Since we only want a single notification pending for the app we'll declare
|
|
|
|
|
// these static
|
|
|
|
|
static NMRec gNMRec;
|
|
|
|
|
static Boolean gNotificationInstalled = false;
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
//#define PAINT_DEBUGGING // flash areas as they are painted
|
|
|
|
|
//#define INVALIDATE_DEBUGGING // flash areas as they are invalidated
|
|
|
|
|
|
|
|
|
|
#if defined(INVALIDATE_DEBUGGING) || defined(PAINT_DEBUGGING)
|
|
|
|
|
static void blinkRect(Rect* r);
|
|
|
|
|
static void blinkRgn(RgnHandle rgn);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Convenience routines to go from a gecko rect to cocoa NSRects and back
|
|
|
|
|
//
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
static inline void
|
2001-11-06 15:35:24 +00:00
|
|
|
|
ConvertGeckoToCocoaRect ( const nsRect & inGeckoRect, NSRect & outCocoaRect )
|
|
|
|
|
{
|
|
|
|
|
outCocoaRect.origin.x = inGeckoRect.x;
|
|
|
|
|
outCocoaRect.origin.y = inGeckoRect.y;
|
|
|
|
|
outCocoaRect.size.width = inGeckoRect.width;
|
|
|
|
|
outCocoaRect.size.height = inGeckoRect.height;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
static inline void
|
2001-11-06 15:35:24 +00:00
|
|
|
|
ConvertCocoaToGeckoRect ( const NSRect & inCocoaRect, nsRect & outGeckoRect )
|
|
|
|
|
{
|
|
|
|
|
outGeckoRect.x = NS_STATIC_CAST(nscoord, inCocoaRect.origin.x);
|
|
|
|
|
outGeckoRect.y = NS_STATIC_CAST(nscoord, inCocoaRect.origin.y);
|
|
|
|
|
outGeckoRect.width = NS_STATIC_CAST(nscoord, inCocoaRect.size.width);
|
|
|
|
|
outGeckoRect.height = NS_STATIC_CAST(nscoord, inCocoaRect.size.height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
static inline void
|
2001-11-06 15:35:24 +00:00
|
|
|
|
ConvertGeckoRectToMacRect(const nsRect& aRect, Rect& outMacRect)
|
|
|
|
|
{
|
|
|
|
|
outMacRect.left = aRect.x;
|
|
|
|
|
outMacRect.top = aRect.y;
|
|
|
|
|
outMacRect.right = aRect.x + aRect.width;
|
|
|
|
|
outMacRect.bottom = aRect.y + aRect.height;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
static PRUint32 underlineAttributeToTextRangeType(PRUint32 aUnderlineStyle)
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_IME
|
|
|
|
|
NSLog(@"****in underlineAttributeToTextRangeType = %d", aUnderlineStyle);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// For more info on the underline attribute, please see:
|
|
|
|
|
// http://developer.apple.com/techpubs/macosx/Cocoa/TasksAndConcepts/ProgrammingTopics/AttributedStrings/Tasks/AccessingAttrs.html
|
|
|
|
|
// We are not clear where the define for value 2 is right now.
|
|
|
|
|
// To see this value in japanese ime, type 'aaaaaaaaa' and hit space to make the
|
|
|
|
|
// ime send you some part of text in 1 (NSSingleUnderlineStyle) and some part in 2.
|
|
|
|
|
// ftang will ask apple for more details
|
|
|
|
|
//
|
|
|
|
|
// it probably means show 1-pixel thickness underline vs 2-pixel thickness
|
|
|
|
|
|
2004-01-29 19:42:13 +00:00
|
|
|
|
return aUnderlineStyle == 1 ? NS_TEXTRANGE_CONVERTEDTEXT : NS_TEXTRANGE_SELECTEDCONVERTEDTEXT;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PRUint32 countRanges(NSAttributedString *aString)
|
|
|
|
|
{
|
|
|
|
|
// Iterate through aString for the NSUnderlineStyleAttributeName and count the
|
|
|
|
|
// different segments adjusting limitRange as we go.
|
|
|
|
|
PRUint32 count = 0;
|
|
|
|
|
NSRange effectiveRange;
|
|
|
|
|
NSRange limitRange = NSMakeRange(0, [aString length]);
|
|
|
|
|
while (limitRange.length > 0) {
|
|
|
|
|
[aString attribute:NSUnderlineStyleAttributeName
|
|
|
|
|
atIndex:limitRange.location
|
|
|
|
|
longestEffectiveRange:&effectiveRange
|
|
|
|
|
inRange:limitRange];
|
|
|
|
|
limitRange = NSMakeRange(NSMaxRange(effectiveRange),
|
|
|
|
|
NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-23 17:59:53 +00:00
|
|
|
|
static void convertAttributeToGeckoRange(NSAttributedString *aString, NSRange markRange, NSRange selRange, PRUint32 inCount, nsTextRange* aRanges)
|
2002-12-13 08:43:18 +00:00
|
|
|
|
{
|
|
|
|
|
// Convert the Cocoa range into the nsTextRange Array used in Gecko.
|
|
|
|
|
// Iterate through the attributed string and map the underline attribute to Gecko IME textrange attributes.
|
|
|
|
|
// We may need to change the code here if we change the implementation of validAttributesForMarkedText.
|
|
|
|
|
PRUint32 i = 0;
|
|
|
|
|
NSRange effectiveRange;
|
|
|
|
|
NSRange limitRange = NSMakeRange(0, [aString length]);
|
|
|
|
|
while ((limitRange.length > 0) && (i < inCount)) {
|
|
|
|
|
id attributeValue = [aString attribute:NSUnderlineStyleAttributeName
|
|
|
|
|
atIndex:limitRange.location
|
|
|
|
|
longestEffectiveRange:&effectiveRange
|
|
|
|
|
inRange:limitRange];
|
|
|
|
|
aRanges[i].mStartOffset = effectiveRange.location;
|
|
|
|
|
aRanges[i].mEndOffset = NSMaxRange(effectiveRange);
|
|
|
|
|
aRanges[i].mRangeType = underlineAttributeToTextRangeType([attributeValue intValue]);
|
|
|
|
|
limitRange = NSMakeRange(NSMaxRange(effectiveRange),
|
|
|
|
|
NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
|
|
|
|
|
i++;
|
|
|
|
|
}
|
2004-12-23 17:59:53 +00:00
|
|
|
|
// Get current caret position.
|
|
|
|
|
// Caret is indicator of insertion point, so mEndOffset = 0.
|
|
|
|
|
aRanges[i].mStartOffset = selRange.location + selRange.length;
|
|
|
|
|
aRanges[i].mEndOffset = 0;
|
|
|
|
|
aRanges[i].mRangeType = NS_TEXTRANGE_CARETPOSITION;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-12-23 17:59:53 +00:00
|
|
|
|
static void fillTextRangeInTextEvent(nsTextEvent *aTextEvent, NSAttributedString* aString, NSRange markRange, NSRange selRange)
|
2002-12-13 08:43:18 +00:00
|
|
|
|
{
|
2004-12-23 17:59:53 +00:00
|
|
|
|
// Count the number of segments in the attributed string and add one more count for sending current caret position to Gecko.
|
|
|
|
|
// Allocate the right size of nsTextRange and draw caret at right position.
|
|
|
|
|
// Convert the attributed string into an array of nsTextRange and get current caret position by calling above functions.
|
|
|
|
|
PRUint32 count = countRanges(aString) + 1;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
aTextEvent->rangeArray = new nsTextRange[count];
|
|
|
|
|
if (aTextEvent->rangeArray)
|
|
|
|
|
{
|
|
|
|
|
aTextEvent->rangeCount = count;
|
2004-12-23 17:59:53 +00:00
|
|
|
|
convertAttributeToGeckoRange(aString, markRange, selRange, aTextEvent->rangeCount, aTextEvent->rangeArray);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// nsChildView constructor
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
2003-04-21 22:24:12 +00:00
|
|
|
|
nsChildView::nsChildView() : nsBaseWidget()
|
2002-12-13 08:43:18 +00:00
|
|
|
|
, mView(nsnull)
|
|
|
|
|
, mParentView(nsnull)
|
|
|
|
|
, mParentWidget(nsnull)
|
|
|
|
|
, mFontMetrics(nsnull)
|
|
|
|
|
, mTempRenderingContext(nsnull)
|
|
|
|
|
, mDestroyCalled(PR_FALSE)
|
|
|
|
|
, mDestructorCalled(PR_FALSE)
|
|
|
|
|
, mVisible(PR_FALSE)
|
|
|
|
|
, mInWindow(PR_FALSE)
|
|
|
|
|
, mDrawing(PR_FALSE)
|
|
|
|
|
, mTempRenderingContextMadeHere(PR_FALSE)
|
|
|
|
|
, mAcceptFocusOnClick(PR_TRUE)
|
|
|
|
|
, mLiveResizeInProgress(PR_FALSE)
|
|
|
|
|
, mPluginDrawing(PR_FALSE)
|
|
|
|
|
, mPluginPort(nsnull)
|
|
|
|
|
, mVisRgn(nsnull)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
{
|
|
|
|
|
WIDGET_SET_CLASSNAME("nsChildView");
|
|
|
|
|
|
|
|
|
|
SetBackgroundColor(NS_RGB(255, 255, 255));
|
|
|
|
|
SetForegroundColor(NS_RGB(0, 0, 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// nsChildView destructor
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
nsChildView::~nsChildView()
|
|
|
|
|
{
|
2004-02-24 03:40:27 +00:00
|
|
|
|
TearDownView(); // should have already been done from Destroy
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
NS_IF_RELEASE(mTempRenderingContext);
|
|
|
|
|
NS_IF_RELEASE(mFontMetrics);
|
|
|
|
|
|
|
|
|
|
delete mPluginPort;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
|
|
|
|
if (mVisRgn)
|
|
|
|
|
{
|
|
|
|
|
::DisposeRgn(mVisRgn);
|
|
|
|
|
mVisRgn = nsnull;
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-09-08 00:31:50 +00:00
|
|
|
|
NS_IMPL_ISUPPORTS_INHERITED3(nsChildView, nsBaseWidget, nsIPluginWidget, nsIKBStateControl, nsIEventSink)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Utility method for implementing both Create(nsIWidget ...) and
|
|
|
|
|
// Create(nsNativeWidget...)
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
nsresult nsChildView::StandardCreate(nsIWidget *aParent,
|
|
|
|
|
const nsRect &aRect,
|
|
|
|
|
EVENT_CALLBACK aHandleEventFunction,
|
|
|
|
|
nsIDeviceContext *aContext,
|
|
|
|
|
nsIAppShell *aAppShell,
|
|
|
|
|
nsIToolkit *aToolkit,
|
|
|
|
|
nsWidgetInitData *aInitData,
|
2001-11-08 21:47:44 +00:00
|
|
|
|
nsNativeWidget aNativeParent)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
{
|
|
|
|
|
mBounds = aRect;
|
|
|
|
|
|
|
|
|
|
// CalcWindowRegions();
|
|
|
|
|
|
|
|
|
|
BaseCreate(aParent, aRect, aHandleEventFunction,
|
|
|
|
|
aContext, aAppShell, aToolkit, aInitData);
|
|
|
|
|
|
|
|
|
|
// inherit things from the parent view and create our parallel
|
|
|
|
|
// NSView in the Cocoa display system
|
2002-02-12 08:30:01 +00:00
|
|
|
|
mParentView = nil;
|
2001-11-08 21:47:44 +00:00
|
|
|
|
if ( aParent ) {
|
|
|
|
|
SetBackgroundColor(aParent->GetBackgroundColor());
|
|
|
|
|
SetForegroundColor(aParent->GetForegroundColor());
|
|
|
|
|
|
|
|
|
|
// inherit the top-level window. NS_NATIVE_WIDGET is always a NSView
|
|
|
|
|
// regardless of if we're asking a window or a view (for compatibility
|
|
|
|
|
// with windows).
|
2002-12-13 08:43:18 +00:00
|
|
|
|
mParentView = (NSView*)aParent->GetNativeData(NS_NATIVE_WIDGET);
|
|
|
|
|
mParentWidget = aParent;
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
2002-02-12 08:30:01 +00:00
|
|
|
|
else
|
|
|
|
|
mParentView = NS_REINTERPRET_CAST(NSView*,aNativeParent);
|
2001-11-08 21:47:44 +00:00
|
|
|
|
|
|
|
|
|
// create our parallel NSView and hook it up to our parent. Recall
|
|
|
|
|
// that NS_NATIVE_WIDGET is the NSView.
|
|
|
|
|
NSRect r;
|
|
|
|
|
ConvertGeckoToCocoaRect(mBounds, r);
|
2001-11-14 22:29:25 +00:00
|
|
|
|
mView = [CreateCocoaView() retain];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (!mView) return NS_ERROR_FAILURE;
|
|
|
|
|
|
2001-11-08 21:47:44 +00:00
|
|
|
|
[mView setFrame:r];
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
#if DEBUG
|
|
|
|
|
// if our parent is a popup window, we're most certainly coming from a <select> list dropdown which
|
|
|
|
|
// we handle in a different way than other platforms. It's ok that we don't have a parent
|
|
|
|
|
// view because we bailed before even creating the cocoa widgetry and as a result, we
|
|
|
|
|
// don't need to assert. However, if that's not the case, we definately want to assert
|
|
|
|
|
// to show views aren't getting correctly parented.
|
|
|
|
|
if ( aParent ) {
|
|
|
|
|
nsWindowType windowType;
|
|
|
|
|
aParent->GetWindowType(windowType);
|
|
|
|
|
if ( windowType != eWindowType_popup )
|
|
|
|
|
NS_ASSERTION(mParentView && mView, "couldn't hook up new NSView in hierarchy");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
NS_ASSERTION(mParentView && mView, "couldn't hook up new NSView in hierarchy");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (mParentView)
|
|
|
|
|
{
|
|
|
|
|
if (![mParentView isKindOfClass: [ChildView class]])
|
|
|
|
|
{
|
2002-02-12 08:30:01 +00:00
|
|
|
|
[mParentView addSubview:mView];
|
|
|
|
|
mVisible = PR_TRUE;
|
2002-04-19 23:58:36 +00:00
|
|
|
|
NSWindow* window = [mParentView window];
|
|
|
|
|
if (!window) {
|
|
|
|
|
// The enclosing view that embeds Gecko is actually hidden
|
|
|
|
|
// right now! This can happen when Gecko is embedded in the
|
|
|
|
|
// tab of a Cocoa tab view. See if the parent view responds
|
|
|
|
|
// to our special getNativeWindow selector, and if it does,
|
|
|
|
|
// use that to get the window instead.
|
|
|
|
|
//if ([mParentView respondsToSelector: @selector(getNativeWindow:)])
|
2002-12-13 08:43:18 +00:00
|
|
|
|
[mView setNativeWindow: [mParentView getNativeWindow]];
|
2002-04-19 23:58:36 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
[mView setNativeWindow: window];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
2002-02-12 08:30:01 +00:00
|
|
|
|
}
|
2002-02-13 19:57:10 +00:00
|
|
|
|
else
|
2002-12-13 08:43:18 +00:00
|
|
|
|
{
|
2002-02-13 19:57:10 +00:00
|
|
|
|
[mView setNativeWindow: [mParentView getNativeWindow]];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mInWindow = ([mParentView window] != nil);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mInWindow = PR_FALSE;
|
2001-11-08 21:47:44 +00:00
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2001-11-14 22:29:25 +00:00
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// CreateCocoaView
|
|
|
|
|
//
|
|
|
|
|
// Creates the appropriate child view. Override to create something other than
|
|
|
|
|
// our |ChildView| object. Autoreleases, so caller must retain.
|
|
|
|
|
//
|
|
|
|
|
NSView*
|
2004-02-24 03:40:27 +00:00
|
|
|
|
nsChildView::CreateCocoaView( )
|
2001-11-14 22:29:25 +00:00
|
|
|
|
{
|
|
|
|
|
return [[[ChildView alloc] initWithGeckoChild:this eventSink:nsnull] autorelease];
|
|
|
|
|
}
|
|
|
|
|
|
2004-02-24 03:40:27 +00:00
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
void nsChildView::TearDownView()
|
|
|
|
|
{
|
|
|
|
|
if (mView)
|
|
|
|
|
{
|
|
|
|
|
NSWindow* win = [mView window];
|
|
|
|
|
NSResponder* responder = [win firstResponder];
|
|
|
|
|
|
|
|
|
|
// We're being unhooked from the view hierarchy, don't leave our view
|
|
|
|
|
// or a child view as the window first responder.
|
|
|
|
|
if (responder && [responder isKindOfClass:[NSView class]] &&
|
|
|
|
|
[(NSView*)responder isDescendantOf:mView])
|
|
|
|
|
[win makeFirstResponder: [mView superview]];
|
|
|
|
|
|
|
|
|
|
[mView removeFromSuperviewWithoutNeedingDisplay];
|
|
|
|
|
[mView release];
|
|
|
|
|
mView = nil;
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-11-14 22:29:25 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// create a nsChildView
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::Create(nsIWidget *aParent,
|
|
|
|
|
const nsRect &aRect,
|
|
|
|
|
EVENT_CALLBACK aHandleEventFunction,
|
|
|
|
|
nsIDeviceContext *aContext,
|
|
|
|
|
nsIAppShell *aAppShell,
|
|
|
|
|
nsIToolkit *aToolkit,
|
|
|
|
|
nsWidgetInitData *aInitData)
|
|
|
|
|
{
|
|
|
|
|
return(StandardCreate(aParent, aRect, aHandleEventFunction,
|
|
|
|
|
aContext, aAppShell, aToolkit, aInitData,
|
|
|
|
|
nsnull));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
2001-11-08 21:47:44 +00:00
|
|
|
|
// Creates a main nsChildView using a native widget (an NSView)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::Create(nsNativeWidget aNativeParent,
|
|
|
|
|
const nsRect &aRect,
|
|
|
|
|
EVENT_CALLBACK aHandleEventFunction,
|
|
|
|
|
nsIDeviceContext *aContext,
|
|
|
|
|
nsIAppShell *aAppShell,
|
|
|
|
|
nsIToolkit *aToolkit,
|
|
|
|
|
nsWidgetInitData *aInitData)
|
|
|
|
|
{
|
2001-11-08 21:47:44 +00:00
|
|
|
|
// what we're passed in |aNativeParent| is an NSView.
|
|
|
|
|
return(StandardCreate(nsnull, aRect, aHandleEventFunction,
|
|
|
|
|
aContext, aAppShell, aToolkit, aInitData, aNativeParent));
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Close this nsChildView
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::Destroy()
|
|
|
|
|
{
|
|
|
|
|
if (mDestroyCalled)
|
|
|
|
|
return NS_OK;
|
|
|
|
|
mDestroyCalled = PR_TRUE;
|
|
|
|
|
|
|
|
|
|
nsBaseWidget::OnDestroy();
|
|
|
|
|
nsBaseWidget::Destroy();
|
|
|
|
|
|
|
|
|
|
// just to be safe. If we're going away and for some reason we're still
|
|
|
|
|
// the rollup widget, rollup and turn off capture.
|
|
|
|
|
if ( this == gRollupWidget ) {
|
|
|
|
|
if ( gRollupListener )
|
|
|
|
|
gRollupListener->Rollup();
|
|
|
|
|
CaptureRollupEvents(nsnull, PR_FALSE, PR_TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReportDestroyEvent(); // beard: this seems to cause the window to be deleted. moved all release code to destructor.
|
2002-12-13 08:43:18 +00:00
|
|
|
|
mParentWidget = nil;
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
2004-02-24 03:40:27 +00:00
|
|
|
|
TearDownView();
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
2001-11-08 21:47:44 +00:00
|
|
|
|
|
2002-04-27 00:19:49 +00:00
|
|
|
|
static pascal OSStatus OnContentClick(EventHandlerCallRef handler, EventRef event, void* userData)
|
|
|
|
|
{
|
|
|
|
|
WindowRef window;
|
|
|
|
|
GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL,
|
|
|
|
|
sizeof(window), NULL, &window);
|
|
|
|
|
|
|
|
|
|
EventRecord macEvent;
|
|
|
|
|
ConvertEventRefToEventRecord(event, &macEvent);
|
|
|
|
|
GrafPtr port = GetWindowPort(window);
|
|
|
|
|
StPortSetter setter(port);
|
|
|
|
|
Point localWhere = macEvent.where;
|
|
|
|
|
GlobalToLocal(&localWhere);
|
|
|
|
|
|
|
|
|
|
nsChildView* childView = (nsChildView*) userData;
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsMouseEvent geckoEvent(NS_MOUSE_LEFT_BUTTON_DOWN, childView);
|
2002-04-27 00:19:49 +00:00
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
|
|
|
|
geckoEvent.time = PR_IntervalNow();
|
|
|
|
|
geckoEvent.clickCount = 1;
|
|
|
|
|
|
|
|
|
|
geckoEvent.refPoint.x = geckoEvent.point.x = localWhere.h;
|
|
|
|
|
geckoEvent.refPoint.y = geckoEvent.point.y = localWhere.v;
|
|
|
|
|
|
|
|
|
|
geckoEvent.isShift = ((macEvent.modifiers & (shiftKey|rightShiftKey)) != 0);
|
|
|
|
|
geckoEvent.isControl = ((macEvent.modifiers & controlKey) != 0);
|
|
|
|
|
geckoEvent.isAlt = ((macEvent.modifiers & optionKey) != 0);
|
|
|
|
|
geckoEvent.isMeta = ((macEvent.modifiers & cmdKey) != 0);
|
|
|
|
|
|
|
|
|
|
// send event into Gecko by going directly to the
|
|
|
|
|
// the widget.
|
|
|
|
|
childView->DispatchMouseEvent(geckoEvent);
|
|
|
|
|
|
|
|
|
|
return noErr;
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
#define AppKitVersionJaguar 644
|
|
|
|
|
|
|
|
|
|
inline bool hasJaguarAppKit()
|
|
|
|
|
{
|
|
|
|
|
return (NSAppKitVersionNumber >= AppKitVersionJaguar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline WindowRef windowToWindowRef(NSWindow* window)
|
|
|
|
|
{
|
|
|
|
|
return (WindowRef) (hasJaguarAppKit() ?
|
|
|
|
|
[window windowRef] :
|
|
|
|
|
[window _windowRef]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline NSRect getWindowRefFrame(NSWindow* window)
|
|
|
|
|
{
|
|
|
|
|
return (hasJaguarAppKit() ?
|
|
|
|
|
[[window contentView] frame] :
|
|
|
|
|
[window frame]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
static void PrintViewHierarcy(NSView *view)
|
|
|
|
|
{
|
|
|
|
|
while (view)
|
|
|
|
|
{
|
|
|
|
|
NSLog(@" view is %@, frame %@", view, NSStringFromRect([view frame]));
|
|
|
|
|
view = [view superview];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Return some native data according to aDataType
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
void* nsChildView::GetNativeData(PRUint32 aDataType)
|
|
|
|
|
{
|
|
|
|
|
void* retVal = nsnull;
|
|
|
|
|
|
|
|
|
|
switch (aDataType)
|
|
|
|
|
{
|
2001-11-08 21:47:44 +00:00
|
|
|
|
case NS_NATIVE_WIDGET: // the NSView
|
|
|
|
|
case NS_NATIVE_DISPLAY:
|
2001-11-06 15:35:24 +00:00
|
|
|
|
retVal = (void*)mView;
|
|
|
|
|
break;
|
|
|
|
|
|
2001-11-08 21:47:44 +00:00
|
|
|
|
case NS_NATIVE_WINDOW:
|
2002-02-13 19:57:10 +00:00
|
|
|
|
retVal = [mView getNativeWindow];
|
2001-11-08 21:47:44 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
case NS_NATIVE_GRAPHIC: // quickdraw port
|
|
|
|
|
// XXX this can return NULL if we are not the focussed view
|
|
|
|
|
retVal = [mView qdPort];
|
2001-11-06 15:35:24 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NS_NATIVE_REGION:
|
|
|
|
|
{
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (!mVisRgn)
|
|
|
|
|
mVisRgn = ::NewRgn();
|
|
|
|
|
GrafPtr port = (GrafPtr)[mView qdPort];
|
|
|
|
|
|
|
|
|
|
if (port && mVisRgn)
|
|
|
|
|
::GetPortVisibleRegion(port, mVisRgn);
|
|
|
|
|
retVal = (void*)mVisRgn;
|
2001-11-06 15:35:24 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case NS_NATIVE_OFFSETX:
|
2001-11-19 15:02:23 +00:00
|
|
|
|
retVal = 0;
|
2001-11-06 15:35:24 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NS_NATIVE_OFFSETY:
|
2001-11-19 15:02:23 +00:00
|
|
|
|
retVal = 0;
|
2001-11-06 15:35:24 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
case NS_NATIVE_COLORMAP:
|
|
|
|
|
//<2F>TODO
|
|
|
|
|
break;
|
2002-04-27 00:19:49 +00:00
|
|
|
|
#endif
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
case NS_NATIVE_PLUGIN_PORT:
|
|
|
|
|
// this needs to be a combination of the port and the offsets.
|
|
|
|
|
if (mPluginPort == nsnull)
|
2002-12-13 08:43:18 +00:00
|
|
|
|
{
|
2001-11-06 15:35:24 +00:00
|
|
|
|
mPluginPort = new nsPluginPort;
|
2002-04-27 00:19:49 +00:00
|
|
|
|
[mView setIsPluginView: YES];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NSWindow* window = [mView getNativeWindow];
|
|
|
|
|
if (window)
|
|
|
|
|
{
|
|
|
|
|
WindowRef topLevelWindow = windowToWindowRef(window);
|
|
|
|
|
if (topLevelWindow)
|
|
|
|
|
{
|
|
|
|
|
mPluginPort->port = ::GetWindowPort(topLevelWindow);
|
|
|
|
|
|
|
|
|
|
NSPoint viewOrigin = [mView convertPoint:NSZeroPoint toView:nil];
|
|
|
|
|
NSRect frame = getWindowRefFrame(window);
|
|
|
|
|
viewOrigin.y = frame.size.height - viewOrigin.y;
|
|
|
|
|
|
|
|
|
|
// need to convert view's origin to window coordinates.
|
|
|
|
|
// then, encode as "SetOrigin" ready values.
|
|
|
|
|
mPluginPort->portx = (PRInt32)-viewOrigin.x;
|
|
|
|
|
mPluginPort->porty = (PRInt32)-viewOrigin.y;
|
|
|
|
|
|
2002-04-27 00:19:49 +00:00
|
|
|
|
}
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
printf("@@@@ Couldn't get NSWindow for plugin port. @@@@\n");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
retVal = (void*)mPluginPort;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
break;
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return retVal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Return PR_TRUE if the whether the component is visible, PR_FALSE otherwise
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_METHOD nsChildView::IsVisible(PRBool & bState)
|
|
|
|
|
{
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (!mVisible) {
|
|
|
|
|
bState = mVisible;
|
|
|
|
|
} else {
|
|
|
|
|
// mVisible does not accurately reflect the state of a hidden tabbed view
|
|
|
|
|
// so verify that the view has a window as well
|
|
|
|
|
bState = ([mView window] != nil);
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Hide or show this component
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::Show(PRBool bState)
|
2002-02-12 08:30:01 +00:00
|
|
|
|
{
|
|
|
|
|
if (bState != mVisible) {
|
|
|
|
|
if (bState)
|
|
|
|
|
[mParentView addSubview: mView];
|
|
|
|
|
else
|
2002-02-20 01:07:39 +00:00
|
|
|
|
[mView removeFromSuperview];
|
2002-02-12 08:30:01 +00:00
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
mVisible = bState;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2002-02-12 08:30:01 +00:00
|
|
|
|
nsIWidget*
|
|
|
|
|
nsChildView::GetParent(void)
|
|
|
|
|
{
|
2002-12-13 08:43:18 +00:00
|
|
|
|
NS_IF_ADDREF(mParentWidget);
|
|
|
|
|
return mParentWidget;
|
2002-02-12 08:30:01 +00:00
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsChildView::ModalEventFilter(PRBool aRealEvent, void *aEvent,
|
|
|
|
|
PRBool *aForWindow)
|
|
|
|
|
{
|
|
|
|
|
*aForWindow = PR_FALSE;
|
|
|
|
|
EventRecord *theEvent = (EventRecord *) aEvent;
|
|
|
|
|
|
|
|
|
|
if (aRealEvent && theEvent->what != nullEvent ) {
|
|
|
|
|
|
|
|
|
|
WindowPtr window = (WindowPtr) GetNativeData(NS_NATIVE_DISPLAY);
|
|
|
|
|
WindowPtr rollupWindow = gRollupWidget ? (WindowPtr) gRollupWidget->GetNativeData(NS_NATIVE_DISPLAY) : nsnull;
|
|
|
|
|
WindowPtr eventWindow = nsnull;
|
|
|
|
|
|
|
|
|
|
PRInt16 where = ::FindWindow ( theEvent->where, &eventWindow );
|
|
|
|
|
PRBool inWindow = eventWindow && (eventWindow == window || eventWindow == rollupWindow);
|
|
|
|
|
|
|
|
|
|
switch ( theEvent->what ) {
|
|
|
|
|
// is it a mouse event?
|
|
|
|
|
case mouseUp:
|
|
|
|
|
*aForWindow = PR_TRUE;
|
|
|
|
|
break;
|
|
|
|
|
case mouseDown:
|
|
|
|
|
// is it in the given window?
|
|
|
|
|
// (note we also let some events questionable for modal dialogs pass through.
|
|
|
|
|
// but it makes sense that the draggability et.al. of a modal window should
|
|
|
|
|
// be controlled by whether the window has a drag bar).
|
|
|
|
|
if (inWindow) {
|
|
|
|
|
if ( where == inContent || where == inDrag || where == inGrow ||
|
|
|
|
|
where == inGoAway || where == inZoomIn || where == inZoomOut )
|
|
|
|
|
*aForWindow = PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
else // we're in another window.
|
|
|
|
|
{
|
|
|
|
|
// let's handle dragging of background windows here
|
|
|
|
|
if (eventWindow && (where == inDrag) && (theEvent->modifiers & cmdKey))
|
|
|
|
|
{
|
|
|
|
|
Rect screenRect;
|
|
|
|
|
::GetRegionBounds(::GetGrayRgn(), &screenRect);
|
|
|
|
|
::DragWindow(eventWindow, theEvent->where, &screenRect);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*aForWindow = PR_FALSE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case keyDown:
|
|
|
|
|
case keyUp:
|
|
|
|
|
case autoKey:
|
|
|
|
|
*aForWindow = PR_TRUE;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case diskEvt:
|
|
|
|
|
// I think dialogs might want to support floppy insertion, and it doesn't
|
|
|
|
|
// interfere with modality...
|
|
|
|
|
case updateEvt:
|
|
|
|
|
// always let update events through, because if we don't handle them, we're
|
|
|
|
|
// doomed!
|
|
|
|
|
case activateEvt:
|
|
|
|
|
// activate events aren't so much a request as simply informative. might
|
|
|
|
|
// as well acknowledge them.
|
|
|
|
|
*aForWindow = PR_TRUE;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case osEvt:
|
|
|
|
|
// check for mouseMoved or suspend/resume events. We especially need to
|
|
|
|
|
// let suspend/resume events through in order to make sure the clipboard is
|
|
|
|
|
// converted correctly.
|
|
|
|
|
unsigned char eventType = (theEvent->message >> 24) & 0x00ff;
|
|
|
|
|
if (eventType == mouseMovedMessage) {
|
|
|
|
|
// I'm guessing we don't want to let these through unless the mouse is
|
|
|
|
|
// in the modal dialog so we don't see rollover feedback in windows behind
|
|
|
|
|
// the dialog.
|
|
|
|
|
if ( where == inContent && inWindow )
|
|
|
|
|
*aForWindow = PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
if ( eventType == suspendResumeMessage ) {
|
|
|
|
|
*aForWindow = PR_TRUE;
|
|
|
|
|
if (theEvent->message & resumeFlag) {
|
|
|
|
|
// divert it to our window if it isn't naturally
|
|
|
|
|
if (!inWindow) {
|
|
|
|
|
StPortSetter portSetter(window);
|
|
|
|
|
theEvent->where.v = 0;
|
|
|
|
|
theEvent->where.h = 0;
|
|
|
|
|
::LocalToGlobal(&theEvent->where);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
} // case of which event type
|
|
|
|
|
} else
|
|
|
|
|
*aForWindow = PR_TRUE;
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2002-04-02 23:01:05 +00:00
|
|
|
|
// Enable
|
|
|
|
|
//
|
|
|
|
|
// Enable/disable this view
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//
|
2002-02-28 23:10:04 +00:00
|
|
|
|
NS_IMETHODIMP nsChildView::Enable(PRBool aState)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
{
|
2002-04-02 23:01:05 +00:00
|
|
|
|
// unimplemented;
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2002-02-28 23:10:04 +00:00
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsChildView::IsEnabled(PRBool *aState)
|
|
|
|
|
{
|
2002-04-02 23:01:05 +00:00
|
|
|
|
// unimplemented
|
|
|
|
|
if (aState)
|
2002-03-04 22:50:11 +00:00
|
|
|
|
*aState = PR_TRUE;
|
2002-02-28 23:10:04 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
static Boolean WeAreFrontProcess()
|
2001-11-06 15:35:24 +00:00
|
|
|
|
{
|
|
|
|
|
ProcessSerialNumber thisPSN;
|
|
|
|
|
ProcessSerialNumber frontPSN;
|
|
|
|
|
(void)::GetCurrentProcess(&thisPSN);
|
|
|
|
|
if (::GetFrontProcess(&frontPSN) == noErr)
|
|
|
|
|
{
|
|
|
|
|
if ((frontPSN.highLongOfPSN == thisPSN.highLongOfPSN) &&
|
|
|
|
|
(frontPSN.lowLongOfPSN == thisPSN.lowLongOfPSN))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Set the focus on this component
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::SetFocus(PRBool aRaise)
|
|
|
|
|
{
|
2002-02-13 02:09:13 +00:00
|
|
|
|
NSWindow* window = [mView window];
|
|
|
|
|
if (window)
|
|
|
|
|
[window makeFirstResponder: mView];
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Get this component font
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
nsIFontMetrics* nsChildView::GetFont(void)
|
|
|
|
|
{
|
|
|
|
|
return mFontMetrics;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Set this component font
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::SetFont(const nsFont &aFont)
|
|
|
|
|
{
|
|
|
|
|
NS_IF_RELEASE(mFontMetrics);
|
|
|
|
|
if (mContext)
|
|
|
|
|
mContext->GetMetricsFor(aFont, mFontMetrics);
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Set the colormap of the window
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::SetColorMap(nsColorMap *aColorMap)
|
|
|
|
|
{
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// SetMenuBar
|
|
|
|
|
// ShowMenuBar
|
|
|
|
|
// GetMenuBar
|
|
|
|
|
//
|
|
|
|
|
// Meaningless in this context. A subview doesn't have a menubar.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsChildView::SetMenuBar(nsIMenuBar * aMenuBar)
|
|
|
|
|
{
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsChildView::ShowMenuBar(PRBool aShow)
|
|
|
|
|
{
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsIMenuBar* nsChildView::GetMenuBar()
|
|
|
|
|
{
|
|
|
|
|
return nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// SetCursor
|
|
|
|
|
//
|
|
|
|
|
// Override to set the cursor on the mac
|
|
|
|
|
//
|
|
|
|
|
NS_METHOD nsChildView::SetCursor(nsCursor aCursor)
|
|
|
|
|
{
|
|
|
|
|
nsBaseWidget::SetCursor(aCursor);
|
2004-04-29 03:14:21 +00:00
|
|
|
|
[[nsCursorManager sharedInstance] setCursor: aCursor];
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
} // nsChildView::SetCursor
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Get this component dimension
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::GetBounds(nsRect &aRect)
|
|
|
|
|
{
|
|
|
|
|
aRect = mBounds;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_METHOD nsChildView::SetBounds(const nsRect &aRect)
|
|
|
|
|
{
|
|
|
|
|
nsresult rv = Inherited::SetBounds(aRect);
|
|
|
|
|
if ( NS_SUCCEEDED(rv) ) {
|
|
|
|
|
//CalcWindowRegions();
|
|
|
|
|
NSRect r;
|
|
|
|
|
ConvertGeckoToCocoaRect(aRect, r);
|
|
|
|
|
[mView setFrame:r];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-01-09 01:29:18 +00:00
|
|
|
|
NS_IMETHODIMP nsChildView::ConstrainPosition(PRBool aAllowSlop,
|
|
|
|
|
PRInt32 *aX, PRInt32 *aY)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
{
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Move this component
|
|
|
|
|
// aX and aY are in the parent widget coordinate system
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::Move(PRInt32 aX, PRInt32 aY)
|
2002-04-06 19:50:30 +00:00
|
|
|
|
{
|
|
|
|
|
return MoveWithRepaintOption(aX, aY, PR_TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsChildView::MoveWithRepaintOption(PRInt32 aX, PRInt32 aY, PRBool aRepaint)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
{
|
|
|
|
|
if ((mBounds.x != aX) || (mBounds.y != aY))
|
|
|
|
|
{
|
2001-11-08 21:47:44 +00:00
|
|
|
|
// Invalidate the current location
|
2002-04-06 19:50:30 +00:00
|
|
|
|
if (mVisible && aRepaint)
|
|
|
|
|
[[mView superview] setNeedsDisplayInRect: [mView frame]]; //XXX needed?
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
// Set the bounds
|
|
|
|
|
mBounds.x = aX;
|
|
|
|
|
mBounds.y = aY;
|
2002-02-21 02:24:18 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
NSRect r;
|
|
|
|
|
ConvertGeckoToCocoaRect(mBounds, r);
|
|
|
|
|
[mView setFrame:r];
|
2002-02-12 08:30:01 +00:00
|
|
|
|
|
2002-04-06 19:50:30 +00:00
|
|
|
|
if (mVisible && aRepaint)
|
2002-02-12 08:30:01 +00:00
|
|
|
|
[mView setNeedsDisplay:YES];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
// Report the event
|
|
|
|
|
ReportMoveEvent();
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Resize this component
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
|
|
|
|
|
{
|
|
|
|
|
if ((mBounds.width != aWidth) || (mBounds.height != aHeight))
|
|
|
|
|
{
|
|
|
|
|
// Set the bounds
|
|
|
|
|
mBounds.width = aWidth;
|
|
|
|
|
mBounds.height = aHeight;
|
|
|
|
|
|
2002-04-06 19:50:30 +00:00
|
|
|
|
if (mVisible && aRepaint)
|
2002-02-20 01:07:39 +00:00
|
|
|
|
[[mView superview] setNeedsDisplayInRect: [mView frame]]; //XXX needed?
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
NSRect r;
|
|
|
|
|
ConvertGeckoToCocoaRect(mBounds, r);
|
|
|
|
|
[mView setFrame:r];
|
2002-02-12 08:30:01 +00:00
|
|
|
|
|
2002-04-06 19:50:30 +00:00
|
|
|
|
if (mVisible && aRepaint)
|
2002-02-12 08:30:01 +00:00
|
|
|
|
[mView setNeedsDisplay:YES];
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
// Report the event
|
|
|
|
|
ReportSizeEvent();
|
|
|
|
|
}
|
2002-02-20 01:07:39 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Resize this component
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
|
|
|
|
|
{
|
2002-04-06 19:50:30 +00:00
|
|
|
|
MoveWithRepaintOption(aX, aY, aRepaint);
|
2001-11-06 15:35:24 +00:00
|
|
|
|
Resize(aWidth, aHeight, aRepaint);
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// GetPreferredSize
|
|
|
|
|
// SetPreferredSize
|
|
|
|
|
//
|
|
|
|
|
// Nobody even calls these aywhere in the code
|
|
|
|
|
//
|
|
|
|
|
NS_METHOD nsChildView::GetPreferredSize(PRInt32& aWidth, PRInt32& aHeight)
|
|
|
|
|
{
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_METHOD nsChildView::SetPreferredSize(PRInt32 aWidth, PRInt32 aHeight)
|
|
|
|
|
{
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::BeginResizingChildren(void)
|
|
|
|
|
{
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::EndResizingChildren(void)
|
|
|
|
|
{
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
2003-02-28 22:59:12 +00:00
|
|
|
|
NS_IMETHODIMP nsChildView::GetPluginClipRect(nsRect& outClipRect, nsPoint& outOrigin, PRBool& outWidgetVisible)
|
2002-12-13 08:43:18 +00:00
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(mPluginPort, "GetPluginClipRect must only be called on a plugin widget");
|
|
|
|
|
if (!mPluginPort) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
NSWindow* window = [mView getNativeWindow];
|
|
|
|
|
if (!window) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
NSPoint viewOrigin = [mView convertPoint:NSZeroPoint toView:nil];
|
|
|
|
|
NSRect frame = getWindowRefFrame(window);
|
|
|
|
|
viewOrigin.y = frame.size.height - viewOrigin.y;
|
|
|
|
|
|
|
|
|
|
// set up the clipping region for plugins.
|
|
|
|
|
NSRect visibleBounds = [mView visibleRect];
|
|
|
|
|
NSPoint clipOrigin = [mView convertPoint:visibleBounds.origin toView:nil];
|
|
|
|
|
|
|
|
|
|
// Convert from cocoa to QuickDraw coordinates
|
|
|
|
|
clipOrigin.y = frame.size.height - clipOrigin.y;
|
|
|
|
|
|
|
|
|
|
outClipRect.x = (nscoord)clipOrigin.x;
|
|
|
|
|
outClipRect.y = (nscoord)clipOrigin.y;
|
|
|
|
|
|
|
|
|
|
if (mInWindow)
|
|
|
|
|
{
|
|
|
|
|
outClipRect.width = (nscoord)visibleBounds.size.width;
|
|
|
|
|
outClipRect.height = (nscoord)visibleBounds.size.height;
|
2003-02-28 22:59:12 +00:00
|
|
|
|
outWidgetVisible = PR_TRUE;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
outClipRect.width = 0;
|
|
|
|
|
outClipRect.height = 0;
|
2003-02-28 22:59:12 +00:00
|
|
|
|
outWidgetVisible = PR_FALSE;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// need to convert view's origin to window coordinates.
|
|
|
|
|
// then, encode as "SetOrigin" ready values.
|
|
|
|
|
outOrigin.x = (nscoord)-viewOrigin.x;
|
|
|
|
|
outOrigin.y = (nscoord)-viewOrigin.y;
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::StartDrawPlugin()
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(mPluginPort, "StartDrawPlugin must only be called on a plugin widget");
|
|
|
|
|
if (!mPluginPort)
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
// prevent reentrant drawing
|
|
|
|
|
if (mPluginDrawing)
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
NSWindow* window = [mView getNativeWindow];
|
|
|
|
|
if (!window) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
if (window /* [mView lockFocusIfCanDraw] */)
|
|
|
|
|
{
|
|
|
|
|
// It appears that the WindowRef from which we get the plugin port undergoes the
|
|
|
|
|
// traditional BeginUpdate/EndUpdate cycle, which, if you recall, sets the visible
|
|
|
|
|
// region to the intersection of the visible region and the update region. Since
|
|
|
|
|
// we don't know here if we're being drawn inside a BeginUpdate/EndUpdate pair
|
|
|
|
|
// (which seem to occur in [NSWindow display]), and we don't want to have the burden
|
|
|
|
|
// of correctly doing Carbon invalidates of the plugin rect, we manually set the
|
|
|
|
|
// visible region to be the entire port every time.
|
|
|
|
|
RgnHandle pluginRegion = ::NewRgn();
|
|
|
|
|
if (pluginRegion)
|
|
|
|
|
{
|
|
|
|
|
StPortSetter setter(mPluginPort->port);
|
|
|
|
|
::SetOrigin(0, 0);
|
|
|
|
|
|
|
|
|
|
nsRect clipRect; // this is in native window coordinates
|
|
|
|
|
nsPoint origin;
|
2003-02-28 22:59:12 +00:00
|
|
|
|
PRBool visible;
|
|
|
|
|
GetPluginClipRect(clipRect, origin, visible);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
2003-02-28 22:59:12 +00:00
|
|
|
|
// XXX if we're not visible, set an empty clip region?
|
2002-12-13 08:43:18 +00:00
|
|
|
|
Rect pluginRect;
|
|
|
|
|
ConvertGeckoRectToMacRect(clipRect, pluginRect);
|
|
|
|
|
|
|
|
|
|
::RectRgn(pluginRegion, &pluginRect);
|
|
|
|
|
::SetPortVisibleRegion(mPluginPort->port, pluginRegion);
|
|
|
|
|
::SetPortClipRegion(mPluginPort->port, pluginRegion);
|
|
|
|
|
|
|
|
|
|
// now set up the origin for the plugin
|
|
|
|
|
::SetOrigin(origin.x, origin.y);
|
|
|
|
|
|
|
|
|
|
::DisposeRgn(pluginRegion);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mPluginDrawing = PR_TRUE;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_ASSERTION(0, "lockFocusIfCanDraw returned false\n");
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::EndDrawPlugin()
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(mPluginPort, "EndDrawPlugin must only be called on a plugin widget");
|
|
|
|
|
//[mView unlockFocus];
|
|
|
|
|
mPluginDrawing = PR_FALSE;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
void nsChildView::RemovedFromWindow()
|
|
|
|
|
{
|
|
|
|
|
mInWindow = PR_FALSE;
|
|
|
|
|
|
2003-03-11 06:51:20 +00:00
|
|
|
|
if (mPluginPort && !mDestroyCalled)
|
2002-12-13 08:43:18 +00:00
|
|
|
|
{
|
|
|
|
|
// force a redraw, so that the plugin knows that it's view is being hidden
|
|
|
|
|
Invalidate(PR_TRUE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
void nsChildView::AddedToWindow()
|
|
|
|
|
{
|
|
|
|
|
mInWindow = PR_TRUE;
|
|
|
|
|
|
|
|
|
|
if (mPluginPort)
|
|
|
|
|
{
|
|
|
|
|
// force a redraw, so that the plugin knows that it's view is being shown
|
|
|
|
|
// note that we can't do a sync invalidate here, because the view
|
|
|
|
|
// hierarchy is in flux.
|
|
|
|
|
Invalidate(PR_FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
void nsChildView::LiveResizeStarted()
|
|
|
|
|
{
|
|
|
|
|
// XXX todo. Use this to disable Java async redraw during resize
|
|
|
|
|
mLiveResizeInProgress = PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
void nsChildView::LiveResizeEnded()
|
|
|
|
|
{
|
|
|
|
|
mLiveResizeInProgress = PR_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
#if defined(INVALIDATE_DEBUGGING) || defined(PAINT_DEBUGGING)
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
static Boolean KeyDown(const UInt8 theKey)
|
|
|
|
|
{
|
|
|
|
|
KeyMap map;
|
|
|
|
|
GetKeys(map);
|
|
|
|
|
return ((*((UInt8 *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Boolean caps_lock()
|
|
|
|
|
{
|
|
|
|
|
return KeyDown(0x39);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void blinkRect(Rect* r)
|
|
|
|
|
{
|
|
|
|
|
StRegionFromPool oldClip;
|
|
|
|
|
if (oldClip != NULL)
|
|
|
|
|
::GetClip(oldClip);
|
|
|
|
|
|
|
|
|
|
::ClipRect(r);
|
|
|
|
|
::InvertRect(r);
|
|
|
|
|
UInt32 end = ::TickCount() + 5;
|
|
|
|
|
while (::TickCount() < end) ;
|
|
|
|
|
::InvertRect(r);
|
|
|
|
|
|
|
|
|
|
if (oldClip != NULL)
|
|
|
|
|
::SetClip(oldClip);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void blinkRgn(RgnHandle rgn)
|
|
|
|
|
{
|
|
|
|
|
StRegionFromPool oldClip;
|
|
|
|
|
if (oldClip != NULL)
|
|
|
|
|
::GetClip(oldClip);
|
|
|
|
|
|
|
|
|
|
::SetClip(rgn);
|
|
|
|
|
::InvertRgn(rgn);
|
|
|
|
|
UInt32 end = ::TickCount() + 5;
|
|
|
|
|
while (::TickCount() < end) ;
|
|
|
|
|
::InvertRgn(rgn);
|
|
|
|
|
|
|
|
|
|
if (oldClip != NULL)
|
|
|
|
|
::SetClip(oldClip);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Invalidate this component's visible area
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::Invalidate(PRBool aIsSynchronous)
|
|
|
|
|
{
|
2002-02-21 02:24:18 +00:00
|
|
|
|
if (!mView || !mVisible)
|
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
|
|
if (aIsSynchronous)
|
|
|
|
|
[mView display];
|
|
|
|
|
else
|
2002-04-27 09:43:44 +00:00
|
|
|
|
[mView setNeedsDisplay:YES];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Invalidate this component's visible area
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::Invalidate(const nsRect &aRect, PRBool aIsSynchronous)
|
|
|
|
|
{
|
2002-02-12 08:30:01 +00:00
|
|
|
|
if ( !mView || !mVisible)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
2002-02-12 08:30:01 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
NSRect r;
|
|
|
|
|
ConvertGeckoToCocoaRect ( aRect, r );
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (aIsSynchronous)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
[mView displayRect:r];
|
|
|
|
|
else
|
|
|
|
|
[mView setNeedsDisplayInRect:r];
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Validate the widget
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::Validate()
|
|
|
|
|
{
|
|
|
|
|
[mView setNeedsDisplay:NO];
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Invalidate this component's visible area
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsChildView::InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous)
|
|
|
|
|
{
|
2002-02-12 08:30:01 +00:00
|
|
|
|
if ( !mView || !mVisible)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
|
|
//FIXME rewrite to use a Cocoa region when nsIRegion isn't a QD Region
|
|
|
|
|
NSRect r;
|
|
|
|
|
nsRect bounds;
|
|
|
|
|
nsIRegion* region = NS_CONST_CAST(nsIRegion*, aRegion); // ugh. this method should be const
|
|
|
|
|
region->GetBoundingBox ( &bounds.x, &bounds.y, &bounds.width, &bounds.height );
|
|
|
|
|
ConvertGeckoToCocoaRect(bounds, r);
|
|
|
|
|
|
|
|
|
|
if ( aIsSynchronous )
|
|
|
|
|
[mView displayRect:r];
|
|
|
|
|
else
|
|
|
|
|
[mView setNeedsDisplayInRect:r];
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline PRUint16 COLOR8TOCOLOR16(PRUint8 color8)
|
|
|
|
|
{
|
|
|
|
|
// return (color8 == 0xFF ? 0xFFFF : (color8 << 8));
|
|
|
|
|
return (color8 << 8) | color8; /* (color8 * 257) == (color8 * 0x0101) */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
// StartDraw
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
void nsChildView::StartDraw(nsIRenderingContext* aRenderingContext)
|
|
|
|
|
{
|
|
|
|
|
if (mDrawing)
|
|
|
|
|
return;
|
|
|
|
|
mDrawing = PR_TRUE;
|
|
|
|
|
|
|
|
|
|
if (aRenderingContext == nsnull)
|
|
|
|
|
{
|
|
|
|
|
// make sure we have a rendering context
|
|
|
|
|
mTempRenderingContext = GetRenderingContext();
|
|
|
|
|
mTempRenderingContextMadeHere = PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// if we already have a rendering context, save its state
|
|
|
|
|
NS_IF_ADDREF(aRenderingContext);
|
|
|
|
|
mTempRenderingContext = aRenderingContext;
|
|
|
|
|
mTempRenderingContextMadeHere = PR_FALSE;
|
|
|
|
|
mTempRenderingContext->PushState();
|
|
|
|
|
|
|
|
|
|
// set the environment to the current widget
|
|
|
|
|
mTempRenderingContext->Init(mContext, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set the widget font. nsMacControl implements SetFont, which is where
|
|
|
|
|
// the font should get set.
|
|
|
|
|
if (mFontMetrics)
|
|
|
|
|
{
|
|
|
|
|
mTempRenderingContext->SetFont(mFontMetrics);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set the widget background and foreground colors
|
|
|
|
|
nscolor color = GetBackgroundColor();
|
|
|
|
|
RGBColor macColor;
|
|
|
|
|
macColor.red = COLOR8TOCOLOR16(NS_GET_R(color));
|
|
|
|
|
macColor.green = COLOR8TOCOLOR16(NS_GET_G(color));
|
|
|
|
|
macColor.blue = COLOR8TOCOLOR16(NS_GET_B(color));
|
|
|
|
|
::RGBBackColor(&macColor);
|
|
|
|
|
|
|
|
|
|
color = GetForegroundColor();
|
|
|
|
|
macColor.red = COLOR8TOCOLOR16(NS_GET_R(color));
|
|
|
|
|
macColor.green = COLOR8TOCOLOR16(NS_GET_G(color));
|
|
|
|
|
macColor.blue = COLOR8TOCOLOR16(NS_GET_B(color));
|
|
|
|
|
::RGBForeColor(&macColor);
|
|
|
|
|
|
|
|
|
|
mTempRenderingContext->SetColor(color); // just in case, set the rendering context color too
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
// EndDraw
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
void nsChildView::EndDraw()
|
|
|
|
|
{
|
|
|
|
|
if (! mDrawing)
|
|
|
|
|
return;
|
|
|
|
|
mDrawing = PR_FALSE;
|
|
|
|
|
|
|
|
|
|
if (mTempRenderingContextMadeHere)
|
2004-04-18 13:55:11 +00:00
|
|
|
|
mTempRenderingContext->PopState();
|
2001-11-06 15:35:24 +00:00
|
|
|
|
NS_RELEASE(mTempRenderingContext);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
void
|
|
|
|
|
nsChildView::Flash(nsPaintEvent &aEvent)
|
|
|
|
|
{
|
2001-11-29 22:37:48 +00:00
|
|
|
|
#if DEBUG
|
2001-11-06 15:35:24 +00:00
|
|
|
|
Rect flashRect;
|
|
|
|
|
if (debug_WantPaintFlashing() && aEvent.rect ) {
|
|
|
|
|
::SetRect ( &flashRect, aEvent.rect->x, aEvent.rect->y, aEvent.rect->x + aEvent.rect->width,
|
|
|
|
|
aEvent.rect->y + aEvent.rect->height );
|
2001-11-14 22:29:25 +00:00
|
|
|
|
StPortSetter portSetter(GetQuickDrawPort());
|
2001-11-06 15:35:24 +00:00
|
|
|
|
unsigned long endTicks;
|
|
|
|
|
::InvertRect ( &flashRect );
|
|
|
|
|
::Delay(10, &endTicks);
|
|
|
|
|
::InvertRect ( &flashRect );
|
|
|
|
|
}
|
2001-11-29 22:37:48 +00:00
|
|
|
|
#endif
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// OnPaint
|
|
|
|
|
//
|
|
|
|
|
// Dummy impl, meant to be overridden
|
|
|
|
|
//
|
|
|
|
|
PRBool
|
|
|
|
|
nsChildView::OnPaint(nsPaintEvent &event)
|
|
|
|
|
{
|
|
|
|
|
return PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Update
|
|
|
|
|
//
|
|
|
|
|
// this is handled for us by UpdateWidget
|
|
|
|
|
//
|
|
|
|
|
NS_IMETHODIMP nsChildView::Update()
|
|
|
|
|
{
|
2002-02-20 01:07:39 +00:00
|
|
|
|
// Update means "Flush any pending changes right now." It does *not* mean
|
|
|
|
|
// repaint the world. :) -- dwh
|
|
|
|
|
[mView displayIfNeeded];
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// UpdateWidget
|
|
|
|
|
//
|
|
|
|
|
// Dispatches the Paint event into Gecko. Usually called from our
|
2002-02-21 02:24:18 +00:00
|
|
|
|
// NSView in response to the display system noticing that something
|
2001-11-06 15:35:24 +00:00
|
|
|
|
// needs repainting. We don't have to worry about painting our child views
|
|
|
|
|
// because the display system will take care of that for us.
|
|
|
|
|
//
|
|
|
|
|
void
|
|
|
|
|
nsChildView::UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext)
|
|
|
|
|
{
|
|
|
|
|
if (! mVisible)
|
|
|
|
|
return;
|
2002-02-20 01:07:39 +00:00
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
// For updating widgets, we _always_ want to use the NSQuickDrawView's port,
|
|
|
|
|
// since that's the correct port for gecko to use to make rendering contexts.
|
|
|
|
|
// The plugin is the only thing that uses the plugin port.
|
|
|
|
|
GrafPtr curPort = (GrafPtr)[mView qdPort];
|
|
|
|
|
StPortSetter port(curPort);
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
// initialize the paint event
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsPaintEvent paintEvent(NS_PAINT, this);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
paintEvent.renderingContext = aContext; // nsPaintEvent
|
|
|
|
|
paintEvent.rect = &aRect;
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
2002-02-21 02:24:18 +00:00
|
|
|
|
// offscreen drawing is pointless.
|
|
|
|
|
if (paintEvent.rect->x < 0)
|
|
|
|
|
paintEvent.rect->x = 0;
|
|
|
|
|
if (paintEvent.rect->y < 0)
|
|
|
|
|
paintEvent.rect->y = 0;
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
// draw the widget
|
|
|
|
|
StartDraw(aContext);
|
|
|
|
|
if ( OnPaint(paintEvent) ) {
|
|
|
|
|
nsEventStatus eventStatus;
|
|
|
|
|
DispatchWindowEvent(paintEvent,eventStatus);
|
|
|
|
|
if(eventStatus != nsEventStatus_eIgnore)
|
|
|
|
|
Flash(paintEvent);
|
|
|
|
|
}
|
|
|
|
|
EndDraw();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
2001-11-14 22:29:25 +00:00
|
|
|
|
// Scroll
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//
|
2001-11-14 22:29:25 +00:00
|
|
|
|
// Scroll the bits of a view and its children
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//
|
2001-11-14 22:29:25 +00:00
|
|
|
|
// FIXME: I'm sure the invalidating can be optimized, just no time now.
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//
|
|
|
|
|
NS_IMETHODIMP nsChildView::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
|
|
|
|
|
{
|
2002-12-13 08:43:18 +00:00
|
|
|
|
BOOL viewWasDirty = NO;
|
|
|
|
|
if (mVisible)
|
|
|
|
|
{
|
|
|
|
|
viewWasDirty = [mView needsDisplay];
|
2002-02-20 01:07:39 +00:00
|
|
|
|
|
|
|
|
|
NSSize scrollVector = {aDx,aDy};
|
2002-12-13 08:43:18 +00:00
|
|
|
|
[mView scrollRect: [mView visibleRect] by:scrollVector];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Scroll the children (even if the widget is not visible)
|
2004-05-22 20:54:40 +00:00
|
|
|
|
for (nsIWidget* kid = mFirstChild; kid; kid = kid->GetNextSibling()) {
|
|
|
|
|
// We use resize rather than move since it gives us control
|
|
|
|
|
// over repainting. In the case of blitting, Quickdraw views
|
|
|
|
|
// draw their child widgets on the blit, so we can scroll
|
|
|
|
|
// like a bat out of hell by not wasting time invalidating
|
|
|
|
|
// the widgets, since it's completely unnecessary to do so.
|
|
|
|
|
nsRect bounds;
|
|
|
|
|
kid->GetBounds(bounds);
|
|
|
|
|
kid->Resize(bounds.x + aDx, bounds.y + aDy, bounds.width, bounds.height, PR_FALSE);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
2002-03-07 03:15:21 +00:00
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (mVisible)
|
|
|
|
|
{
|
|
|
|
|
if (viewWasDirty)
|
|
|
|
|
{
|
|
|
|
|
[mView setNeedsDisplay:YES];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NSRect frame = [mView visibleRect];
|
|
|
|
|
NSRect horizInvalid = frame;
|
|
|
|
|
NSRect vertInvalid = frame;
|
|
|
|
|
|
2003-02-13 10:29:21 +00:00
|
|
|
|
if (aDx != 0) {
|
|
|
|
|
horizInvalid.size.width = abs(aDx);
|
|
|
|
|
if (aDx < 0)
|
|
|
|
|
horizInvalid.origin.x = frame.origin.x + frame.size.width + aDx;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
[mView setNeedsDisplayInRect: horizInvalid];
|
2003-02-13 10:29:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (aDy != 0) {
|
|
|
|
|
vertInvalid.size.height = abs(aDy);
|
|
|
|
|
if (aDy < 0)
|
|
|
|
|
vertInvalid.origin.y = frame.origin.y + frame.size.height + aDy;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
[mView setNeedsDisplayInRect: vertInvalid];
|
2003-02-13 10:29:21 +00:00
|
|
|
|
}
|
2002-03-07 03:15:21 +00:00
|
|
|
|
|
2003-02-13 10:29:21 +00:00
|
|
|
|
// We also need to check for any ChildViews which overlap this widget
|
|
|
|
|
// but are not descendent widgets. If there are any, we need to
|
|
|
|
|
// invalidate the area of this view that these ChildViews will have been
|
|
|
|
|
// blitted into, since these widgets aren't supposed to scroll with
|
|
|
|
|
// this widget.
|
|
|
|
|
|
|
|
|
|
// To do this, start at the root Gecko NSView, and walk down along
|
|
|
|
|
// our ancestor view chain, looking at all the subviews in each level
|
|
|
|
|
// of the hierarchy. If we find a non-ancestor view that overlaps
|
|
|
|
|
// this view, invalidate the area around it.
|
|
|
|
|
|
|
|
|
|
// We need to convert all rects to a common ancestor view to intersect
|
|
|
|
|
// them, since a view's frame is in the coordinate space of its parent.
|
|
|
|
|
// Use mParentView as the frame of reference.
|
|
|
|
|
NSRect selfFrame = [mParentView convertRect:[mView frame] fromView:[mView superview]];
|
|
|
|
|
NSView* view = mParentView;
|
|
|
|
|
BOOL selfLevel = NO;
|
|
|
|
|
|
|
|
|
|
while (!selfLevel) {
|
|
|
|
|
NSView* nextAncestorView;
|
|
|
|
|
NSArray* subviews = [view subviews];
|
2003-03-11 06:51:20 +00:00
|
|
|
|
for (unsigned int i = 0; i < [subviews count]; ++i) {
|
2003-02-13 10:29:21 +00:00
|
|
|
|
NSView* subView = [subviews objectAtIndex: i];
|
|
|
|
|
if (subView == mView)
|
|
|
|
|
selfLevel = YES;
|
|
|
|
|
else if ([mView isDescendantOf:subView])
|
|
|
|
|
nextAncestorView = subView;
|
|
|
|
|
else {
|
|
|
|
|
NSRect intersectArea = NSIntersectionRect([mParentView convertRect:[subView frame] fromView:[subView superview]], selfFrame);
|
|
|
|
|
if (!NSIsEmptyRect(intersectArea)) {
|
|
|
|
|
NSPoint origin = [mView convertPoint:intersectArea.origin fromView:mParentView];
|
|
|
|
|
|
|
|
|
|
if (aDy != 0) {
|
|
|
|
|
vertInvalid.origin.x = origin.x;
|
|
|
|
|
if (aDy < 0) // scrolled down, invalidate above
|
|
|
|
|
vertInvalid.origin.y = origin.y + aDy;
|
|
|
|
|
else // invalidate below
|
|
|
|
|
vertInvalid.origin.y = origin.y + intersectArea.size.height;
|
|
|
|
|
vertInvalid.size.width = intersectArea.size.width;
|
|
|
|
|
[mView setNeedsDisplayInRect: vertInvalid];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (aDx != 0) {
|
|
|
|
|
horizInvalid.origin.y = origin.y;
|
|
|
|
|
if (aDx < 0) // scrolled right, invalidate to the left
|
|
|
|
|
horizInvalid.origin.x = origin.x + aDx;
|
|
|
|
|
else // invalidate to the right
|
|
|
|
|
horizInvalid.origin.x = origin.x + intersectArea.size.width;
|
|
|
|
|
horizInvalid.size.height = intersectArea.size.height;
|
|
|
|
|
[mView setNeedsDisplayInRect: horizInvalid];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
view = nextAncestorView;
|
|
|
|
|
}
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This is an evil hack that doesn't always work.
|
|
|
|
|
//
|
|
|
|
|
// Drawing plugins in a Cocoa environment is tricky, because the
|
|
|
|
|
// plugins are living in a Carbon WindowRef/BeginUpdate/EndUpdate
|
|
|
|
|
// world, and Cocoa has its own notion of dirty rectangles. Throw
|
|
|
|
|
// Quartz Extreme and QuickTime into the mix, and things get bad.
|
|
|
|
|
//
|
|
|
|
|
// This code is working around a cosmetic issue seen when Quartz Extreme
|
|
|
|
|
// is active, and you're scrolling a page with a QuickTime plugin; areas
|
|
|
|
|
// outside the plugin fail to scroll properly. This [display] ensures that
|
|
|
|
|
// the view is properly drawn before the next Scroll call.
|
|
|
|
|
//
|
|
|
|
|
// The time this doesn't work is when you're scrolling a page containing
|
|
|
|
|
// an iframe which in turn contains a plugin.
|
|
|
|
|
//
|
|
|
|
|
// This is turned off because it makes scrolling pages with plugins slow.
|
|
|
|
|
//
|
|
|
|
|
//if ([mView childViewHasPlugin])
|
|
|
|
|
// [mView display];
|
2002-03-07 03:15:21 +00:00
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
return NS_OK;
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-11-14 22:29:25 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
PRBool nsChildView::ConvertStatus(nsEventStatus aStatus)
|
|
|
|
|
{
|
|
|
|
|
switch (aStatus)
|
|
|
|
|
{
|
|
|
|
|
case nsEventStatus_eIgnore: return(PR_FALSE);
|
|
|
|
|
case nsEventStatus_eConsumeNoDefault: return(PR_TRUE); // don't do default processing
|
|
|
|
|
case nsEventStatus_eConsumeDoDefault: return(PR_FALSE);
|
|
|
|
|
default:
|
|
|
|
|
NS_ASSERTION(0, "Illegal nsEventStatus enumeration value");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return(PR_FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Invokes callback and ProcessEvent method on Event Listener object
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::DispatchEvent(nsGUIEvent* event, nsEventStatus& aStatus)
|
|
|
|
|
{
|
|
|
|
|
aStatus = nsEventStatus_eIgnore;
|
|
|
|
|
if (! mDestructorCalled)
|
|
|
|
|
{
|
|
|
|
|
nsIWidget* aWidget = event->widget;
|
|
|
|
|
NS_IF_ADDREF(aWidget);
|
|
|
|
|
|
|
|
|
|
if (nsnull != mMenuListener){
|
2002-04-27 00:19:49 +00:00
|
|
|
|
if (NS_MENU_EVENT == event->eventStructType)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
aStatus = mMenuListener->MenuSelected( static_cast<nsMenuEvent&>(*event) );
|
|
|
|
|
}
|
|
|
|
|
if (mEventCallback)
|
|
|
|
|
aStatus = (*mEventCallback)(event);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
// Dispatch to event listener if event was not consumed
|
|
|
|
|
if ((aStatus != nsEventStatus_eConsumeNoDefault) && (mEventListener != nsnull))
|
|
|
|
|
aStatus = mEventListener->ProcessEvent(*event);
|
|
|
|
|
|
|
|
|
|
NS_IF_RELEASE(aWidget);
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
PRBool nsChildView::DispatchWindowEvent(nsGUIEvent &event)
|
|
|
|
|
{
|
|
|
|
|
nsEventStatus status;
|
|
|
|
|
DispatchEvent(&event, status);
|
|
|
|
|
return ConvertStatus(status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
PRBool nsChildView::DispatchWindowEvent(nsGUIEvent &event,nsEventStatus &aStatus)
|
|
|
|
|
{
|
|
|
|
|
DispatchEvent(&event, aStatus);
|
|
|
|
|
return ConvertStatus(aStatus);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Deal with all sort of mouse event
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
PRBool nsChildView::DispatchMouseEvent(nsMouseEvent &aEvent)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
PRBool result = PR_FALSE;
|
|
|
|
|
if (nsnull == mEventCallback && nsnull == mMouseListener) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// call the event callback
|
|
|
|
|
if (nsnull != mEventCallback)
|
|
|
|
|
{
|
|
|
|
|
result = (DispatchWindowEvent(aEvent));
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nsnull != mMouseListener) {
|
|
|
|
|
switch (aEvent.message) {
|
|
|
|
|
case NS_MOUSE_MOVE: {
|
|
|
|
|
result = ConvertStatus(mMouseListener->MouseMoved(aEvent));
|
|
|
|
|
nsRect rect;
|
|
|
|
|
GetBounds(rect);
|
|
|
|
|
if (rect.Contains(aEvent.point.x, aEvent.point.y))
|
|
|
|
|
{
|
|
|
|
|
//if (mWindowPtr == NULL || mWindowPtr != this)
|
|
|
|
|
//{
|
|
|
|
|
// printf("Mouse enter");
|
|
|
|
|
//mCurrentWindow = this;
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// printf("Mouse exit");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} break;
|
|
|
|
|
|
|
|
|
|
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
|
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
|
|
|
|
case NS_MOUSE_RIGHT_BUTTON_DOWN:
|
|
|
|
|
result = ConvertStatus(mMouseListener->MousePressed(aEvent));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NS_MOUSE_LEFT_BUTTON_UP:
|
|
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
|
|
|
|
case NS_MOUSE_RIGHT_BUTTON_UP:
|
|
|
|
|
result = ConvertStatus(mMouseListener->MouseReleased(aEvent));
|
|
|
|
|
result = ConvertStatus(mMouseListener->MouseClicked(aEvent));
|
|
|
|
|
break;
|
|
|
|
|
} // switch
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
PRBool nsChildView::ReportDestroyEvent()
|
|
|
|
|
{
|
|
|
|
|
// nsEvent
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsGUIEvent event(NS_DESTROY, this);
|
|
|
|
|
event.time = PR_IntervalNow();
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
// dispatch event
|
2004-01-12 08:25:18 +00:00
|
|
|
|
return (DispatchWindowEvent(event));
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
PRBool nsChildView::ReportMoveEvent()
|
|
|
|
|
{
|
|
|
|
|
// nsEvent
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsGUIEvent moveEvent(NS_MOVE, this);
|
2001-11-06 15:35:24 +00:00
|
|
|
|
moveEvent.point.x = mBounds.x;
|
|
|
|
|
moveEvent.point.y = mBounds.y;
|
|
|
|
|
moveEvent.time = PR_IntervalNow();
|
|
|
|
|
|
|
|
|
|
// dispatch event
|
|
|
|
|
return (DispatchWindowEvent(moveEvent));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
PRBool nsChildView::ReportSizeEvent()
|
|
|
|
|
{
|
|
|
|
|
// nsEvent
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsSizeEvent sizeEvent(NS_SIZE, this);
|
2001-11-06 15:35:24 +00:00
|
|
|
|
sizeEvent.time = PR_IntervalNow();
|
|
|
|
|
|
|
|
|
|
// nsSizeEvent
|
|
|
|
|
sizeEvent.windowSize = &mBounds;
|
|
|
|
|
sizeEvent.mWinWidth = mBounds.width;
|
|
|
|
|
sizeEvent.mWinHeight = mBounds.height;
|
|
|
|
|
|
|
|
|
|
// dispatch event
|
|
|
|
|
return(DispatchWindowEvent(sizeEvent));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
void nsChildView::CalcWindowRegions()
|
|
|
|
|
{
|
|
|
|
|
// i don't think this is necessary anymore...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
/* Calculate the x and y offsets for this particular widget
|
|
|
|
|
* @update ps 09/22/98
|
|
|
|
|
* @param aX -- x offset amount
|
|
|
|
|
* @param aY -- y offset amount
|
|
|
|
|
* @return NOTHING
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsChildView::CalcOffset(PRInt32 &aX,PRInt32 &aY)
|
|
|
|
|
{
|
|
|
|
|
aX = aY = 0;
|
2001-11-29 22:37:48 +00:00
|
|
|
|
NSRect bounds = {{0, 0}, {0, 0}};
|
2001-11-06 15:35:24 +00:00
|
|
|
|
bounds = [mView convertRect:bounds toView:nil];
|
|
|
|
|
aX += NS_STATIC_CAST(PRInt32, bounds.origin.x);
|
|
|
|
|
aY += NS_STATIC_CAST(PRInt32, bounds.origin.y);
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
// PointInWidget
|
|
|
|
|
// Find if a point in local coordinates is inside this object
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
PRBool nsChildView::PointInWidget(Point aThePoint)
|
|
|
|
|
{
|
|
|
|
|
// get the origin in local coordinates
|
|
|
|
|
nsPoint widgetOrigin(0, 0);
|
|
|
|
|
LocalToWindowCoordinate(widgetOrigin);
|
|
|
|
|
|
|
|
|
|
// get rectangle relatively to the parent
|
|
|
|
|
nsRect widgetRect;
|
|
|
|
|
GetBounds(widgetRect);
|
|
|
|
|
|
|
|
|
|
// convert the topLeft corner to local coordinates
|
|
|
|
|
widgetRect.MoveBy(widgetOrigin.x, widgetOrigin.y);
|
|
|
|
|
|
|
|
|
|
// finally tell whether it's a hit
|
|
|
|
|
return(widgetRect.Contains(aThePoint.h, aThePoint.v));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
// WidgetToScreen
|
|
|
|
|
// Convert the given rect to global coordinates.
|
|
|
|
|
// @param aLocalRect -- rect in local coordinates of this widget
|
|
|
|
|
// @param aGlobalRect -- |aLocalRect| in global coordinates
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::WidgetToScreen(const nsRect& aLocalRect, nsRect& aGlobalRect)
|
|
|
|
|
{
|
|
|
|
|
NSRect temp;
|
|
|
|
|
ConvertGeckoToCocoaRect(aLocalRect, temp);
|
|
|
|
|
temp = [mView convertRect:temp toView:nil]; // convert to window coords
|
2002-02-13 19:57:10 +00:00
|
|
|
|
temp.origin = [[mView getNativeWindow] convertBaseToScreen:temp.origin]; // convert to screen coords
|
2001-11-06 15:35:24 +00:00
|
|
|
|
ConvertCocoaToGeckoRect(temp, aGlobalRect);
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
// ScreenToWidget
|
|
|
|
|
// Convert the given rect to local coordinates.
|
|
|
|
|
// @param aGlobalRect -- rect in screen coordinates
|
|
|
|
|
// @param aLocalRect -- |aGlobalRect| in coordinates of this widget
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP nsChildView::ScreenToWidget(const nsRect& aGlobalRect, nsRect& aLocalRect)
|
|
|
|
|
{
|
|
|
|
|
NSRect temp;
|
|
|
|
|
ConvertGeckoToCocoaRect(aGlobalRect, temp);
|
2002-02-13 19:57:10 +00:00
|
|
|
|
temp.origin = [[mView getNativeWindow] convertScreenToBase:temp.origin]; // convert to screen coords
|
2001-11-06 15:35:24 +00:00
|
|
|
|
temp = [mView convertRect:temp fromView:nil]; // convert to window coords
|
|
|
|
|
ConvertCocoaToGeckoRect(temp, aLocalRect);
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=================================================================
|
|
|
|
|
/* Convert the coordinates to some device coordinates so GFX can draw.
|
|
|
|
|
* @update dc 09/16/98
|
|
|
|
|
* @param nscoord -- X coordinate to convert
|
|
|
|
|
* @param nscoord -- Y coordinate to convert
|
|
|
|
|
* @return NONE
|
|
|
|
|
*/
|
|
|
|
|
void nsChildView::ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY)
|
|
|
|
|
{
|
|
|
|
|
PRInt32 offX = 0, offY = 0;
|
|
|
|
|
this->CalcOffset(offX,offY);
|
|
|
|
|
|
|
|
|
|
aX += offX;
|
|
|
|
|
aY += offY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsChildView::CaptureRollupEvents(nsIRollupListener * aListener,
|
|
|
|
|
PRBool aDoCapture,
|
|
|
|
|
PRBool aConsumeRollupEvent)
|
|
|
|
|
{
|
|
|
|
|
if (aDoCapture) {
|
|
|
|
|
NS_IF_RELEASE(gRollupListener);
|
|
|
|
|
NS_IF_RELEASE(gRollupWidget);
|
|
|
|
|
gRollupListener = aListener;
|
|
|
|
|
NS_ADDREF(aListener);
|
|
|
|
|
gRollupWidget = this;
|
|
|
|
|
NS_ADDREF(this);
|
|
|
|
|
} else {
|
|
|
|
|
NS_IF_RELEASE(gRollupListener);
|
|
|
|
|
//gRollupListener = nsnull;
|
|
|
|
|
NS_IF_RELEASE(gRollupWidget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-04-18 23:18:23 +00:00
|
|
|
|
NS_IMETHODIMP nsChildView::SetTitle(const nsAString& title)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
{
|
|
|
|
|
// nothing to do here
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-02-11 03:46:30 +00:00
|
|
|
|
NS_IMETHODIMP nsChildView::GetAttention(PRInt32 aCycleCount)
|
2001-11-06 15:35:24 +00:00
|
|
|
|
{
|
2003-03-24 04:15:34 +00:00
|
|
|
|
// Since the Mac doesn't consider each window a separate process this call functions
|
2001-11-06 15:35:24 +00:00
|
|
|
|
// slightly different than on other platforms. We first check to see if we're the
|
|
|
|
|
// foreground process and, if so, ignore the call. We also check to see if a notification
|
|
|
|
|
// is already pending and, if so, remove it since we only have one notification per process.
|
|
|
|
|
// After all that checking we install a notification manager request to mark the app's icon
|
|
|
|
|
// in the process menu and play the default alert sound
|
|
|
|
|
|
|
|
|
|
OSErr err;
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (WeAreFrontProcess())
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
|
|
if (gNotificationInstalled)
|
|
|
|
|
{
|
|
|
|
|
(void)::NMRemove(&gNMRec);
|
|
|
|
|
gNotificationInstalled = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = GetIconSuite( &gNMRec.nmIcon, 128, svAllSmallData );
|
|
|
|
|
if ( err != noErr )
|
|
|
|
|
gNMRec.nmIcon = NULL;
|
|
|
|
|
|
|
|
|
|
// Setup and install the notification manager rec
|
|
|
|
|
gNMRec.qType = nmType;
|
|
|
|
|
gNMRec.nmMark = 1; // Flag the icon in the process menu
|
|
|
|
|
gNMRec.nmSound = (Handle)-1L; // Use the default alert sound
|
|
|
|
|
gNMRec.nmStr = NULL; // No alert/window so no text
|
|
|
|
|
gNMRec.nmResp = NULL; // No response proc, use the default behavior
|
|
|
|
|
gNMRec.nmRefCon = NULL;
|
|
|
|
|
if (::NMInstall(&gNMRec) == noErr)
|
|
|
|
|
gNotificationInstalled = true;
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsChildView::ResetInputState()
|
|
|
|
|
{
|
2001-11-08 21:47:44 +00:00
|
|
|
|
#if 0
|
2001-11-06 15:35:24 +00:00
|
|
|
|
// currently, the nsMacEventHandler is owned by nsCocoaWindow, which is the top level window
|
|
|
|
|
// we delegate this call to its parent
|
|
|
|
|
nsCOMPtr<nsIWidget> parent = getter_AddRefs(GetParent());
|
|
|
|
|
NS_ASSERTION(parent, "cannot get parent");
|
|
|
|
|
if(parent)
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIKBStateControl> kb = do_QueryInterface(parent);
|
|
|
|
|
NS_ASSERTION(kb, "cannot get parent");
|
|
|
|
|
if(kb) {
|
|
|
|
|
return kb->ResetInputState();
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-11-08 21:47:44 +00:00
|
|
|
|
#endif
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return NS_ERROR_ABORT;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-12 05:00:57 +00:00
|
|
|
|
NS_IMETHODIMP nsChildView::SetIMEOpenState(PRBool aState)
|
|
|
|
|
{
|
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsChildView::GetIMEOpenState(PRBool* aState)
|
|
|
|
|
{
|
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
2004-11-13 11:27:09 +00:00
|
|
|
|
NS_IMETHODIMP nsChildView::CancelIMEComposition()
|
|
|
|
|
{
|
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
2001-11-14 22:29:25 +00:00
|
|
|
|
//
|
|
|
|
|
// GetQuickDrawPort
|
|
|
|
|
//
|
|
|
|
|
// Find a quickdraw port in which to draw (needed by GFX until it
|
|
|
|
|
// is converted to Cocoa). This must be overridden if CreateCocoaView()
|
|
|
|
|
// does not create something that inherits from NSQuickDrawView!
|
|
|
|
|
//
|
|
|
|
|
GrafPtr
|
2002-02-22 09:22:56 +00:00
|
|
|
|
nsChildView::GetQuickDrawPort()
|
2001-11-14 22:29:25 +00:00
|
|
|
|
{
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (mPluginPort)
|
|
|
|
|
return mPluginPort->port;
|
|
|
|
|
else
|
|
|
|
|
return (GrafPtr) [mView qdPort];
|
2001-11-14 22:29:25 +00:00
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
|
2002-04-23 03:55:19 +00:00
|
|
|
|
//
|
|
|
|
|
// DispatchEvent
|
|
|
|
|
//
|
|
|
|
|
// Handle an event coming into us and send it to gecko.
|
|
|
|
|
//
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
nsChildView::DispatchEvent ( void* anEvent, PRBool *_retval )
|
|
|
|
|
{
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// DragEvent
|
|
|
|
|
//
|
|
|
|
|
// The drag manager has let us know that something related to a drag has
|
|
|
|
|
// occurred in this window. It could be any number of things, ranging from
|
|
|
|
|
// a drop, to a drag enter/leave, or a drag over event. The actual event
|
|
|
|
|
// is passed in |aMessage| and is passed along to our event hanlder so Gecko
|
|
|
|
|
// knows about it.
|
|
|
|
|
//
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
nsChildView::DragEvent(PRUint32 aMessage, PRInt16 aMouseGlobalX, PRInt16 aMouseGlobalY,
|
|
|
|
|
PRUint16 aKeyModifiers, PRBool *_retval)
|
|
|
|
|
{
|
2002-04-26 20:24:02 +00:00
|
|
|
|
// ensure that this is going to a ChildView (not something else like a
|
|
|
|
|
// scrollbar). I think it's safe to just bail at this point if it's not
|
|
|
|
|
// what we expect it to be
|
|
|
|
|
if ( ![mView isKindOfClass:[ChildView class]] ) {
|
|
|
|
|
*_retval = PR_FALSE;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2002-04-23 03:55:19 +00:00
|
|
|
|
nsMouseEvent geckoEvent;
|
2002-04-25 22:40:00 +00:00
|
|
|
|
|
|
|
|
|
// we're given the point in global coordinates. We need to convert it to
|
|
|
|
|
// window coordinates for convert:message:toGeckoEvent
|
2002-04-23 03:55:19 +00:00
|
|
|
|
NSPoint pt; pt.x = aMouseGlobalX; pt.y = aMouseGlobalY;
|
2002-04-25 22:40:00 +00:00
|
|
|
|
[[mView window] convertScreenToBase:pt];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
[mView convert:pt message:aMessage modifiers:0 toGeckoEvent:&geckoEvent];
|
2002-04-23 03:55:19 +00:00
|
|
|
|
|
2002-04-25 22:40:00 +00:00
|
|
|
|
// XXXPINK
|
|
|
|
|
// hack, because we're currently getting the point in Carbon global coordinates,
|
|
|
|
|
// but obviously the cocoa views don't know how to convert those (because they
|
|
|
|
|
// use an entirely different coordinate system).
|
|
|
|
|
geckoEvent.point.x = 50; geckoEvent.point.y = 50;
|
|
|
|
|
//printf("mouse location is %d %d\n", geckoEvent.point.x, geckoEvent.point.y);
|
|
|
|
|
DispatchWindowEvent(geckoEvent);
|
|
|
|
|
|
|
|
|
|
// we handled the event
|
|
|
|
|
*_retval = PR_TRUE;
|
2002-04-23 03:55:19 +00:00
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Scroll
|
|
|
|
|
//
|
|
|
|
|
// Someone wants us to scroll in the current window, probably as the result
|
|
|
|
|
// of a scrollWheel event or external scrollbars. Pass along to the
|
|
|
|
|
// eventhandler.
|
|
|
|
|
//
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
nsChildView::Scroll ( PRBool aVertical, PRInt16 aNumLines, PRInt16 aMouseLocalX,
|
|
|
|
|
PRInt16 aMouseLocalY, PRBool *_retval )
|
|
|
|
|
{
|
|
|
|
|
#if 0
|
|
|
|
|
*_retval = PR_FALSE;
|
|
|
|
|
Point localPoint = {aMouseLocalY, aMouseLocalX};
|
|
|
|
|
if ( mMacEventHandler.get() )
|
|
|
|
|
*_retval = mMacEventHandler->Scroll(aVertical ? kEventMouseWheelAxisY : kEventMouseWheelAxisX,
|
|
|
|
|
aNumLines, localPoint);
|
|
|
|
|
#endif
|
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
nsChildView::Idle()
|
|
|
|
|
{
|
|
|
|
|
// do some idle stuff?
|
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
@implementation ChildView
|
|
|
|
|
|
2002-03-09 22:43:04 +00:00
|
|
|
|
-(NSMenu*)menuForEvent:(NSEvent*)theEvent
|
|
|
|
|
{
|
2002-03-09 22:58:13 +00:00
|
|
|
|
// Fire the context menu event into Gecko.
|
2002-12-13 08:43:18 +00:00
|
|
|
|
nsMouseEvent geckoEvent;
|
2002-03-09 22:58:13 +00:00
|
|
|
|
[self convert:theEvent message:NS_CONTEXTMENU toGeckoEvent:&geckoEvent];
|
|
|
|
|
|
|
|
|
|
// send event into Gecko by going directly to the
|
|
|
|
|
// the widget.
|
2002-03-10 02:04:21 +00:00
|
|
|
|
mGeckoChild->DispatchMouseEvent(geckoEvent);
|
2002-03-09 22:58:13 +00:00
|
|
|
|
|
2002-03-10 02:04:21 +00:00
|
|
|
|
// Go up our view chain to fetch the correct menu to return.
|
2002-04-12 09:39:59 +00:00
|
|
|
|
return [self getContextMenu];
|
2002-03-09 22:43:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-04-12 09:39:59 +00:00
|
|
|
|
-(NSMenu*)getContextMenu
|
|
|
|
|
{
|
|
|
|
|
return [[self superview] getContextMenu];
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// initWithGeckoChild:eventSink:
|
|
|
|
|
//
|
|
|
|
|
// do init stuff
|
|
|
|
|
//
|
|
|
|
|
- (id)initWithGeckoChild:(nsChildView*)inChild eventSink:(nsIEventSink*)inSink
|
|
|
|
|
{
|
|
|
|
|
[super init];
|
|
|
|
|
|
|
|
|
|
mGeckoChild = inChild;
|
|
|
|
|
mEventSink = inSink;
|
2002-04-27 00:19:49 +00:00
|
|
|
|
mIsPluginView = NO;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
mLastKeyEventWasSentToCocoa = NO;
|
|
|
|
|
mCurEvent = NULL;
|
2004-06-16 05:55:44 +00:00
|
|
|
|
|
|
|
|
|
// See if hack code for enabling and disabling mouse move
|
|
|
|
|
// events is necessary. Fixed by at least 10.2.8
|
|
|
|
|
long version = 0;
|
|
|
|
|
::Gestalt(gestaltSystemVersion, &version);
|
|
|
|
|
mToggleMouseMoveEventWatching = (version < 0x00001028);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
|
|
|
|
// initialization for NSTextInput
|
|
|
|
|
mMarkedRange.location = NSNotFound;
|
|
|
|
|
mMarkedRange.length = 0;
|
|
|
|
|
mSelectedRange.location = NSNotFound;
|
|
|
|
|
mSelectedRange.length = 0;
|
|
|
|
|
mInComposition = NO;
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-02-13 19:57:10 +00:00
|
|
|
|
- (NSWindow*) getNativeWindow
|
|
|
|
|
{
|
|
|
|
|
NSWindow* currWin = [self window];
|
|
|
|
|
if (currWin)
|
|
|
|
|
return currWin;
|
|
|
|
|
else
|
|
|
|
|
return mWindow;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) setNativeWindow: (NSWindow*)aWindow
|
|
|
|
|
{
|
|
|
|
|
mWindow = aWindow;
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
|
{
|
2002-12-13 08:43:18 +00:00
|
|
|
|
[super dealloc]; // this sets the current port to _savePort
|
|
|
|
|
SetPort(NULL); // this is safe on OS X; it will set the port to
|
|
|
|
|
// an empty fallback port.
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-03-13 20:37:32 +00:00
|
|
|
|
// Find the nearest scrollable view for this ChildView.
|
|
|
|
|
- (nsIScrollableView*) getScrollableView
|
|
|
|
|
{
|
|
|
|
|
nsIScrollableView* aScrollableView = nil;
|
|
|
|
|
ChildView* currView = self;
|
|
|
|
|
// we have to loop up through superviews in case the view that received the
|
|
|
|
|
// mouseDown is in fact a plugin view with no scrollbars
|
|
|
|
|
while (!aScrollableView && currView) {
|
|
|
|
|
|
|
|
|
|
// This is a hack I learned in nsView::GetViewFor(nsIWidget* aWidget)
|
|
|
|
|
// that I'm not sure is kosher. If anyone knows a better way to get
|
|
|
|
|
// the view for a widget, I'd love to hear it. --Nathan
|
|
|
|
|
|
|
|
|
|
void* clientData;
|
|
|
|
|
[currView widget]->GetClientData(clientData);
|
|
|
|
|
|
|
|
|
|
nsISupports* data = (nsISupports*)clientData;
|
2004-09-20 12:51:31 +00:00
|
|
|
|
nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(data));
|
|
|
|
|
if (req)
|
|
|
|
|
req->GetInterface(NS_GET_IID(nsIScrollableView), &aScrollableView);
|
2003-03-13 20:37:32 +00:00
|
|
|
|
|
|
|
|
|
if ([[currView superview] isMemberOfClass:[ChildView class]])
|
|
|
|
|
currView = [currView superview];
|
|
|
|
|
else
|
|
|
|
|
currView = nil;
|
|
|
|
|
}
|
|
|
|
|
return aScrollableView;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set the closed hand cursor and record the starting scroll positions
|
|
|
|
|
- (void) startHandScroll:(NSEvent*)theEvent
|
|
|
|
|
{
|
|
|
|
|
mHandScrollStartMouseLoc = [[self window] convertBaseToScreen: [theEvent locationInWindow]];
|
|
|
|
|
|
|
|
|
|
nsIScrollableView* aScrollableView = [self getScrollableView];
|
|
|
|
|
|
|
|
|
|
// if we succeeded in getting aScrollableView
|
|
|
|
|
if (aScrollableView) {
|
|
|
|
|
aScrollableView->GetScrollPosition(mHandScrollStartScrollX, mHandScrollStartScrollY);
|
|
|
|
|
mGeckoChild->SetCursor(eCursor_grabbing);
|
|
|
|
|
mInHandScroll = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// update the scroll position based on the new mouse coordinates
|
|
|
|
|
- (void) updateHandScroll:(NSEvent*)theEvent
|
|
|
|
|
{
|
|
|
|
|
nsIScrollableView* aScrollableView = [self getScrollableView];
|
|
|
|
|
if (!aScrollableView)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
NSPoint newMouseLoc = [[self window] convertBaseToScreen: [theEvent locationInWindow]];
|
|
|
|
|
|
|
|
|
|
PRInt32 deltaX = (PRInt32)(mHandScrollStartMouseLoc.x - newMouseLoc.x);
|
|
|
|
|
PRInt32 deltaY = (PRInt32)(newMouseLoc.y - mHandScrollStartMouseLoc.y);
|
|
|
|
|
|
|
|
|
|
// convert to the nsIView coordinates
|
|
|
|
|
float mPixelsToTwips = 1.0;
|
2004-02-05 01:57:10 +00:00
|
|
|
|
mPixelsToTwips = mGeckoChild->GetDeviceContext()->DevUnitsToAppUnits();
|
2003-03-13 20:37:32 +00:00
|
|
|
|
nscoord newX = mHandScrollStartScrollX +
|
|
|
|
|
NSIntPixelsToTwips(deltaX, mPixelsToTwips);
|
|
|
|
|
nscoord newY = mHandScrollStartScrollY +
|
|
|
|
|
NSIntPixelsToTwips(deltaY, mPixelsToTwips);
|
|
|
|
|
aScrollableView->ScrollTo(newX, newY, NS_VMREFRESH_IMMEDIATE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// reset the scroll flag and cursor
|
|
|
|
|
- (void) stopHandScroll:(NSEvent*)theEvent
|
|
|
|
|
{
|
|
|
|
|
mInHandScroll = FALSE;
|
|
|
|
|
|
|
|
|
|
// calling flagsChanged will set the cursor appropriately
|
|
|
|
|
[self flagsChanged:theEvent];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return true if the correct modifiers are pressed to perform hand scrolling.
|
|
|
|
|
+ (BOOL) areHandScrollModifiers:(unsigned int)modifiers
|
|
|
|
|
{
|
2003-12-09 20:53:45 +00:00
|
|
|
|
// The command and option key should be held down; ignore caps lock. We only
|
|
|
|
|
// check the low word because Apple started using it in panther for other purposes
|
|
|
|
|
// (no idea what).
|
|
|
|
|
modifiers |= NSAlphaShiftKeyMask; // ignore capsLock by setting it explicitly to match
|
|
|
|
|
return modifiers >> 16 == (NSAlphaShiftKeyMask | NSCommandKeyMask | NSAlternateKeyMask) >> 16;
|
2003-03-13 20:37:32 +00:00
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// -setFrame
|
|
|
|
|
//
|
|
|
|
|
// Override in order to keep our mouse enter/exit tracking rect in sync with
|
|
|
|
|
// the frame of the view
|
|
|
|
|
//
|
|
|
|
|
- (void)setFrame:(NSRect)frameRect
|
|
|
|
|
{
|
|
|
|
|
[super setFrame:frameRect];
|
2003-03-13 20:37:32 +00:00
|
|
|
|
if (mMouseEnterExitTag)
|
|
|
|
|
[self removeTrackingRect:mMouseEnterExitTag];
|
|
|
|
|
|
|
|
|
|
mMouseEnterExitTag = [self addTrackingRect:[self bounds] owner:self
|
2004-05-07 23:46:57 +00:00
|
|
|
|
userData:nil assumeInside: [[self window]
|
|
|
|
|
acceptsMouseMovedEvents]];
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// -isFlipped
|
|
|
|
|
//
|
|
|
|
|
// Make the origin of this view the topLeft corner (gecko origin) rather
|
|
|
|
|
// than the bottomLeft corner (standard cocoa origin).
|
|
|
|
|
//
|
|
|
|
|
- (BOOL)isFlipped
|
|
|
|
|
{
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
|
2002-02-20 01:07:39 +00:00
|
|
|
|
// -isOpaque
|
|
|
|
|
//
|
|
|
|
|
// XXXdwh. Quickdraw views are transparent by default. Since Gecko does its own blending if/when
|
|
|
|
|
// opacity is specified, we would like to optimize here by turning off the transparency of the view.
|
|
|
|
|
// But we can't. :(
|
|
|
|
|
- (BOOL)isOpaque
|
|
|
|
|
{
|
2002-04-27 00:19:49 +00:00
|
|
|
|
return mIsPluginView;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-(void)setIsPluginView:(BOOL)aIsPlugin
|
|
|
|
|
{
|
|
|
|
|
mIsPluginView = aIsPlugin;
|
2002-02-20 01:07:39 +00:00
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
-(BOOL)getIsPluginView
|
|
|
|
|
{
|
|
|
|
|
return mIsPluginView;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL)childViewHasPlugin
|
|
|
|
|
{
|
|
|
|
|
NSArray* subviews = [self subviews];
|
|
|
|
|
for (unsigned int i = 0; i < [subviews count]; i ++)
|
|
|
|
|
{
|
|
|
|
|
id subview = [subviews objectAtIndex:i];
|
|
|
|
|
if ([subview respondsToSelector:@selector(getIsPluginView)] && [subview getIsPluginView])
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//
|
|
|
|
|
// -acceptsFirstResponder
|
|
|
|
|
//
|
|
|
|
|
// We accept key and mouse events, so don't keep passing them up the chain. Allow
|
|
|
|
|
// this to be a 'focussed' widget for event dispatch
|
|
|
|
|
//
|
|
|
|
|
- (BOOL)acceptsFirstResponder
|
|
|
|
|
{
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
- (void)viewWillMoveToWindow:(NSWindow *)newWindow
|
|
|
|
|
{
|
|
|
|
|
if (mGeckoChild && !newWindow)
|
|
|
|
|
mGeckoChild->RemovedFromWindow();
|
2003-03-13 20:37:32 +00:00
|
|
|
|
if (mMouseEnterExitTag)
|
|
|
|
|
[self removeTrackingRect:mMouseEnterExitTag];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)viewDidMoveToWindow
|
|
|
|
|
{
|
|
|
|
|
if (mGeckoChild && [self window])
|
|
|
|
|
mGeckoChild->AddedToWindow();
|
2003-03-13 20:37:32 +00:00
|
|
|
|
|
|
|
|
|
mMouseEnterExitTag = [self addTrackingRect:[self bounds] owner:self
|
2004-05-07 23:46:57 +00:00
|
|
|
|
userData:nil assumeInside: [[self window]
|
|
|
|
|
acceptsMouseMovedEvents]];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)viewWillStartLiveResize
|
|
|
|
|
{
|
|
|
|
|
if (mGeckoChild && mIsPluginView)
|
|
|
|
|
mGeckoChild->LiveResizeStarted();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)viewDidEndLiveResize
|
|
|
|
|
{
|
|
|
|
|
if (mGeckoChild && mIsPluginView)
|
|
|
|
|
mGeckoChild->LiveResizeEnded();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL)mouseDownCanMoveWindow
|
|
|
|
|
{
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// -drawRect:
|
|
|
|
|
//
|
|
|
|
|
// The display system has told us that a portion of our view is dirty. Tell
|
|
|
|
|
// gecko to paint it
|
|
|
|
|
//
|
|
|
|
|
- (void)drawRect:(NSRect)aRect
|
|
|
|
|
{
|
2002-02-17 19:09:07 +00:00
|
|
|
|
PRBool isVisible;
|
|
|
|
|
mGeckoChild->IsVisible(isVisible);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (!isVisible) {
|
2002-02-17 19:09:07 +00:00
|
|
|
|
return;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
2002-02-17 19:09:07 +00:00
|
|
|
|
|
2004-05-07 01:16:14 +00:00
|
|
|
|
// tell gecko to paint.
|
|
|
|
|
// If < 10.3, just paint the rect
|
|
|
|
|
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_2) {
|
|
|
|
|
nsRect r;
|
|
|
|
|
ConvertCocoaToGeckoRect(aRect, r);
|
|
|
|
|
nsCOMPtr<nsIRenderingContext> rendContext = getter_AddRefs(mGeckoChild->GetRenderingContext());
|
|
|
|
|
mGeckoChild->UpdateWidget(r, rendContext);
|
|
|
|
|
}
|
|
|
|
|
// If >10.3, only paint the sub-rects that need it. This avoids the
|
|
|
|
|
// nasty coalesced updates that result in big white areas.
|
|
|
|
|
else {
|
|
|
|
|
const NSRect *rects;
|
|
|
|
|
int count, i;
|
|
|
|
|
[self getRectsBeingDrawn:&rects count:&count];
|
|
|
|
|
for (i=0; i<count; ++i) {
|
|
|
|
|
nsRect r;
|
|
|
|
|
ConvertCocoaToGeckoRect(rects[i], r);
|
|
|
|
|
nsCOMPtr<nsIRenderingContext> rendContext = getter_AddRefs(mGeckoChild->GetRenderingContext());
|
|
|
|
|
mGeckoChild->UpdateWidget(r, rendContext);
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-05-07 07:17:41 +00:00
|
|
|
|
//
|
|
|
|
|
// -wantsDefaultClipping
|
|
|
|
|
//
|
|
|
|
|
// A panther-only method, allows us to turn off setting up the clip region
|
|
|
|
|
// before each drawRect. We already clip within gecko.
|
|
|
|
|
//
|
|
|
|
|
- (BOOL)wantsDefaultClipping
|
|
|
|
|
{
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
2004-02-18 16:18:38 +00:00
|
|
|
|
#if USE_CLICK_HOLD_CONTEXTMENU
|
2004-01-15 19:01:49 +00:00
|
|
|
|
//
|
|
|
|
|
// -clickHoldCallback:
|
|
|
|
|
//
|
|
|
|
|
// called from a timer two seconds after a mouse down to see if we should display
|
|
|
|
|
// a context menu (click-hold). |anEvent| is the original mouseDown event. If we're
|
|
|
|
|
// still in that mouseDown by this time, put up the context menu, otherwise just
|
|
|
|
|
// fuhgeddaboutit. |anEvent| has been retained by the OS until after this callback
|
|
|
|
|
// fires so we're ok there.
|
|
|
|
|
//
|
2004-02-18 16:18:38 +00:00
|
|
|
|
// This code currently messes in a bunch of edge cases (bugs 234751, 232964, 232314)
|
|
|
|
|
// so removing it until we get it straightened out.
|
|
|
|
|
//
|
2004-01-15 19:01:49 +00:00
|
|
|
|
- (void)clickHoldCallback:(id)theEvent;
|
|
|
|
|
{
|
|
|
|
|
if( theEvent == [NSApp currentEvent] ) {
|
|
|
|
|
// we're still in the middle of the same mousedown event here, activate
|
|
|
|
|
// click-hold context menu by triggering the right mouseDown action.
|
|
|
|
|
NSEvent* clickHoldEvent = [NSEvent mouseEventWithType:NSRightMouseDown
|
|
|
|
|
location:[theEvent locationInWindow]
|
|
|
|
|
modifierFlags:[theEvent modifierFlags]
|
|
|
|
|
timestamp:[theEvent timestamp]
|
|
|
|
|
windowNumber:[theEvent windowNumber]
|
|
|
|
|
context:[theEvent context]
|
|
|
|
|
eventNumber:[theEvent eventNumber]
|
|
|
|
|
clickCount:[theEvent clickCount]
|
|
|
|
|
pressure:[theEvent pressure]];
|
|
|
|
|
[self rightMouseDown:clickHoldEvent];
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-02-18 16:18:38 +00:00
|
|
|
|
#endif
|
2004-01-15 19:01:49 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
- (void)mouseDown:(NSEvent *)theEvent
|
|
|
|
|
{
|
2003-03-13 20:37:32 +00:00
|
|
|
|
// if the command and alt keys are held down, initiate hand scrolling
|
|
|
|
|
if ([ChildView areHandScrollModifiers:[theEvent modifierFlags]]) {
|
|
|
|
|
[self startHandScroll: theEvent];
|
2003-03-18 19:13:47 +00:00
|
|
|
|
// needed to change the focus, among other things, since we don't
|
2004-01-15 19:01:49 +00:00
|
|
|
|
// get to do that below.
|
2003-03-18 19:13:47 +00:00
|
|
|
|
[super mouseDown:theEvent];
|
2003-03-18 18:57:17 +00:00
|
|
|
|
return; // do not pass this mousedown event to gecko
|
2003-03-13 20:37:32 +00:00
|
|
|
|
}
|
2004-01-15 19:01:49 +00:00
|
|
|
|
|
2004-02-18 16:18:38 +00:00
|
|
|
|
#if USE_CLICK_HOLD_CONTEXTMENU
|
2004-01-15 19:01:49 +00:00
|
|
|
|
// fire off timer to check for click-hold after two seconds. retains |theEvent|
|
|
|
|
|
[self performSelector:@selector(clickHoldCallback:) withObject:theEvent afterDelay:2.0];
|
2004-02-18 16:18:38 +00:00
|
|
|
|
#endif
|
2004-01-15 19:01:49 +00:00
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
nsMouseEvent geckoEvent;
|
|
|
|
|
[self convert:theEvent message:NS_MOUSE_LEFT_BUTTON_DOWN toGeckoEvent:&geckoEvent];
|
|
|
|
|
geckoEvent.clickCount = [theEvent clickCount];
|
|
|
|
|
|
2002-04-27 00:19:49 +00:00
|
|
|
|
NSPoint mouseLoc = [theEvent locationInWindow];
|
|
|
|
|
NSPoint screenLoc = [[self window] convertBaseToScreen: mouseLoc];
|
|
|
|
|
|
|
|
|
|
EventRecord macEvent;
|
|
|
|
|
macEvent.what = mouseDown;
|
|
|
|
|
macEvent.message = 0;
|
|
|
|
|
macEvent.when = ::TickCount();
|
|
|
|
|
// macEvent.where.h = screenLoc.x, macEvent.where.v = screenLoc.y; XXX fix this, they are flipped!
|
|
|
|
|
GetGlobalMouse(&macEvent.where);
|
|
|
|
|
macEvent.modifiers = GetCurrentKeyModifiers();
|
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
// send event into Gecko by going directly to the
|
|
|
|
|
// the widget.
|
|
|
|
|
mGeckoChild->DispatchMouseEvent(geckoEvent);
|
|
|
|
|
|
|
|
|
|
} // mouseDown
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (void)mouseUp:(NSEvent *)theEvent
|
|
|
|
|
{
|
2003-03-13 20:37:32 +00:00
|
|
|
|
if (mInHandScroll) {
|
|
|
|
|
[self updateHandScroll:theEvent];
|
|
|
|
|
[self stopHandScroll:theEvent];
|
|
|
|
|
return;
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
nsMouseEvent geckoEvent;
|
|
|
|
|
[self convert:theEvent message:NS_MOUSE_LEFT_BUTTON_UP toGeckoEvent:&geckoEvent];
|
|
|
|
|
|
2002-04-27 00:19:49 +00:00
|
|
|
|
NSPoint mouseLoc = [theEvent locationInWindow];
|
|
|
|
|
NSPoint screenLoc = [[self window] convertBaseToScreen: mouseLoc];
|
|
|
|
|
|
|
|
|
|
EventRecord macEvent;
|
|
|
|
|
macEvent.what = mouseUp;
|
|
|
|
|
macEvent.message = 0;
|
|
|
|
|
macEvent.when = ::TickCount();
|
|
|
|
|
// macEvent.where.h = screenLoc.x, macEvent.where.v = screenLoc.y; XXX fix this, they are flipped!
|
|
|
|
|
GetGlobalMouse(&macEvent.where);
|
|
|
|
|
macEvent.modifiers = GetCurrentKeyModifiers();
|
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
// send event into Gecko by going directly to the
|
|
|
|
|
// the widget.
|
|
|
|
|
mGeckoChild->DispatchMouseEvent(geckoEvent);
|
|
|
|
|
|
|
|
|
|
} // mouseUp
|
|
|
|
|
|
|
|
|
|
- (void)mouseMoved:(NSEvent*)theEvent
|
|
|
|
|
{
|
2002-02-22 01:58:21 +00:00
|
|
|
|
NSView* view = [[[self window] contentView] hitTest: [theEvent locationInWindow]];
|
|
|
|
|
if (view != (NSView*)self) {
|
|
|
|
|
// We shouldn't handle this. Send it to the right view.
|
|
|
|
|
[view mouseMoved: theEvent];
|
|
|
|
|
return;
|
|
|
|
|
}
|
2003-03-13 20:37:32 +00:00
|
|
|
|
// check if we are in a hand scroll or if the user
|
|
|
|
|
// has command and alt held down; if so, we do not want
|
|
|
|
|
// gecko messing with the cursor.
|
|
|
|
|
if ([ChildView areHandScrollModifiers:[theEvent modifierFlags]]) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
nsMouseEvent geckoEvent;
|
|
|
|
|
[self convert:theEvent message:NS_MOUSE_MOVE toGeckoEvent:&geckoEvent];
|
|
|
|
|
|
2002-04-27 00:19:49 +00:00
|
|
|
|
NSPoint mouseLoc = [theEvent locationInWindow];
|
|
|
|
|
NSPoint screenLoc = [[self window] convertBaseToScreen: mouseLoc];
|
|
|
|
|
|
|
|
|
|
EventRecord macEvent;
|
|
|
|
|
macEvent.what = nullEvent;
|
|
|
|
|
macEvent.message = 0;
|
|
|
|
|
macEvent.when = ::TickCount();
|
|
|
|
|
// macEvent.where.h = screenLoc.x, macEvent.where.v = screenLoc.y; XXX fix this, they are flipped!
|
|
|
|
|
GetGlobalMouse(&macEvent.where);
|
|
|
|
|
macEvent.modifiers = GetCurrentKeyModifiers();
|
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
// send event into Gecko by going directly to the
|
|
|
|
|
// the widget.
|
|
|
|
|
mGeckoChild->DispatchMouseEvent(geckoEvent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)mouseDragged:(NSEvent*)theEvent
|
|
|
|
|
{
|
2003-03-13 20:37:32 +00:00
|
|
|
|
// if the handscroll flag is set, steal this event
|
|
|
|
|
if (mInHandScroll) {
|
|
|
|
|
[self updateHandScroll:theEvent];
|
|
|
|
|
return;
|
|
|
|
|
}
|
2002-12-13 08:43:18 +00:00
|
|
|
|
nsMouseEvent geckoEvent;
|
|
|
|
|
[self convert:theEvent message:NS_MOUSE_MOVE toGeckoEvent:&geckoEvent];
|
|
|
|
|
|
|
|
|
|
EventRecord macEvent;
|
|
|
|
|
macEvent.what = nullEvent;
|
|
|
|
|
macEvent.message = 0;
|
|
|
|
|
macEvent.when = ::TickCount();
|
|
|
|
|
// macEvent.where.h = screenLoc.x, macEvent.where.v = screenLoc.y; XXX fix this, they are flipped!
|
|
|
|
|
GetGlobalMouse(&macEvent.where);
|
|
|
|
|
macEvent.modifiers = btnState | GetCurrentKeyModifiers();
|
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
|
|
|
|
|
|
|
|
|
// send event into Gecko by going directly to the
|
|
|
|
|
// the widget.
|
|
|
|
|
mGeckoChild->DispatchMouseEvent(geckoEvent);
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)mouseEntered:(NSEvent*)theEvent
|
|
|
|
|
{
|
2003-03-13 20:37:32 +00:00
|
|
|
|
// checks to see if we should change to the hand cursor
|
|
|
|
|
[self flagsChanged:theEvent];
|
2004-06-16 05:55:44 +00:00
|
|
|
|
|
2003-04-21 23:06:08 +00:00
|
|
|
|
// we need to forward mouse move events to gecko when the mouse
|
|
|
|
|
// is over a gecko view
|
2004-06-16 05:55:44 +00:00
|
|
|
|
if (mToggleMouseMoveEventWatching)
|
|
|
|
|
[[self window] setAcceptsMouseMovedEvents: YES];
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)mouseExited:(NSEvent*)theEvent
|
|
|
|
|
{
|
2003-06-03 20:40:34 +00:00
|
|
|
|
// Gecko may have set the cursor to ibeam or link hand, or handscroll may
|
|
|
|
|
// have set it to the open hand cursor. Cocoa won't call this during a drag.
|
|
|
|
|
mGeckoChild->SetCursor(eCursor_standard);
|
2004-06-16 05:55:44 +00:00
|
|
|
|
|
2003-07-18 01:16:41 +00:00
|
|
|
|
// no need to monitor mouse movements outside of the gecko view,
|
|
|
|
|
// but make sure we are not a plugin view.
|
2004-06-16 05:55:44 +00:00
|
|
|
|
if (mToggleMouseMoveEventWatching && ![[self superview] isKindOfClass: [ChildView class]])
|
2003-07-18 01:16:41 +00:00
|
|
|
|
[[self window] setAcceptsMouseMovedEvents: NO];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)rightMouseDown:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
// The right mouse went down. Fire off a right mouse down and
|
|
|
|
|
// then send the context menu event.
|
|
|
|
|
nsMouseEvent geckoEvent;
|
|
|
|
|
|
|
|
|
|
[self convert: theEvent message: NS_MOUSE_RIGHT_BUTTON_DOWN toGeckoEvent:&geckoEvent];
|
|
|
|
|
|
|
|
|
|
// plugins need a native event here
|
|
|
|
|
EventRecord macEvent;
|
|
|
|
|
macEvent.what = mouseDown;
|
|
|
|
|
macEvent.message = 0;
|
|
|
|
|
macEvent.when = ::TickCount();
|
|
|
|
|
GetGlobalMouse(&macEvent.where);
|
|
|
|
|
macEvent.modifiers = controlKey; // fake a context menu click
|
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
|
|
|
|
|
|
|
|
|
geckoEvent.clickCount = [theEvent clickCount];
|
|
|
|
|
PRBool handled = mGeckoChild->DispatchMouseEvent(geckoEvent);
|
|
|
|
|
if (!handled)
|
|
|
|
|
[super rightMouseDown:theEvent]; // let the superview do context menu stuff
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)rightMouseUp:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
nsMouseEvent geckoEvent;
|
|
|
|
|
|
|
|
|
|
[self convert: theEvent message: NS_MOUSE_RIGHT_BUTTON_UP toGeckoEvent:&geckoEvent];
|
|
|
|
|
|
|
|
|
|
// plugins need a native event here
|
|
|
|
|
EventRecord macEvent;
|
|
|
|
|
macEvent.what = mouseUp;
|
|
|
|
|
macEvent.message = 0;
|
|
|
|
|
macEvent.when = ::TickCount();
|
|
|
|
|
GetGlobalMouse(&macEvent.where);
|
|
|
|
|
macEvent.modifiers = controlKey; // fake a context menu click
|
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
|
|
|
|
|
|
|
|
|
geckoEvent.clickCount = [theEvent clickCount];
|
|
|
|
|
PRBool handled = mGeckoChild->DispatchMouseEvent(geckoEvent);
|
|
|
|
|
if (!handled)
|
|
|
|
|
[super rightMouseUp:theEvent];
|
2001-11-06 15:35:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-09 23:09:34 +00:00
|
|
|
|
- (void)otherMouseDown:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
nsMouseEvent geckoEvent;
|
|
|
|
|
[self convert:theEvent message:NS_MOUSE_MIDDLE_BUTTON_DOWN toGeckoEvent:&geckoEvent];
|
|
|
|
|
geckoEvent.clickCount = [theEvent clickCount];
|
|
|
|
|
|
|
|
|
|
// send event into Gecko by going directly to the
|
|
|
|
|
// the widget.
|
|
|
|
|
mGeckoChild->DispatchMouseEvent(geckoEvent);
|
|
|
|
|
|
|
|
|
|
} // otherMouseDown
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (void)otherMouseUp:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
nsMouseEvent geckoEvent;
|
|
|
|
|
[self convert:theEvent message:NS_MOUSE_MIDDLE_BUTTON_UP toGeckoEvent:&geckoEvent];
|
|
|
|
|
|
|
|
|
|
// send event into Gecko by going directly to the
|
|
|
|
|
// the widget.
|
|
|
|
|
mGeckoChild->DispatchMouseEvent(geckoEvent);
|
|
|
|
|
|
|
|
|
|
} // mouseUp
|
|
|
|
|
|
2002-04-24 00:52:38 +00:00
|
|
|
|
const PRInt32 kNumLines = 4;
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
2002-02-17 19:09:07 +00:00
|
|
|
|
-(void)scrollWheel:(NSEvent*)theEvent
|
|
|
|
|
{
|
|
|
|
|
// XXXdwh. We basically always get 1 or -1 as the delta. This is treated by
|
|
|
|
|
// Gecko as the number of lines to scroll. We go ahead and use a
|
2002-12-13 08:43:18 +00:00
|
|
|
|
// default kNumLines of 4 for now (until I learn how we can get settings from
|
2002-02-17 19:09:07 +00:00
|
|
|
|
// the OS). --dwh
|
|
|
|
|
nsMouseScrollEvent geckoEvent;
|
2003-01-08 06:43:08 +00:00
|
|
|
|
|
2002-02-17 19:09:07 +00:00
|
|
|
|
[self convert:theEvent message:NS_MOUSE_SCROLL toGeckoEvent:&geckoEvent];
|
2003-01-08 06:43:08 +00:00
|
|
|
|
PRInt32 incomingDeltaX = (PRInt32)[theEvent deltaX];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
PRInt32 incomingDeltaY = (PRInt32)[theEvent deltaY];
|
2003-01-08 06:43:08 +00:00
|
|
|
|
|
|
|
|
|
PRInt32 scrollDelta = 0;
|
|
|
|
|
if (incomingDeltaY != 0)
|
|
|
|
|
{
|
|
|
|
|
geckoEvent.scrollFlags |= nsMouseScrollEvent::kIsVertical;
|
|
|
|
|
scrollDelta = incomingDeltaY;
|
|
|
|
|
}
|
|
|
|
|
else if (incomingDeltaX != 0)
|
|
|
|
|
{
|
|
|
|
|
geckoEvent.scrollFlags |= nsMouseScrollEvent::kIsHorizontal;
|
|
|
|
|
scrollDelta = incomingDeltaX;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
// Use hasJaguarAppKit to determine if we're on 10.2 where the user has control
|
|
|
|
|
// over the deltaY from a scrollwheel event via the Mouse panel in System Preferences
|
|
|
|
|
if (hasJaguarAppKit())
|
2003-01-08 06:43:08 +00:00
|
|
|
|
geckoEvent.delta = -scrollDelta;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
else
|
2003-01-08 06:43:08 +00:00
|
|
|
|
geckoEvent.delta = scrollDelta * -kNumLines;
|
|
|
|
|
|
2002-02-17 19:09:07 +00:00
|
|
|
|
// send event into Gecko by going directly to the
|
|
|
|
|
// the widget.
|
|
|
|
|
mGeckoChild->DispatchWindowEvent(geckoEvent);
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// -convert:message:toGeckoEvent:
|
|
|
|
|
//
|
2002-04-23 03:55:19 +00:00
|
|
|
|
// convert from one event system to the other for event dispatching
|
2001-11-06 15:35:24 +00:00
|
|
|
|
//
|
|
|
|
|
- (void) convert:(NSEvent*)inEvent message:(PRInt32)inMsg toGeckoEvent:(nsInputEvent*)outGeckoEvent
|
2002-04-23 03:55:19 +00:00
|
|
|
|
{
|
|
|
|
|
outGeckoEvent->nativeMsg = inEvent;
|
|
|
|
|
[self convert:[inEvent locationInWindow] message:inMsg modifiers:[inEvent modifierFlags]
|
|
|
|
|
toGeckoEvent:outGeckoEvent];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) convert:(NSPoint)inPoint message:(PRInt32)inMsg modifiers:(unsigned int)inMods toGeckoEvent:(nsInputEvent*)outGeckoEvent
|
2001-11-06 15:35:24 +00:00
|
|
|
|
{
|
|
|
|
|
outGeckoEvent->message = inMsg;
|
|
|
|
|
outGeckoEvent->widget = [self widget];
|
|
|
|
|
outGeckoEvent->time = PR_IntervalNow();
|
2002-02-22 08:44:16 +00:00
|
|
|
|
|
|
|
|
|
if (outGeckoEvent->eventStructType != NS_KEY_EVENT) {
|
2002-04-23 03:55:19 +00:00
|
|
|
|
NSPoint mouseLoc = inPoint;
|
2002-02-22 08:44:16 +00:00
|
|
|
|
|
|
|
|
|
// convert point to view coordinate system
|
|
|
|
|
NSPoint localPoint = [self convertPoint:mouseLoc fromView:nil];
|
2002-03-11 23:31:39 +00:00
|
|
|
|
outGeckoEvent->refPoint.x = outGeckoEvent->point.x = NS_STATIC_CAST(nscoord, localPoint.x);
|
|
|
|
|
outGeckoEvent->refPoint.y = outGeckoEvent->point.y = NS_STATIC_CAST(nscoord, localPoint.y);
|
2002-02-26 00:42:32 +00:00
|
|
|
|
|
2002-02-22 08:44:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set up modifier keys
|
2002-04-23 03:55:19 +00:00
|
|
|
|
outGeckoEvent->isShift = ((inMods & NSShiftKeyMask) != 0);
|
|
|
|
|
outGeckoEvent->isControl = ((inMods & NSControlKeyMask) != 0);
|
|
|
|
|
outGeckoEvent->isAlt = ((inMods & NSAlternateKeyMask) != 0);
|
|
|
|
|
outGeckoEvent->isMeta = ((inMods & NSCommandKeyMask) != 0);
|
|
|
|
|
}
|
2001-11-06 15:35:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// -widget
|
|
|
|
|
//
|
|
|
|
|
// return our gecko child view widget. Note this does not AddRef.
|
|
|
|
|
//
|
|
|
|
|
- (nsIWidget*) widget
|
|
|
|
|
{
|
|
|
|
|
return NS_STATIC_CAST(nsIWidget*, mGeckoChild);
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
static PRBool ConvertUnicodeToCharCode(PRUnichar inUniChar, unsigned char* outChar)
|
2002-06-11 22:13:03 +00:00
|
|
|
|
{
|
2002-12-13 08:43:18 +00:00
|
|
|
|
UnicodeToTextInfo converterInfo;
|
|
|
|
|
TextEncoding systemEncoding;
|
|
|
|
|
Str255 convertedString;
|
|
|
|
|
OSStatus err;
|
|
|
|
|
|
|
|
|
|
*outChar = 0;
|
|
|
|
|
|
|
|
|
|
err = ::UpgradeScriptInfoToTextEncoding(smSystemScript, kTextLanguageDontCare, kTextRegionDontCare, NULL, &systemEncoding);
|
|
|
|
|
if (err != noErr)
|
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
|
|
err = ::CreateUnicodeToTextInfoByEncoding(systemEncoding, &converterInfo);
|
|
|
|
|
if (err != noErr)
|
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
|
|
err = ::ConvertFromUnicodeToPString(converterInfo, sizeof(PRUnichar), &inUniChar, convertedString);
|
|
|
|
|
if (err != noErr)
|
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
|
|
*outChar = convertedString[1];
|
|
|
|
|
::DisposeUnicodeToTextInfo(&converterInfo);
|
|
|
|
|
return PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ConvertCocoaKeyEventToMacEvent(NSEvent* cocoaEvent, EventRecord& macEvent)
|
|
|
|
|
{
|
|
|
|
|
if ([cocoaEvent type] == NSKeyDown)
|
|
|
|
|
macEvent.what = [cocoaEvent isARepeat] ? autoKey : keyDown;
|
|
|
|
|
else
|
|
|
|
|
macEvent.what = keyUp;
|
|
|
|
|
|
2002-06-11 22:13:03 +00:00
|
|
|
|
UInt32 charCode = [[cocoaEvent characters] characterAtIndex: 0];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (charCode >= 0x0080)
|
|
|
|
|
{
|
2002-06-11 22:13:03 +00:00
|
|
|
|
switch (charCode) {
|
|
|
|
|
case NSUpArrowFunctionKey:
|
2002-12-13 08:43:18 +00:00
|
|
|
|
charCode = kUpArrowCharCode;
|
2002-06-11 22:13:03 +00:00
|
|
|
|
break;
|
|
|
|
|
case NSDownArrowFunctionKey:
|
2002-12-13 08:43:18 +00:00
|
|
|
|
charCode = kDownArrowCharCode;
|
2002-06-11 22:13:03 +00:00
|
|
|
|
break;
|
|
|
|
|
case NSLeftArrowFunctionKey:
|
2002-12-13 08:43:18 +00:00
|
|
|
|
charCode = kLeftArrowCharCode;
|
2002-06-11 22:13:03 +00:00
|
|
|
|
break;
|
|
|
|
|
case NSRightArrowFunctionKey:
|
2002-12-13 08:43:18 +00:00
|
|
|
|
charCode = kRightArrowCharCode;
|
2002-06-11 22:13:03 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
2002-12-13 08:43:18 +00:00
|
|
|
|
unsigned char convertedCharCode;
|
|
|
|
|
if (ConvertUnicodeToCharCode(charCode, &convertedCharCode))
|
|
|
|
|
charCode = convertedCharCode;
|
|
|
|
|
//NSLog(@"charcode is %d, converted to %c, char is %@", charCode, convertedCharCode, [cocoaEvent characters]);
|
2002-06-11 22:13:03 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
macEvent.message = (charCode & 0x00FF) | ([cocoaEvent keyCode] << 8);
|
|
|
|
|
macEvent.when = ::TickCount();
|
|
|
|
|
GetGlobalMouse(&macEvent.where);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
macEvent.modifiers = ::GetCurrentKeyModifiers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (nsRect)sendCompositionEvent:(PRInt32) aEventType;
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_IME
|
|
|
|
|
NSLog(@"****in sendCompositionEvent; type = %d\n", aEventType);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// static void init_composition_event( *aEvent, int aType)
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsCompositionEvent event(aEventType, mGeckoChild);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
event.time = PR_IntervalNow();
|
|
|
|
|
mGeckoChild->DispatchWindowEvent(event);
|
|
|
|
|
return event.theReply.mCursorPosition;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)sendTextEvent:(PRUnichar*) aBuffer
|
|
|
|
|
attributedString:(NSAttributedString*) aString
|
|
|
|
|
selectedRange:(NSRange) selRange
|
|
|
|
|
markedRange:(NSRange) markRange
|
|
|
|
|
doCommit:(BOOL) doCommit
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_IME
|
|
|
|
|
NSLog(@"****in sendTextEvent; string = %@\n", aString);
|
|
|
|
|
NSLog(@" markRange = %d, %d; selRange = %d, %d\n", markRange.location, markRange.length, selRange.location, selRange.length);
|
|
|
|
|
#endif
|
|
|
|
|
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsTextEvent textEvent(NS_TEXT_TEXT, mGeckoChild);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
textEvent.time = PR_IntervalNow();
|
|
|
|
|
textEvent.theText = aBuffer;
|
|
|
|
|
if (!doCommit)
|
2004-12-23 17:59:53 +00:00
|
|
|
|
fillTextRangeInTextEvent(&textEvent, aString, markRange, selRange);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
|
|
|
|
mGeckoChild->DispatchWindowEvent(textEvent);
|
|
|
|
|
if ( textEvent.rangeArray )
|
|
|
|
|
delete [] textEvent.rangeArray;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define MAX_BUFFER_SIZE 32
|
|
|
|
|
// NSTextInput implementation
|
|
|
|
|
|
|
|
|
|
- (void)insertText:(id)insertString;
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
NSLog(@"****in insertText: %@\n", insertString);
|
|
|
|
|
NSLog(@" markRange = %d, %d; selRange = %d, %d\n", mMarkedRange.location, mMarkedRange.length, mSelectedRange.location, mSelectedRange.length);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if ( ! [insertString isKindOfClass:[NSAttributedString class]])
|
|
|
|
|
insertString = [[[NSAttributedString alloc] initWithString:insertString] autorelease];
|
|
|
|
|
|
|
|
|
|
NSString *tmpStr = [insertString string];
|
|
|
|
|
unsigned int len = [tmpStr length];
|
|
|
|
|
PRUnichar buffer[MAX_BUFFER_SIZE];
|
2004-01-29 19:42:13 +00:00
|
|
|
|
PRUnichar *bufPtr = (len >= MAX_BUFFER_SIZE) ? new PRUnichar[len + 1] : buffer;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
[tmpStr getCharacters: bufPtr];
|
|
|
|
|
bufPtr[len] = (PRUnichar)'\0';
|
|
|
|
|
|
|
|
|
|
if (len == 1 && !mInComposition)
|
|
|
|
|
{
|
|
|
|
|
// dispatch keypress event with char instead of textEvent
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsKeyEvent geckoEvent(NS_KEY_PRESS, mGeckoChild);
|
2004-02-24 03:40:27 +00:00
|
|
|
|
geckoEvent.time = PR_IntervalNow();
|
|
|
|
|
geckoEvent.charCode = bufPtr[0]; // gecko expects OS-translated unicode
|
|
|
|
|
geckoEvent.isChar = PR_TRUE;
|
|
|
|
|
geckoEvent.isShift = ([mCurEvent modifierFlags] & NSShiftKeyMask) != 0;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
|
|
|
|
// plugins need a native autokey event here, but only if this is a repeat event
|
|
|
|
|
EventRecord macEvent;
|
|
|
|
|
if (mCurEvent && [mCurEvent isARepeat])
|
|
|
|
|
{
|
|
|
|
|
ConvertCocoaKeyEventToMacEvent(mCurEvent, macEvent);
|
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mGeckoChild->DispatchWindowEvent(geckoEvent);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!mInComposition)
|
|
|
|
|
{
|
|
|
|
|
// send start composition event to gecko
|
|
|
|
|
[self sendCompositionEvent: NS_COMPOSITION_START];
|
|
|
|
|
mInComposition = YES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dispatch textevent (is this redundant?)
|
|
|
|
|
[self sendTextEvent:bufPtr attributedString:insertString
|
|
|
|
|
selectedRange:NSMakeRange(0, len)
|
|
|
|
|
markedRange:mMarkedRange
|
|
|
|
|
doCommit:YES];
|
|
|
|
|
|
|
|
|
|
// send end composition event to gecko
|
|
|
|
|
[self sendCompositionEvent: NS_COMPOSITION_END];
|
|
|
|
|
mInComposition = NO;
|
|
|
|
|
mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bufPtr != buffer)
|
|
|
|
|
delete[] bufPtr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)insertNewline:(id)sender
|
|
|
|
|
{
|
|
|
|
|
// dummy impl, does nothing (other than stop the beeping when hitting return)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) doCommandBySelector:(SEL)aSelector;
|
|
|
|
|
{
|
|
|
|
|
[super doCommandBySelector:aSelector];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) setMarkedText:(id)aString selectedRange:(NSRange)selRange;
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
NSLog(@"****in setMarkedText location: %d, length: %d\n", selRange.location, selRange.length);
|
|
|
|
|
NSLog(@" markRange = %d, %d; selRange = %d, %d\n", mMarkedRange.location, mMarkedRange.length, mSelectedRange.location, mSelectedRange.length);
|
|
|
|
|
NSLog(@" aString = %@\n", aString);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if ( ![aString isKindOfClass:[NSAttributedString class]] )
|
|
|
|
|
aString = [[[NSAttributedString alloc] initWithString:aString] autorelease];
|
|
|
|
|
|
|
|
|
|
mSelectedRange = selRange;
|
|
|
|
|
|
|
|
|
|
NSMutableAttributedString *mutableAttribStr = aString;
|
|
|
|
|
NSString *tmpStr = [mutableAttribStr string];
|
|
|
|
|
unsigned int len = [tmpStr length];
|
|
|
|
|
PRUnichar buffer[MAX_BUFFER_SIZE];
|
2004-01-29 19:42:13 +00:00
|
|
|
|
PRUnichar *bufPtr = (len >= MAX_BUFFER_SIZE) ? new PRUnichar[len + 1] : buffer;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
[tmpStr getCharacters: bufPtr];
|
|
|
|
|
bufPtr[len] = (PRUnichar)'\0';
|
|
|
|
|
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
printf("****in setMarkedText, len = %d, text = ", len);
|
|
|
|
|
PRUint32 n = 0;
|
|
|
|
|
PRUint32 maxlen = len > 12 ? 12 : len;
|
|
|
|
|
for (PRUnichar *a = bufPtr; (*a != (PRUnichar)'\0') && n<maxlen; a++, n++) printf((*a&0xff80) ? "\\u%4X" : "%c", *a);
|
|
|
|
|
printf("\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
mMarkedRange.location = 0;
|
|
|
|
|
mMarkedRange.length = len;
|
|
|
|
|
|
|
|
|
|
if (!mInComposition)
|
|
|
|
|
{
|
|
|
|
|
[self sendCompositionEvent:NS_COMPOSITION_START];
|
|
|
|
|
mInComposition = YES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[self sendTextEvent:bufPtr attributedString:aString
|
|
|
|
|
selectedRange:selRange
|
|
|
|
|
markedRange:mMarkedRange
|
|
|
|
|
doCommit:NO];
|
|
|
|
|
|
2004-01-29 19:42:13 +00:00
|
|
|
|
if (mInComposition && len == 0)
|
|
|
|
|
[self unmarkText];
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (bufPtr != buffer)
|
|
|
|
|
delete[] bufPtr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) unmarkText;
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
NSLog(@"****in unmarkText\n");
|
|
|
|
|
NSLog(@" markedRange = %d, %d\n", mMarkedRange.location, mMarkedRange.length);
|
|
|
|
|
NSLog(@" selectedRange = %d, %d\n", mSelectedRange.location, mSelectedRange.length);
|
|
|
|
|
#endif
|
|
|
|
|
|
2004-01-29 19:42:13 +00:00
|
|
|
|
mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (mInComposition) {
|
|
|
|
|
[self sendCompositionEvent: NS_COMPOSITION_END];
|
|
|
|
|
mInComposition = NO; // brade: do we need to send an end composition event?
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL) hasMarkedText;
|
|
|
|
|
{
|
|
|
|
|
return mMarkedRange.location != NSNotFound && mMarkedRange.length != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (long) conversationIdentifier;
|
|
|
|
|
{
|
|
|
|
|
return (long)self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSAttributedString *) attributedSubstringFromRange:(NSRange)theRange;
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
NSLog(@"****in attributedSubstringFromRange\n");
|
|
|
|
|
NSLog(@" theRange = %d, %d\n", theRange.location, theRange.length);
|
|
|
|
|
NSLog(@" markedRange = %d, %d\n", mMarkedRange.location, mMarkedRange.length);
|
|
|
|
|
NSLog(@" selectedRange = %d, %d\n", mSelectedRange.location, mSelectedRange.length);
|
|
|
|
|
#endif
|
|
|
|
|
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsReconversionEvent reconversionEvent(NS_RECONVERSION_QUERY, mGeckoChild);
|
2002-12-13 08:43:18 +00:00
|
|
|
|
reconversionEvent.time = PR_IntervalNow();
|
|
|
|
|
|
|
|
|
|
nsresult rv = mGeckoChild->DispatchWindowEvent(reconversionEvent);
|
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
|
{
|
|
|
|
|
PRUnichar *reconvstr = reconversionEvent.theReply.mReconversionString;
|
|
|
|
|
NSAttributedString *result = [[[NSAttributedString alloc] stringWithCharacters:reconvstr length: reconvstr ? nsCRT::strlen(reconvstr) : 0] autorelease];
|
|
|
|
|
nsMemory::Free(reconvstr);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
2002-06-11 22:13:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
- (NSRange) markedRange;
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
NSLog(@"****in markedRange\n");
|
|
|
|
|
NSLog(@" markedRange = %d, %d\n", mMarkedRange.location, mMarkedRange.length);
|
|
|
|
|
NSLog(@" selectedRange = %d, %d\n", mSelectedRange.location, mSelectedRange.length);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (![self hasMarkedText]) {
|
|
|
|
|
return NSMakeRange(NSNotFound, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mMarkedRange;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSRange) selectedRange;
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
NSLog(@"****in selectedRange\n");
|
|
|
|
|
NSLog(@" markedRange = %d, %d\n", mMarkedRange.location, mMarkedRange.length);
|
|
|
|
|
NSLog(@" selectedRange = %d, %d\n", mSelectedRange.location, mSelectedRange.length);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return mSelectedRange;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (NSRect) firstRectForCharacterRange:(NSRange)theRange;
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
NSLog(@"****in firstRectForCharacterRange\n");
|
|
|
|
|
NSLog(@" theRange = %d, %d\n", theRange.location, theRange.length);
|
|
|
|
|
NSLog(@" markedRange = %d, %d\n", mMarkedRange.location, mMarkedRange.length);
|
|
|
|
|
NSLog(@" selectedRange = %d, %d\n", mSelectedRange.location, mSelectedRange.length);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if BRADE_GETS_THIS_WORKING
|
|
|
|
|
// send NS_COMPOSITION_QUERY event
|
|
|
|
|
nsRect r = [self sendCompositionEvent: NS_COMPOSITION_QUERY];
|
|
|
|
|
|
|
|
|
|
// similar to mGeckoChild->WidgetToScreen(gecko_r, screen_r);
|
|
|
|
|
NSRect temp;
|
|
|
|
|
ConvertGeckoToCocoaRect(r, temp);
|
|
|
|
|
temp = [mGeckoChild->mView convertRect:temp toView:nil]; // convert to window coords
|
|
|
|
|
temp.origin = [[mGeckoChild->mView getNativeWindow] convertBaseToScreen:temp.origin]; // convert to screen coords
|
|
|
|
|
#else
|
|
|
|
|
NSRect temp;
|
|
|
|
|
temp.origin.x = temp.origin.y = temp.size.width = temp.size.height = 0;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
NSLog(@"********** cocoa rect (x, y, w, h): %f %f, %f, %f\n", temp.origin.x, temp.origin.y, temp.size.width, temp.size.height);
|
|
|
|
|
#endif
|
|
|
|
|
return temp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (unsigned int)characterIndexForPoint:(NSPoint)thePoint;
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
NSLog(@"****in characterIndexForPoint\n");
|
|
|
|
|
NSLog(@" markRange = %d, %d; selectRange = %d, %d\n", mMarkedRange.location, mMarkedRange.length, mSelectedRange.location, mSelectedRange.length);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// short regionClass;
|
|
|
|
|
// return mGeckoChild->HandlePositionToOffset(thePoint, ®ionClass);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSArray*) validAttributesForMarkedText;
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG_IME
|
|
|
|
|
NSLog(@"****in validAttributesForMarkedText\n");
|
|
|
|
|
NSLog(@" markRange = %d, %d; selectRange = %d, %d\n", mMarkedRange.location, mMarkedRange.length, mSelectedRange.location, mSelectedRange.length);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return [NSArray array]; // empty array; we don't support any attributes right now
|
|
|
|
|
}
|
|
|
|
|
// end NSTextInput
|
|
|
|
|
|
2004-02-04 22:08:14 +00:00
|
|
|
|
//
|
|
|
|
|
// keyDown:
|
|
|
|
|
//
|
|
|
|
|
// Handle matching cocoa IME with gecko key events. Sends a key down and key press
|
|
|
|
|
// event to gecko.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: diacriticals (opt-e, e) aren't fully handled.
|
|
|
|
|
//
|
2002-02-22 08:44:16 +00:00
|
|
|
|
- (void)keyDown:(NSEvent*)theEvent;
|
|
|
|
|
{
|
2002-12-13 08:43:18 +00:00
|
|
|
|
PRBool isKeyDownEventHandled = PR_TRUE;
|
|
|
|
|
PRBool isKeyEventHandled = PR_FALSE;
|
2002-02-22 08:44:16 +00:00
|
|
|
|
PRBool isChar = PR_FALSE;
|
|
|
|
|
BOOL isARepeat = [theEvent isARepeat];
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
|
|
|
|
mCurEvent = theEvent;
|
|
|
|
|
|
|
|
|
|
// if we have a dead-key event, we won't get a character
|
|
|
|
|
// since we have no character, there isn't any point to generating
|
|
|
|
|
// a gecko event until they have dead key events
|
|
|
|
|
BOOL nonDeadKeyPress = [[theEvent characters] length] > 0;
|
|
|
|
|
if (!isARepeat && nonDeadKeyPress)
|
|
|
|
|
{
|
2002-02-22 08:44:16 +00:00
|
|
|
|
// Fire a key down.
|
|
|
|
|
nsKeyEvent geckoEvent;
|
|
|
|
|
geckoEvent.point.x = geckoEvent.point.y = 0;
|
|
|
|
|
[self convert: theEvent message: NS_KEY_DOWN
|
|
|
|
|
isChar: &isChar
|
|
|
|
|
toGeckoEvent: &geckoEvent];
|
|
|
|
|
geckoEvent.isChar = isChar;
|
2002-06-11 22:13:03 +00:00
|
|
|
|
|
|
|
|
|
// As an optimisation, only do this when there is a plugin present.
|
|
|
|
|
EventRecord macEvent;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
ConvertCocoaKeyEventToMacEvent(theEvent, macEvent);
|
2002-06-11 22:13:03 +00:00
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
isKeyDownEventHandled = mGeckoChild->DispatchWindowEvent(geckoEvent);
|
2002-02-22 08:44:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check to see if we are still the first responder.
|
|
|
|
|
// The key down event may have shifted the focus, in which
|
|
|
|
|
// case we should not fire the key press.
|
|
|
|
|
NSResponder* resp = [[self window] firstResponder];
|
|
|
|
|
if (resp != (NSResponder*)self) {
|
2002-12-13 08:43:18 +00:00
|
|
|
|
#if DEBUG
|
|
|
|
|
printf("We are no longer the responder. Bailing.\n");
|
|
|
|
|
#endif
|
|
|
|
|
mCurEvent = NULL;
|
2002-02-22 08:44:16 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-13 08:43:18 +00:00
|
|
|
|
if (!mInComposition && nonDeadKeyPress)
|
|
|
|
|
{
|
|
|
|
|
// Fire a key press.
|
|
|
|
|
nsKeyEvent geckoEvent;
|
|
|
|
|
geckoEvent.point.x = geckoEvent.point.y = 0;
|
|
|
|
|
isChar = PR_FALSE;
|
|
|
|
|
[self convert: theEvent message: NS_KEY_PRESS
|
|
|
|
|
isChar: &isChar
|
|
|
|
|
toGeckoEvent: &geckoEvent];
|
|
|
|
|
geckoEvent.isChar = isChar;
|
|
|
|
|
if (isChar)
|
|
|
|
|
{
|
|
|
|
|
// we'll send the NS_KEY_PRESS event to gecko in [insertText:]
|
|
|
|
|
mLastKeyEventWasSentToCocoa = YES; // force all events to go through inserttext
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// if this is a repeat non-char event (e.g. arrows), then set up
|
|
|
|
|
// a mac event
|
|
|
|
|
if (isARepeat)
|
|
|
|
|
{
|
|
|
|
|
// plugins need a native event (this should be an autoKey event)
|
|
|
|
|
EventRecord macEvent;
|
|
|
|
|
ConvertCocoaKeyEventToMacEvent(theEvent, macEvent);
|
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// do we need to end composition if we got here by arrow key press or other?
|
|
|
|
|
isKeyEventHandled = mGeckoChild->DispatchWindowEvent(geckoEvent);
|
2004-02-04 22:08:14 +00:00
|
|
|
|
|
|
|
|
|
// only force this through cocoa if this special-key was not handled by gecko
|
|
|
|
|
mLastKeyEventWasSentToCocoa = !isKeyEventHandled;
|
2002-02-22 08:44:16 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
|
|
|
|
if (!nonDeadKeyPress || mLastKeyEventWasSentToCocoa || (!isKeyDownEventHandled && !isKeyEventHandled))
|
|
|
|
|
{
|
|
|
|
|
// XXX hack: we need to have a flag so we call interpretKeyEvents even tho
|
|
|
|
|
// we've inserted the character(s); if we don't, the system/Cocoa key event
|
|
|
|
|
// handling code doesn't know that the letters were "composed" or entered
|
|
|
|
|
// for example, option-e, e would only send option-e event and we'd get
|
|
|
|
|
// the accent character with all subsequent key events since it didn't see
|
|
|
|
|
// the resulting keypress
|
|
|
|
|
mLastKeyEventWasSentToCocoa = !mLastKeyEventWasSentToCocoa;
|
|
|
|
|
[super interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mCurEvent = NULL;
|
2002-02-22 08:44:16 +00:00
|
|
|
|
}
|
2001-11-14 22:29:25 +00:00
|
|
|
|
|
2002-02-22 08:44:16 +00:00
|
|
|
|
- (void)keyUp:(NSEvent*)theEvent;
|
|
|
|
|
{
|
2002-12-13 08:43:18 +00:00
|
|
|
|
// if we don't have any characters we can't generate a keyUp event
|
|
|
|
|
if (0 == [[theEvent characters] length])
|
|
|
|
|
return;
|
|
|
|
|
|
2002-02-22 08:44:16 +00:00
|
|
|
|
// Fire a key up.
|
|
|
|
|
nsKeyEvent geckoEvent;
|
|
|
|
|
geckoEvent.point.x = geckoEvent.point.y = 0;
|
|
|
|
|
PRBool isChar;
|
|
|
|
|
[self convert: theEvent message: NS_KEY_UP
|
|
|
|
|
isChar: &isChar
|
|
|
|
|
toGeckoEvent: &geckoEvent];
|
2002-06-11 22:13:03 +00:00
|
|
|
|
|
|
|
|
|
// As an optimisation, only do this when there is a plugin present.
|
|
|
|
|
EventRecord macEvent;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
ConvertCocoaKeyEventToMacEvent(theEvent, macEvent);
|
2002-06-11 22:13:03 +00:00
|
|
|
|
geckoEvent.nativeMsg = &macEvent;
|
2002-12-13 08:43:18 +00:00
|
|
|
|
|
2002-02-22 08:44:16 +00:00
|
|
|
|
mGeckoChild->DispatchWindowEvent(geckoEvent);
|
|
|
|
|
}
|
2001-11-14 22:29:25 +00:00
|
|
|
|
|
2003-03-13 20:37:32 +00:00
|
|
|
|
// look for the user's pressing of command and alt so that we can display
|
|
|
|
|
// the hand scroll cursor
|
|
|
|
|
- (void)flagsChanged:(NSEvent*)theEvent
|
|
|
|
|
{
|
|
|
|
|
BOOL inMouseView = NO;
|
|
|
|
|
// check to see if the user has hand scroll modifiers held down; if so,
|
|
|
|
|
// find out if the cursor is in an ChildView
|
|
|
|
|
if ([ChildView areHandScrollModifiers:[theEvent modifierFlags]]) {
|
|
|
|
|
NSPoint pointInWindow = [[self window] mouseLocationOutsideOfEventStream];
|
|
|
|
|
|
|
|
|
|
NSView* mouseView = [[[self window] contentView] hitTest:pointInWindow];
|
|
|
|
|
inMouseView = (mouseView != nil && [mouseView isMemberOfClass:[ChildView class]]);
|
|
|
|
|
}
|
|
|
|
|
if (inMouseView) {
|
|
|
|
|
mGeckoChild->SetCursor(eCursor_grab);
|
|
|
|
|
} else {
|
|
|
|
|
nsCursor cursor = mGeckoChild->GetCursor();
|
|
|
|
|
if (!mInHandScroll) {
|
|
|
|
|
if (cursor == eCursor_grab || cursor == eCursor_grabbing)
|
|
|
|
|
mGeckoChild->SetCursor(eCursor_standard);
|
|
|
|
|
// pass on the event since we are not using it
|
|
|
|
|
[super flagsChanged:theEvent];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-03-09 22:43:04 +00:00
|
|
|
|
// This method is called when we are about to be focused.
|
|
|
|
|
- (BOOL)becomeFirstResponder
|
|
|
|
|
{
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsFocusEvent event(NS_GOTFOCUS, mGeckoChild);
|
2002-03-09 22:43:04 +00:00
|
|
|
|
|
|
|
|
|
mGeckoChild->DispatchWindowEvent(event);
|
|
|
|
|
return [super becomeFirstResponder];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This method is called when are are about to lose focus.
|
|
|
|
|
- (BOOL)resignFirstResponder
|
|
|
|
|
{
|
2004-01-12 08:25:18 +00:00
|
|
|
|
nsFocusEvent event(NS_LOSTFOCUS, mGeckoChild);
|
2002-03-09 22:43:04 +00:00
|
|
|
|
|
|
|
|
|
mGeckoChild->DispatchWindowEvent(event);
|
|
|
|
|
|
|
|
|
|
return [super resignFirstResponder];
|
|
|
|
|
}
|
|
|
|
|
|
2002-02-22 08:44:16 +00:00
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// ConvertMacToRaptorKeyCode
|
|
|
|
|
//
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Key code constants
|
|
|
|
|
enum
|
2001-11-14 22:29:25 +00:00
|
|
|
|
{
|
2002-02-22 08:44:16 +00:00
|
|
|
|
kEscapeKeyCode = 0x35,
|
|
|
|
|
kCommandKeyCode = 0x37,
|
|
|
|
|
kShiftKeyCode = 0x38,
|
|
|
|
|
kCapsLockKeyCode = 0x39,
|
|
|
|
|
kControlKeyCode = 0x3B,
|
|
|
|
|
kOptionkeyCode = 0x3A, // left and right option keys
|
|
|
|
|
kClearKeyCode = 0x47,
|
2001-11-14 22:29:25 +00:00
|
|
|
|
|
2002-02-22 08:44:16 +00:00
|
|
|
|
// function keys
|
|
|
|
|
kF1KeyCode = 0x7A,
|
|
|
|
|
kF2KeyCode = 0x78,
|
|
|
|
|
kF3KeyCode = 0x63,
|
|
|
|
|
kF4KeyCode = 0x76,
|
|
|
|
|
kF5KeyCode = 0x60,
|
|
|
|
|
kF6KeyCode = 0x61,
|
|
|
|
|
kF7KeyCode = 0x62,
|
|
|
|
|
kF8KeyCode = 0x64,
|
|
|
|
|
kF9KeyCode = 0x65,
|
|
|
|
|
kF10KeyCode = 0x6D,
|
|
|
|
|
kF11KeyCode = 0x67,
|
|
|
|
|
kF12KeyCode = 0x6F,
|
|
|
|
|
kF13KeyCode = 0x69,
|
|
|
|
|
kF14KeyCode = 0x6B,
|
|
|
|
|
kF15KeyCode = 0x71,
|
2001-11-14 22:29:25 +00:00
|
|
|
|
|
2002-02-22 08:44:16 +00:00
|
|
|
|
kPrintScreenKeyCode = kF13KeyCode,
|
|
|
|
|
kScrollLockKeyCode = kF14KeyCode,
|
|
|
|
|
kPauseKeyCode = kF15KeyCode,
|
2001-11-14 22:29:25 +00:00
|
|
|
|
|
2002-02-22 08:44:16 +00:00
|
|
|
|
// keypad
|
|
|
|
|
kKeypad0KeyCode = 0x52,
|
|
|
|
|
kKeypad1KeyCode = 0x53,
|
|
|
|
|
kKeypad2KeyCode = 0x54,
|
|
|
|
|
kKeypad3KeyCode = 0x55,
|
|
|
|
|
kKeypad4KeyCode = 0x56,
|
|
|
|
|
kKeypad5KeyCode = 0x57,
|
|
|
|
|
kKeypad6KeyCode = 0x58,
|
|
|
|
|
kKeypad7KeyCode = 0x59,
|
|
|
|
|
kKeypad8KeyCode = 0x5B,
|
|
|
|
|
kKeypad9KeyCode = 0x5C,
|
2001-11-14 22:29:25 +00:00
|
|
|
|
|
2002-02-22 08:44:16 +00:00
|
|
|
|
kKeypadMultiplyKeyCode = 0x43,
|
|
|
|
|
kKeypadAddKeyCode = 0x45,
|
|
|
|
|
kKeypadSubtractKeyCode = 0x4E,
|
|
|
|
|
kKeypadDecimalKeyCode = 0x41,
|
|
|
|
|
kKeypadDivideKeyCode = 0x4B,
|
|
|
|
|
kKeypadEqualsKeyCode = 0x51, // no correpsonding raptor key code
|
|
|
|
|
kEnterKeyCode = 0x4C,
|
|
|
|
|
kReturnKeyCode = 0x24,
|
|
|
|
|
kPowerbookEnterKeyCode = 0x34, // Enter on Powerbook's keyboard is different
|
|
|
|
|
|
|
|
|
|
kInsertKeyCode = 0x72, // also help key
|
|
|
|
|
kDeleteKeyCode = 0x75, // also forward delete key
|
|
|
|
|
kTabKeyCode = 0x30,
|
|
|
|
|
kBackspaceKeyCode = 0x33,
|
|
|
|
|
kHomeKeyCode = 0x73,
|
|
|
|
|
kEndKeyCode = 0x77,
|
|
|
|
|
kPageUpKeyCode = 0x74,
|
|
|
|
|
kPageDownKeyCode = 0x79,
|
|
|
|
|
kLeftArrowKeyCode = 0x7B,
|
|
|
|
|
kRightArrowKeyCode = 0x7C,
|
|
|
|
|
kUpArrowKeyCode = 0x7E,
|
|
|
|
|
kDownArrowKeyCode = 0x7D
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static PRUint32 ConvertMacToRaptorKeyCode(UInt32 keyCode, nsKeyEvent* aKeyEvent, NSString* characters)
|
|
|
|
|
{
|
2002-12-13 08:43:18 +00:00
|
|
|
|
PRUint32 raptorKeyCode = 0;
|
|
|
|
|
PRUint8 charCode;
|
|
|
|
|
if ([characters length])
|
|
|
|
|
charCode = [characters characterAtIndex: 0];
|
|
|
|
|
else
|
|
|
|
|
charCode = 0;
|
|
|
|
|
|
2002-02-22 08:44:16 +00:00
|
|
|
|
switch (keyCode)
|
2001-11-14 22:29:25 +00:00
|
|
|
|
{
|
2002-02-22 08:44:16 +00:00
|
|
|
|
// case ?? : raptorKeyCode = NS_VK_CANCEL; break; // don't know what this key means. Nor does joki
|
|
|
|
|
|
|
|
|
|
// modifiers. We don't get separate events for these
|
|
|
|
|
case kEscapeKeyCode: raptorKeyCode = NS_VK_ESCAPE; break;
|
|
|
|
|
case kShiftKeyCode: raptorKeyCode = NS_VK_SHIFT; break;
|
|
|
|
|
// case kCommandKeyCode: raptorKeyCode = NS_VK_META; break;
|
|
|
|
|
case kCapsLockKeyCode: raptorKeyCode = NS_VK_CAPS_LOCK; break;
|
|
|
|
|
case kControlKeyCode: raptorKeyCode = NS_VK_CONTROL; break;
|
|
|
|
|
case kOptionkeyCode: raptorKeyCode = NS_VK_ALT; break;
|
|
|
|
|
case kClearKeyCode: raptorKeyCode = NS_VK_CLEAR; break;
|
|
|
|
|
|
|
|
|
|
// function keys
|
|
|
|
|
case kF1KeyCode: raptorKeyCode = NS_VK_F1; break;
|
|
|
|
|
case kF2KeyCode: raptorKeyCode = NS_VK_F2; break;
|
|
|
|
|
case kF3KeyCode: raptorKeyCode = NS_VK_F3; break;
|
|
|
|
|
case kF4KeyCode: raptorKeyCode = NS_VK_F4; break;
|
|
|
|
|
case kF5KeyCode: raptorKeyCode = NS_VK_F5; break;
|
|
|
|
|
case kF6KeyCode: raptorKeyCode = NS_VK_F6; break;
|
|
|
|
|
case kF7KeyCode: raptorKeyCode = NS_VK_F7; break;
|
|
|
|
|
case kF8KeyCode: raptorKeyCode = NS_VK_F8; break;
|
|
|
|
|
case kF9KeyCode: raptorKeyCode = NS_VK_F9; break;
|
|
|
|
|
case kF10KeyCode: raptorKeyCode = NS_VK_F10; break;
|
|
|
|
|
case kF11KeyCode: raptorKeyCode = NS_VK_F11; break;
|
|
|
|
|
case kF12KeyCode: raptorKeyCode = NS_VK_F12; break;
|
|
|
|
|
// case kF13KeyCode: raptorKeyCode = NS_VK_F13; break; // clash with the 3 below
|
|
|
|
|
// case kF14KeyCode: raptorKeyCode = NS_VK_F14; break;
|
|
|
|
|
// case kF15KeyCode: raptorKeyCode = NS_VK_F15; break;
|
|
|
|
|
case kPauseKeyCode: raptorKeyCode = NS_VK_PAUSE; break;
|
|
|
|
|
case kScrollLockKeyCode: raptorKeyCode = NS_VK_SCROLL_LOCK; break;
|
|
|
|
|
case kPrintScreenKeyCode: raptorKeyCode = NS_VK_PRINTSCREEN; break;
|
|
|
|
|
|
|
|
|
|
// keypad
|
|
|
|
|
case kKeypad0KeyCode: raptorKeyCode = NS_VK_NUMPAD0; break;
|
|
|
|
|
case kKeypad1KeyCode: raptorKeyCode = NS_VK_NUMPAD1; break;
|
|
|
|
|
case kKeypad2KeyCode: raptorKeyCode = NS_VK_NUMPAD2; break;
|
|
|
|
|
case kKeypad3KeyCode: raptorKeyCode = NS_VK_NUMPAD3; break;
|
|
|
|
|
case kKeypad4KeyCode: raptorKeyCode = NS_VK_NUMPAD4; break;
|
|
|
|
|
case kKeypad5KeyCode: raptorKeyCode = NS_VK_NUMPAD5; break;
|
|
|
|
|
case kKeypad6KeyCode: raptorKeyCode = NS_VK_NUMPAD6; break;
|
|
|
|
|
case kKeypad7KeyCode: raptorKeyCode = NS_VK_NUMPAD7; break;
|
|
|
|
|
case kKeypad8KeyCode: raptorKeyCode = NS_VK_NUMPAD8; break;
|
|
|
|
|
case kKeypad9KeyCode: raptorKeyCode = NS_VK_NUMPAD9; break;
|
|
|
|
|
|
|
|
|
|
case kKeypadMultiplyKeyCode: raptorKeyCode = NS_VK_MULTIPLY; break;
|
|
|
|
|
case kKeypadAddKeyCode: raptorKeyCode = NS_VK_ADD; break;
|
|
|
|
|
case kKeypadSubtractKeyCode: raptorKeyCode = NS_VK_SUBTRACT; break;
|
|
|
|
|
case kKeypadDecimalKeyCode: raptorKeyCode = NS_VK_DECIMAL; break;
|
|
|
|
|
case kKeypadDivideKeyCode: raptorKeyCode = NS_VK_DIVIDE; break;
|
|
|
|
|
// case ?? : raptorKeyCode = NS_VK_SEPARATOR; break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// these may clash with forward delete and help
|
|
|
|
|
case kInsertKeyCode: raptorKeyCode = NS_VK_INSERT; break;
|
|
|
|
|
case kDeleteKeyCode: raptorKeyCode = NS_VK_DELETE; break;
|
|
|
|
|
|
|
|
|
|
case kBackspaceKeyCode: raptorKeyCode = NS_VK_BACK; break;
|
|
|
|
|
case kTabKeyCode: raptorKeyCode = NS_VK_TAB; break;
|
|
|
|
|
case kHomeKeyCode: raptorKeyCode = NS_VK_HOME; break;
|
|
|
|
|
case kEndKeyCode: raptorKeyCode = NS_VK_END; break;
|
|
|
|
|
case kPageUpKeyCode: raptorKeyCode = NS_VK_PAGE_UP; break;
|
|
|
|
|
case kPageDownKeyCode: raptorKeyCode = NS_VK_PAGE_DOWN; break;
|
|
|
|
|
case kLeftArrowKeyCode: raptorKeyCode = NS_VK_LEFT; break;
|
|
|
|
|
case kRightArrowKeyCode: raptorKeyCode = NS_VK_RIGHT; break;
|
|
|
|
|
case kUpArrowKeyCode: raptorKeyCode = NS_VK_UP; break;
|
|
|
|
|
case kDownArrowKeyCode: raptorKeyCode = NS_VK_DOWN; break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
if (aKeyEvent->isControl)
|
|
|
|
|
charCode += 64;
|
|
|
|
|
|
|
|
|
|
// if we haven't gotten the key code already, look at the char code
|
|
|
|
|
switch (charCode)
|
|
|
|
|
{
|
|
|
|
|
case kReturnCharCode: raptorKeyCode = NS_VK_RETURN; break;
|
|
|
|
|
case kEnterCharCode: raptorKeyCode = NS_VK_RETURN; break; // fix me!
|
|
|
|
|
case ' ': raptorKeyCode = NS_VK_SPACE; break;
|
|
|
|
|
case ';': raptorKeyCode = NS_VK_SEMICOLON; break;
|
|
|
|
|
case '=': raptorKeyCode = NS_VK_EQUALS; break;
|
|
|
|
|
case ',': raptorKeyCode = NS_VK_COMMA; break;
|
|
|
|
|
case '.': raptorKeyCode = NS_VK_PERIOD; break;
|
|
|
|
|
case '/': raptorKeyCode = NS_VK_SLASH; break;
|
|
|
|
|
case '`': raptorKeyCode = NS_VK_BACK_QUOTE; break;
|
|
|
|
|
case '{':
|
|
|
|
|
case '[': raptorKeyCode = NS_VK_OPEN_BRACKET; break;
|
|
|
|
|
case '\\': raptorKeyCode = NS_VK_BACK_SLASH; break;
|
|
|
|
|
case '}':
|
|
|
|
|
case ']': raptorKeyCode = NS_VK_CLOSE_BRACKET; break;
|
|
|
|
|
case '\'':
|
|
|
|
|
case '"': raptorKeyCode = NS_VK_QUOTE; break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
|
|
if (charCode >= '0' && charCode <= '9') // numerals
|
|
|
|
|
{
|
|
|
|
|
raptorKeyCode = charCode;
|
|
|
|
|
}
|
|
|
|
|
else if (charCode >= 'a' && charCode <= 'z') // lowercase
|
|
|
|
|
{
|
|
|
|
|
raptorKeyCode = toupper(charCode);
|
|
|
|
|
}
|
|
|
|
|
else if (charCode >= 'A' && charCode <= 'Z') // uppercase
|
|
|
|
|
{
|
|
|
|
|
raptorKeyCode = charCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return raptorKeyCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PRBool IsSpecialRaptorKey(UInt32 macKeyCode)
|
|
|
|
|
{
|
|
|
|
|
PRBool isSpecial;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// this table is used to determine which keys are special and should not generate a charCode
|
|
|
|
|
//
|
|
|
|
|
switch (macKeyCode)
|
2001-11-14 22:29:25 +00:00
|
|
|
|
{
|
2002-02-22 08:44:16 +00:00
|
|
|
|
// modifiers. We don't get separate events for these
|
|
|
|
|
// yet
|
|
|
|
|
case kEscapeKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kShiftKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kCommandKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kCapsLockKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kControlKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kOptionkeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kClearKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
|
|
|
|
|
// function keys
|
|
|
|
|
case kF1KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF2KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF3KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF4KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF5KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF6KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF7KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF8KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF9KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF10KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF11KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kF12KeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kPauseKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kScrollLockKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kPrintScreenKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
|
|
|
|
|
case kInsertKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kDeleteKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kTabKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kBackspaceKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
|
|
|
|
|
case kHomeKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kEndKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kPageUpKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kPageDownKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kLeftArrowKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kRightArrowKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kUpArrowKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kDownArrowKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kReturnKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kEnterKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
case kPowerbookEnterKeyCode: isSpecial = PR_TRUE; break;
|
|
|
|
|
|
|
|
|
|
default: isSpecial = PR_FALSE; break;
|
|
|
|
|
}
|
|
|
|
|
return isSpecial;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) convert:(NSEvent*)aKeyEvent message:(PRUint32)aMessage
|
|
|
|
|
isChar:(PRBool*)aIsChar
|
|
|
|
|
toGeckoEvent:(nsKeyEvent*)outGeckoEvent
|
|
|
|
|
{
|
|
|
|
|
[self convert:aKeyEvent message:aMessage toGeckoEvent:outGeckoEvent];
|
|
|
|
|
|
|
|
|
|
// Initialize the out boolean for whether or not we are using
|
|
|
|
|
// charCodes to false.
|
|
|
|
|
if (aIsChar)
|
|
|
|
|
*aIsChar = PR_FALSE;
|
|
|
|
|
|
|
|
|
|
// Check to see if the message is a key press that does not involve
|
|
|
|
|
// one of our special key codes.
|
|
|
|
|
if (aMessage == NS_KEY_PRESS && !IsSpecialRaptorKey([aKeyEvent keyCode]))
|
|
|
|
|
{
|
|
|
|
|
if (!outGeckoEvent->isControl && !outGeckoEvent->isMeta)
|
2002-11-07 03:34:13 +00:00
|
|
|
|
outGeckoEvent->isControl = outGeckoEvent->isAlt = outGeckoEvent->isMeta = 0;
|
2002-02-22 08:44:16 +00:00
|
|
|
|
|
|
|
|
|
// We're not a special key.
|
|
|
|
|
outGeckoEvent->keyCode = 0;
|
|
|
|
|
if (aIsChar)
|
|
|
|
|
*aIsChar = PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
outGeckoEvent->keyCode = ConvertMacToRaptorKeyCode([aKeyEvent keyCode], outGeckoEvent, [aKeyEvent characters]);
|
|
|
|
|
outGeckoEvent->charCode = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (aMessage == NS_KEY_PRESS && !outGeckoEvent->isMeta && outGeckoEvent->keyCode != NS_VK_PAGE_UP &&
|
|
|
|
|
outGeckoEvent->keyCode != NS_VK_PAGE_DOWN)
|
2001-11-14 22:29:25 +00:00
|
|
|
|
::ObscureCursor();
|
|
|
|
|
}
|
|
|
|
|
|
2004-01-29 20:11:54 +00:00
|
|
|
|
//
|
|
|
|
|
// -_destinationFloatValueForScroller
|
|
|
|
|
//
|
|
|
|
|
// When smooth scrolling is turned on on panther, the parent of a scrollbar (which
|
|
|
|
|
// I guess they assume is a NSScrollView) gets called with this method. I have no
|
|
|
|
|
// idea what the correct return value is, but we have to have this otherwise the scrollbar
|
|
|
|
|
// will not continuously respond when the mouse is held down in the pageup/down area.
|
|
|
|
|
//
|
|
|
|
|
-(float)_destinationFloatValueForScroller:(id)scroller
|
|
|
|
|
{
|
|
|
|
|
return [scroller floatValue];
|
|
|
|
|
}
|
|
|
|
|
|
2001-11-06 15:35:24 +00:00
|
|
|
|
@end
|