mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-15 14:30:47 +00:00
First Checked In.
This commit is contained in:
parent
df0d58397b
commit
e019f297bb
470
widget/src/mac/nsMacMessagePump.cpp
Normal file
470
widget/src/mac/nsMacMessagePump.cpp
Normal file
@ -0,0 +1,470 @@
|
||||
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsMacMessagePump.h"
|
||||
#include "nsMacMessageSink.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsToolkit.h"
|
||||
#include "nscore.h"
|
||||
|
||||
#include <MacWindows.h>
|
||||
#include <LPeriodical.h>
|
||||
#include <ToolUtils.h>
|
||||
#include <LowMem.h>
|
||||
|
||||
#define DRAW_ON_RESIZE
|
||||
|
||||
const char SUSPENDRESUMEMESSAGE = 0x01;
|
||||
const char MOUSEMOVEDMESSAGE = 0xFA;
|
||||
|
||||
//nsWindow* nsMacMessagePump::gCurrentWindow = nsnull;
|
||||
//nsWindow* nsMacMessagePump::gGrabWindow = nsnull; // need this for grabmouse
|
||||
|
||||
//static NS_DEFINE_IID(kITEXTWIDGETIID, NS_TEXTFIELD_CID);
|
||||
nsMacMessagePump::nsWindowlessMenuEventHandler nsMacMessagePump::gWindowlessMenuEventHandler = nsnull;
|
||||
|
||||
|
||||
bool IsUserWindow ( WindowPtr ) ;
|
||||
|
||||
// a small helper routine, inlined for efficiency
|
||||
inline
|
||||
bool IsUserWindow ( WindowPtr wp )
|
||||
{
|
||||
return wp && (::GetWindowKind(wp) >= kApplicationWindowKind);
|
||||
}
|
||||
|
||||
|
||||
//=================================================================
|
||||
/* Constructor
|
||||
* @update dc 08/31/98
|
||||
* @param aToolkit -- The toolkit created by the application
|
||||
* @return NONE
|
||||
*/
|
||||
nsMacMessagePump::nsMacMessagePump(nsToolkit *aToolkit, nsMacMessageSink* aSink)
|
||||
: mToolkit(aToolkit), mMessageSink(aSink)
|
||||
{
|
||||
mRunning = PR_FALSE;
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
/* Destructor
|
||||
* @update dc 08/31/98
|
||||
* @param NONE
|
||||
* @return NONE
|
||||
*/
|
||||
nsMacMessagePump::~nsMacMessagePump()
|
||||
{
|
||||
//¥¥¥ release the toolkits and sinks? not if we use COM_auto_ptr.
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
/* Runs the message pump for the macintosh. Turns them into Raptor events
|
||||
* @update dc 08/31/98
|
||||
* @param NONE
|
||||
* @return A boolean which states how the pump terminated
|
||||
*/
|
||||
PRBool
|
||||
nsMacMessagePump::DoMessagePump()
|
||||
{
|
||||
Boolean haveEvent;
|
||||
EventRecord theEvent;
|
||||
long sleep = 0;
|
||||
unsigned short eventMask = (everyEvent - diskMask);
|
||||
|
||||
mRunning = PR_TRUE;
|
||||
mInBackground = PR_FALSE;
|
||||
|
||||
// calculate the region to watch
|
||||
RgnHandle mouseRgn = ::NewRgn();
|
||||
::SetRectRgn(mouseRgn, -32000, -32000, -32001, -32001);
|
||||
|
||||
while (mRunning)
|
||||
{
|
||||
::LMSetSysEvtMask(eventMask); // we need keyUp events
|
||||
haveEvent = ::WaitNextEvent(eventMask, &theEvent, sleep, mouseRgn);
|
||||
|
||||
if (haveEvent)
|
||||
{
|
||||
switch(theEvent.what)
|
||||
{
|
||||
case keyUp:
|
||||
case keyDown:
|
||||
case autoKey:
|
||||
DoKey(theEvent);
|
||||
break;
|
||||
|
||||
case mouseDown:
|
||||
DoMouseDown(theEvent);
|
||||
break;
|
||||
|
||||
case mouseUp:
|
||||
DoMouseUp(theEvent);
|
||||
break;
|
||||
|
||||
case updateEvt:
|
||||
DoUpdate(theEvent);
|
||||
break;
|
||||
|
||||
case activateEvt:
|
||||
DoActivate(theEvent);
|
||||
break;
|
||||
|
||||
case osEvt:
|
||||
unsigned char eventType = ((theEvent.message >> 24) & 0x00ff);
|
||||
switch (eventType)
|
||||
{
|
||||
case SUSPENDRESUMEMESSAGE:
|
||||
if (theEvent.message & 0x00000001)
|
||||
mInBackground = PR_FALSE; // resume message
|
||||
else
|
||||
mInBackground = PR_TRUE; // suspend message
|
||||
break;
|
||||
|
||||
case MOUSEMOVEDMESSAGE:
|
||||
DoMouseMove(theEvent);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DoIdle(theEvent);
|
||||
if (mRunning)
|
||||
LPeriodical::DevoteTimeToIdlers(theEvent);
|
||||
}
|
||||
|
||||
if (mRunning)
|
||||
LPeriodical::DevoteTimeToRepeaters(theEvent);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// DoUpdate
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
void nsMacMessagePump::DoUpdate(EventRecord &anEvent)
|
||||
{
|
||||
WindowPtr whichWindow = (WindowPtr)anEvent.message;
|
||||
if (IsUserWindow(whichWindow))
|
||||
{
|
||||
GrafPtr savePort;
|
||||
::GetPort(&savePort);
|
||||
::SetPort(whichWindow);
|
||||
::BeginUpdate(whichWindow);
|
||||
#if 0 //¥¥¥test¥¥¥
|
||||
static Boolean aBool = 1;
|
||||
RGBColor green = {0,65535,0};
|
||||
RGBColor red = {65535,0,0};
|
||||
::RGBForeColor((aBool ? &green : &red));
|
||||
aBool ^= 1;
|
||||
::PenSize(2,2);
|
||||
::ClipRect(&whichWindow->portRect);
|
||||
::FrameRgn(whichWindow->visRgn);
|
||||
#endif //¥¥¥¥¥¥¥¥¥
|
||||
// The app can do its own updates here
|
||||
DispatchOSEventToRaptor(anEvent, whichWindow);
|
||||
::EndUpdate(whichWindow);
|
||||
::SetPort(savePort);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// DoMouseDown
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
void nsMacMessagePump::DoMouseDown(EventRecord &anEvent)
|
||||
{
|
||||
WindowPtr whichWindow;
|
||||
PRInt16 partCode;
|
||||
|
||||
partCode = ::FindWindow(anEvent.where, &whichWindow);
|
||||
|
||||
switch (partCode)
|
||||
{
|
||||
case inSysWindow:
|
||||
break;
|
||||
|
||||
case inMenuBar:
|
||||
{
|
||||
long menuResult = ::MenuSelect(anEvent.where);
|
||||
if (HiWord(menuResult) != 0)
|
||||
DoMenu(anEvent, menuResult);
|
||||
break;
|
||||
}
|
||||
|
||||
case inContent:
|
||||
{
|
||||
::SetPort(whichWindow);
|
||||
if (IsWindowHilited(whichWindow))
|
||||
DispatchOSEventToRaptor(anEvent, whichWindow);
|
||||
else
|
||||
::SelectWindow(whichWindow);
|
||||
break;
|
||||
}
|
||||
|
||||
case inDrag:
|
||||
{
|
||||
::SetPort(whichWindow);
|
||||
if (!(anEvent.modifiers & cmdKey))
|
||||
::SelectWindow(whichWindow);
|
||||
Rect screenRect = qd.screenBits.bounds;
|
||||
::InsetRect(&screenRect, 4, 4);
|
||||
screenRect.top += ::LMGetMBarHeight();
|
||||
::DragWindow(whichWindow, anEvent.where, &screenRect);
|
||||
|
||||
::GetMouse(&anEvent.where);
|
||||
::LocalToGlobal(&anEvent.where);
|
||||
// it's not really necessary to send that event to Raptor but (who knows?)
|
||||
// some windows may want to know that they have been moved
|
||||
DispatchOSEventToRaptor(anEvent, whichWindow);
|
||||
break;
|
||||
}
|
||||
|
||||
case inGrow:
|
||||
{
|
||||
::SetPort(whichWindow);
|
||||
#ifdef DRAW_ON_RESIZE
|
||||
Point oldPt = anEvent.where;
|
||||
while (::WaitMouseUp())
|
||||
{
|
||||
LPeriodical::DevoteTimeToRepeaters(anEvent);
|
||||
Point newPt;
|
||||
::GetMouse(&newPt);
|
||||
::LocalToGlobal(&newPt);
|
||||
if (::DeltaPoint(oldPt, newPt))
|
||||
{
|
||||
Rect portRect = whichWindow->portRect;
|
||||
short width = (portRect.right - portRect.left) + (newPt.h - oldPt.h);
|
||||
short height = (portRect.bottom - portRect.top) + (newPt.v - oldPt.v);
|
||||
|
||||
oldPt = newPt;
|
||||
::SizeWindow(whichWindow, width, height, true);
|
||||
::DrawGrowIcon(whichWindow);
|
||||
anEvent.where = newPt; // important!
|
||||
DispatchOSEventToRaptor(anEvent, whichWindow);
|
||||
}
|
||||
}
|
||||
#else
|
||||
Rect sizeRect;
|
||||
sizeRect.bottom = qd.screenBits.bounds.bottom;
|
||||
sizeRect.right = qd.screenBits.bounds.right;
|
||||
sizeRect.top = sizeRect.left = 75;
|
||||
long newSize = ::GrowWindow(whichWindow, anEvent.where, &sizeRect);
|
||||
if (newSize != 0)
|
||||
::SizeWindow(whichWindow, newSize & 0x0FFFF, (newSize >> 16) & 0x0FFFF, true);
|
||||
::DrawGrowIcon(whichWindow);
|
||||
Point newPt;
|
||||
::GetMouse(&newPt);
|
||||
::LocalToGlobal(&newPt);
|
||||
anEvent.where = newPt; // important!
|
||||
DispatchOSEventToRaptor(anEvent, whichWindow);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case inGoAway:
|
||||
{
|
||||
::SetPort(whichWindow);
|
||||
if (::TrackGoAway(whichWindow, anEvent.where))
|
||||
DispatchOSEventToRaptor(anEvent, whichWindow);
|
||||
break;
|
||||
}
|
||||
|
||||
case inZoomIn:
|
||||
case inZoomOut:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// DoMouseUp
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
void nsMacMessagePump::DoMouseUp(EventRecord &anEvent)
|
||||
{
|
||||
WindowPtr whichWindow;
|
||||
PRInt16 partCode;
|
||||
|
||||
partCode = ::FindWindow(anEvent.where, &whichWindow);
|
||||
if (whichWindow == nil)
|
||||
{
|
||||
// We need to report the event even when it happens over no window:
|
||||
// when the user clicks a widget, keeps the mouse button pressed and
|
||||
// releases it outside the window, the event needs to be reported to
|
||||
// the widget so that it can deactivate itself.
|
||||
whichWindow = ::FrontWindow();
|
||||
}
|
||||
DispatchOSEventToRaptor(anEvent, whichWindow);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// DoMouseMove
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
void nsMacMessagePump::DoMouseMove(EventRecord &anEvent)
|
||||
{
|
||||
// same thing as DoMouseUp
|
||||
WindowPtr whichWindow;
|
||||
PRInt16 partCode;
|
||||
|
||||
partCode = ::FindWindow(anEvent.where, &whichWindow);
|
||||
if (whichWindow == nil)
|
||||
whichWindow = ::FrontWindow();
|
||||
DispatchOSEventToRaptor(anEvent, whichWindow);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// DoKey
|
||||
//
|
||||
// This is called for keydown, keyup, and key repeating events. So we need
|
||||
// to be careful not to do things twice.
|
||||
//-------------------------------------------------------------------------
|
||||
void nsMacMessagePump::DoKey(EventRecord &anEvent)
|
||||
{
|
||||
char theChar = (char)(anEvent.message & charCodeMask);
|
||||
if ((anEvent.what == keyDown) && ((anEvent.modifiers & cmdKey) != 0))
|
||||
{
|
||||
// do a menu key command
|
||||
long menuResult = ::MenuKey(theChar);
|
||||
if (HiWord(menuResult) != 0)
|
||||
DoMenu(anEvent, menuResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
DispatchOSEventToRaptor(anEvent, ::FrontWindow());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// DoMenu
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
void nsMacMessagePump::DoMenu(EventRecord &anEvent, long menuResult)
|
||||
{
|
||||
// The app can handle its menu commands here or
|
||||
// in the nsNativeBrowserWindow and nsNativeViewerApp
|
||||
if (::FrontWindow() != nil)
|
||||
{
|
||||
DispatchMenuCommandToRaptor(anEvent, menuResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gWindowlessMenuEventHandler != nsnull)
|
||||
gWindowlessMenuEventHandler(menuResult);
|
||||
}
|
||||
HiliteMenu(0);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// DoActivate
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
void nsMacMessagePump::DoActivate(EventRecord &anEvent)
|
||||
{
|
||||
WindowPtr whichWindow = (WindowPtr)anEvent.message;
|
||||
::SetPort(whichWindow);
|
||||
if (anEvent.modifiers & activeFlag)
|
||||
{
|
||||
::BringToFront(whichWindow);
|
||||
::HiliteWindow(whichWindow,TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
::HiliteWindow(whichWindow,FALSE);
|
||||
}
|
||||
|
||||
DispatchOSEventToRaptor(anEvent, whichWindow);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// DoIdle
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
void nsMacMessagePump::DoIdle(EventRecord &anEvent)
|
||||
{
|
||||
// send mouseMove event
|
||||
static Point lastWhere = {0, 0};
|
||||
|
||||
if (*(long*)&lastWhere == *(long*)&anEvent.where)
|
||||
return;
|
||||
|
||||
lastWhere = anEvent.where;
|
||||
DoMouseMove(anEvent);
|
||||
|
||||
// idle controls //¥TODO? : is this really necessary?
|
||||
WindowPtr win = ::FrontWindow();
|
||||
while (win)
|
||||
{
|
||||
::SetPort(win);
|
||||
::SetOrigin(0,0);
|
||||
::ClipRect(&win->portRect);
|
||||
::IdleControls(win);
|
||||
win = ::GetNextWindow(win);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// DispatchOSEventToRaptor
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
void nsMacMessagePump::DispatchOSEventToRaptor(
|
||||
EventRecord &anEvent,
|
||||
WindowPtr aWindow)
|
||||
{
|
||||
if (aWindow && IsUserWindow(aWindow))
|
||||
mMessageSink->DispatchOSEvent(anEvent, aWindow);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// DispatchMenuCommandToRaptor
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
void nsMacMessagePump::DispatchMenuCommandToRaptor(
|
||||
EventRecord &anEvent,
|
||||
long menuResult)
|
||||
{
|
||||
WindowPtr whichWindow = ::FrontWindow();
|
||||
if (whichWindow && IsUserWindow(whichWindow))
|
||||
mMessageSink->DispatchMenuCommand(anEvent, menuResult);
|
||||
|
||||
}
|
75
widget/src/mac/nsMacMessagePump.h
Normal file
75
widget/src/mac/nsMacMessagePump.h
Normal file
@ -0,0 +1,75 @@
|
||||
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsMacMessagePump_h__
|
||||
#define nsMacMessagePump_h__
|
||||
|
||||
#include <Events.h>
|
||||
#include "prtypes.h"
|
||||
|
||||
class nsToolkit;
|
||||
class nsMacMessageSink;
|
||||
|
||||
//================================================
|
||||
|
||||
// Macintosh Message Pump Class
|
||||
class nsMacMessagePump
|
||||
{
|
||||
// CLASS MEMBERS
|
||||
private:
|
||||
PRBool mRunning;
|
||||
Point mMousePoint; // keep track of where the mouse is at all times
|
||||
PRBool mInBackground;
|
||||
nsToolkit* mToolkit;
|
||||
nsMacMessageSink* mMessageSink; //¥¥¥ should be COM_auto_ptr
|
||||
|
||||
// CLASS METHODS
|
||||
|
||||
public:
|
||||
nsMacMessagePump(nsToolkit *aToolKit, nsMacMessageSink* aSink);
|
||||
virtual ~nsMacMessagePump();
|
||||
|
||||
PRBool DoMessagePump();
|
||||
void StopRunning() {mRunning = PR_FALSE;}
|
||||
|
||||
private:
|
||||
void DoMouseDown(EventRecord &anEvent);
|
||||
void DoMouseUp(EventRecord &anEvent);
|
||||
void DoMouseMove(EventRecord &anEvent);
|
||||
void DoUpdate(EventRecord &anEvent);
|
||||
void DoKey(EventRecord &anEvent);
|
||||
void DoMenu(EventRecord &anEvent, long menuResult);
|
||||
void DoActivate(EventRecord &anEvent);
|
||||
void DoIdle(EventRecord &anEvent);
|
||||
|
||||
void DispatchOSEventToRaptor(EventRecord &anEvent, WindowPtr aWindow);
|
||||
void DispatchMenuCommandToRaptor(EventRecord &anEvent, long menuResult);
|
||||
|
||||
public:
|
||||
typedef void (*nsWindowlessMenuEventHandler) (PRInt32 menuResult);
|
||||
static nsWindowlessMenuEventHandler gWindowlessMenuEventHandler;
|
||||
static void SetWindowlessMenuEventHandler(nsWindowlessMenuEventHandler func)
|
||||
{gWindowlessMenuEventHandler = func;}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // nsMacMessagePump_h__
|
||||
|
Loading…
x
Reference in New Issue
Block a user