Files
Mozilla/mozilla/widget/src/mac/nsMacMessagePump.cpp
thom%netscape.com 9668f3bd42 Quick hack to get timers working (added call to tickle LPeriodical class)
git-svn-id: svn://10.0.0.236/trunk@9292 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-04 00:28:35 +00:00

579 lines
14 KiB
C++

/* -*- 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 "nsWindow.h"
#include <LPeriodical.h>
#include "net.h" //¥¥¥TEMPORARY
#define IsUserWindow(wp) (wp && ((((WindowPeek)wp)->windowKind) >= userKind))
nsWindow* nsMacMessagePump::gCurrentWindow = nsnull;
nsWindow* nsMacMessagePump::gGrabWindow = nsnull; // need this for grabmouse
//==============================================================
nsMacMessagePump::nsMacMessagePump(nsMacMessenger *aTheMessageProc)
{
mMessenger = aTheMessageProc;
mRunning = PR_FALSE;
}
//==============================================================
nsMacMessagePump::~nsMacMessagePump()
{
}
//==============================================================
PRBool
nsMacMessagePump::DoMessagePump()
{
PRBool stillrunning = PR_TRUE;
EventRecord theevent;
long sleep=0;
PRInt16 haveevent;
WindowPtr whichwindow;
RgnHandle currgn;
unsigned char evtype;
#define SUSPENDRESUMEMESSAGE 0x01
#define MOUSEMOVEDMESSAGE 0xFA
mRunning = PR_TRUE;
mInBackground = PR_FALSE;
// calculate the regions to watch
currgn = ::NewRgn();
SetRectRgn(currgn,-32000,-32000,-32000,-32000);
while(mRunning && stillrunning)
{
haveevent = ::WaitNextEvent(everyEvent,&theevent,sleep,0l);
NET_PollSockets(); //¥¥¥TEMPORARY
if(haveevent)
{
switch(theevent.what)
{
case diskEvt:
if(theevent.message<0)
{
// error, bad disk mount
}
break;
case keyUp:
break;
case keyDown:
case autoKey:
DoKey(&theevent);
break;
case mouseDown:
DoMouseDown(&theevent);
break;
case mouseUp:
DoMouseUp(&theevent);
break;
case updateEvt:
DoPaintEvent(&theevent);
break;
case activateEvt:
whichwindow = (WindowPtr)theevent.message;
SetPort(whichwindow);
if(theevent.modifiers & activeFlag)
{
::BringToFront(whichwindow);
::HiliteWindow(whichwindow,TRUE);
}
else
{
::HiliteWindow(whichwindow,FALSE);
}
break;
case osEvt:
default:
evtype = (unsigned char) (theevent.message>>24)&0x00ff;
switch(evtype)
{
//case MOUSEMOVEDMESSAGE:
//DoMouseMove(&theevent);
//break;
case SUSPENDRESUMEMESSAGE:
if(theevent.message&0x00000001)
{
// resume message
mInBackground = PR_FALSE;
}
else
{
// suspend message
mInBackground = PR_TRUE;
}
break;
}
break;
}
}
else
{
switch(theevent.what)
{
case nullEvent:
DoIdleWidgets();
// construct the mousemove myself
::GetMouse(&theevent.where);
LocalToGlobal(&theevent.where);
DoMouseMove(&theevent);
break;
}
}
if(mMessenger)
stillrunning = mMessenger->IsRunning();
LPeriodical::DevoteTimeToRepeaters(theevent);
}
//if (mDispatchListener)
//mDispatchListener->AfterDispatch();
return NS_OK;
}
//==============================================================
void
nsMacMessagePump::DoPaintEvent(EventRecord *aTheEvent)
{
GrafPtr curport;
WindowPtr whichwindow;
nsWindow *thewindow;
nsRect rect;
RgnHandle updateregion;
::GetPort(&curport);
whichwindow = (WindowPtr)aTheEvent->message;
if (IsUserWindow(whichwindow))
{
SetPort(whichwindow);
BeginUpdate(whichwindow);
thewindow = (nsWindow*)(((WindowPeek)whichwindow)->refCon);
if(thewindow != nsnull)
{
updateregion = whichwindow->visRgn;
thewindow->DoPaintWidgets(updateregion);
}
EndUpdate(whichwindow);
}
::SetPort(curport);
}
//==============================================================
void
nsMacMessagePump::DoIdleWidgets()
{
WindowPtr whichwindow;
nsWindow *thewindow;
whichwindow = ::FrontWindow();
while(whichwindow)
{
// idle the widget
thewindow = (nsWindow*)(((WindowPeek)whichwindow)->refCon);
whichwindow = (WindowPtr)((WindowPeek)whichwindow)->nextWindow;
}
}
//==============================================================
void
nsMacMessagePump::DoMouseDown(EventRecord *aTheEvent)
{
Rect therect;
Point windowcoord;
long newsize; // window's new size
WindowPtr whichwindow;
PRInt16 partcode;
nsWindow *thewindow;
nsMouseEvent mouseevent;
partcode = FindWindow(aTheEvent->where,&whichwindow);
if(whichwindow!=0)
{
SelectWindow(whichwindow);
thewindow = (nsWindow*)(((WindowPeek)whichwindow)->refCon);
if(thewindow != nsnull)
{
thewindow = thewindow->FindWidgetHit(aTheEvent->where);
}
switch(partcode)
{
case inSysWindow:
break;
case inContent:
if(thewindow)
{
SetPort(whichwindow);
mouseevent.message = NS_MOUSE_LEFT_BUTTON_DOWN;
mouseevent.widget = (nsWindow *) thewindow;
windowcoord = aTheEvent->where;
GlobalToLocal(&windowcoord);
mouseevent.point.x = windowcoord.h;
mouseevent.point.y = windowcoord.v;
mouseevent.time = 0;
mouseevent.isShift = FALSE;
mouseevent.isControl = FALSE;
mouseevent.isAlt = FALSE;
mouseevent.clickCount = 1;
mouseevent.eventStructType = NS_MOUSE_EVENT;
thewindow->DispatchMouseEvent(mouseevent);
gGrabWindow = (nsWindow*)thewindow; // grab is in effect
this->SetCurrentWindow(thewindow);
}
break;
case inDrag:
therect = qd.screenBits.bounds;
InsetRect(&therect, 3,3);
therect.top += 20; /* Allow space for menu bar */
DragWindow(whichwindow, aTheEvent->where, &therect);
therect = whichwindow->portRect;
if (thewindow != nsnull)
{
LocalToGlobal(&topLeft(therect));
LocalToGlobal(&botRight(therect));
thewindow->SetBounds(therect);
}
break;
case inGrow:
SetPort(whichwindow);
therect = whichwindow->portRect;
EraseRect(&therect);
InvalRect(&therect);
// Set up the window's allowed minimum and maximum sizes
therect.bottom = qd.screenBits.bounds.bottom;
therect.right = qd.screenBits.bounds.right;
therect.top = therect.left = 75;
newsize = GrowWindow(whichwindow, aTheEvent->where, &therect);
if(newsize != 0)
SizeWindow(whichwindow, newsize & 0x0FFFF, (newsize >> 16) & 0x0FFFF, true);
// Draw the grow icon & validate that area
therect = whichwindow->portRect;
therect.left = therect.right - 16;
therect.top = therect.bottom - 16;
DrawGrowIcon(whichwindow);
ValidRect(&therect);
if (thewindow != nsnull)
{
therect = whichwindow->portRect;
LocalToGlobal(&topLeft(therect));
LocalToGlobal(&botRight(therect));
thewindow->SetBounds(therect);
}
break;
case inGoAway:
if(TrackGoAway(whichwindow,aTheEvent->where))
if(thewindow)
{
thewindow->Destroy();
mRunning = PR_FALSE;
}
else
{
}
break;
case inZoomIn:
case inZoomOut:
break;
case inMenuBar:
break;
}
}
}
//==============================================================
void
nsMacMessagePump::DoMouseUp(EventRecord *aTheEvent)
{
WindowPtr whichwindow;
PRInt16 partcode;
Point windowcoord;
nsWindow *thewindow;
nsMouseEvent mouseevent;
partcode = FindWindow(aTheEvent->where,&whichwindow);
if(gGrabWindow)
{
mouseevent.message = NS_MOUSE_LEFT_BUTTON_UP;
mouseevent.widget = (nsWindow *) gGrabWindow;
windowcoord = aTheEvent->where;
GlobalToLocal(&windowcoord);
mouseevent.point.x = windowcoord.h;
mouseevent.point.y = windowcoord.v;
mouseevent.time = 0;
mouseevent.isShift = FALSE;
mouseevent.isControl = FALSE;
mouseevent.isAlt = FALSE;
mouseevent.clickCount = 1;
mouseevent.eventStructType = NS_MOUSE_EVENT;
gGrabWindow->DispatchMouseEvent(mouseevent);
gGrabWindow = nsnull; // mouse grab no longer in effect
return;
}
if(whichwindow!=0)
{
SelectWindow(whichwindow);
thewindow = (nsWindow*)(((WindowPeek)whichwindow)->refCon);
if(thewindow != nsnull)
thewindow = thewindow->FindWidgetHit(aTheEvent->where);
switch(partcode)
{
case inSysWindow:
break;
case inContent:
if(thewindow)
{
SetPort(whichwindow);
mouseevent.message = NS_MOUSE_LEFT_BUTTON_UP;
mouseevent.widget = (nsWindow *) thewindow;
windowcoord = aTheEvent->where;
GlobalToLocal(&windowcoord);
mouseevent.point.x = windowcoord.h;
mouseevent.point.y = windowcoord.v;
mouseevent.time = 0;
mouseevent.isShift = FALSE;
mouseevent.isControl = FALSE;
mouseevent.isAlt = FALSE;
mouseevent.clickCount = 1;
mouseevent.eventStructType = NS_MOUSE_EVENT;
thewindow->DispatchMouseEvent(mouseevent);
}
break;
}
}
gGrabWindow = nsnull; // mouse grab no longer in effect
}
//==============================================================
void
nsMacMessagePump::DoMouseMove(EventRecord *aTheEvent)
{
WindowPtr whichwindow;
PRInt16 partcode;
Point windowcoord;
nsWindow *thewindow,*lastwindow;
nsMouseEvent mouseevent;
if (*(long*)&mMousePoint == *(long*)&aTheEvent->where)
return;
mouseevent.time = 0;
mouseevent.isShift = FALSE;
mouseevent.isControl = FALSE;
mouseevent.isAlt = FALSE;
mouseevent.clickCount = 1;
mouseevent.eventStructType = NS_MOUSE_EVENT;
lastwindow = this->GetCurrentWindow();
mMousePoint = aTheEvent->where;
partcode = FindWindow(aTheEvent->where,&whichwindow);
thewindow = nsnull;
if(whichwindow!=nsnull)
{
SetPort(whichwindow);
thewindow = (nsWindow*)(((WindowPeek)whichwindow)->refCon);
}
if( (thewindow != nsnull))
thewindow = thewindow->FindWidgetHit(aTheEvent->where);
if(gGrabWindow)
{
if( /*(gGrabWindow==thewindow) ||*/ thewindow==lastwindow)
{
// JUST A MOUSE MOVE
mouseevent.message = NS_MOUSE_MOVE;
mouseevent.widget = (nsWindow *) gGrabWindow;
windowcoord = aTheEvent->where;
GlobalToLocal(&windowcoord);
mouseevent.point.x = windowcoord.h;
mouseevent.point.y = windowcoord.v;
gGrabWindow->DispatchMouseEvent(mouseevent);
this->SetCurrentWindow(thewindow);
}
else
{
// EXIT or ENTER?
if(lastwindow == nsnull || thewindow != lastwindow)
{
if(lastwindow == gGrabWindow)
{
mouseevent.message = NS_MOUSE_EXIT;
mouseevent.widget = (nsWindow *) gGrabWindow;
windowcoord = aTheEvent->where;
GlobalToLocal(&windowcoord);
mouseevent.point.x = windowcoord.h;
mouseevent.point.y = windowcoord.v;
gGrabWindow->DispatchMouseEvent(mouseevent);
this->SetCurrentWindow(thewindow);
}
else
{
mouseevent.message = NS_MOUSE_ENTER;
mouseevent.widget = (nsWindow *) gGrabWindow;
windowcoord = aTheEvent->where;
GlobalToLocal(&windowcoord);
mouseevent.point.x = windowcoord.h;
mouseevent.point.y = windowcoord.v;
gGrabWindow->DispatchMouseEvent(mouseevent);
this->SetCurrentWindow(thewindow);
}
}
}
return;
}
//partcode = FindWindow(aTheEvent->where,&whichwindow);
switch(partcode)
{
case inContent:
//thewindow = nsnull;
//if(whichwindow!=nsnull)
//{
//SetPort(whichwindow);
//thewindow = (nsWindow*)(((WindowPeek)whichwindow)->refCon);
//}
//if( (thewindow != nsnull))
//thewindow = thewindow->FindWidgetHit(aTheEvent->where);
if(thewindow)
{
if(lastwindow == nsnull || thewindow != lastwindow)
{
// mouseexit
if(lastwindow != nsnull)
{
mouseevent.message = NS_MOUSE_EXIT;
mouseevent.widget = (nsWindow *) lastwindow;
windowcoord = aTheEvent->where;
GlobalToLocal(&windowcoord);
mouseevent.point.x = windowcoord.h;
mouseevent.point.y = windowcoord.v;
lastwindow->DispatchMouseEvent(mouseevent);
}
// mouseenter
this->SetCurrentWindow(thewindow);
mouseevent.message = NS_MOUSE_ENTER;
mouseevent.widget = (nsWindow *) thewindow;
windowcoord = aTheEvent->where;
GlobalToLocal(&windowcoord);
mouseevent.point.x = windowcoord.h;
mouseevent.point.y = windowcoord.v;
thewindow->DispatchMouseEvent(mouseevent);
}
else
{
// mousedown inside the content region
mouseevent.message = NS_MOUSE_MOVE;
mouseevent.widget = (nsWindow *) thewindow;
windowcoord = aTheEvent->where;
GlobalToLocal(&windowcoord);
mouseevent.point.x = windowcoord.h;
mouseevent.point.y = windowcoord.v;
thewindow->DispatchMouseEvent(mouseevent);
break;
}
}
break;
default:
if(lastwindow != nsnull)
{
this->SetCurrentWindow(nsnull);
mouseevent.message = NS_MOUSE_EXIT;
mouseevent.widget = (nsWindow *) lastwindow;
windowcoord = aTheEvent->where;
GlobalToLocal(&windowcoord);
mouseevent.point.x = windowcoord.h;
mouseevent.point.y = windowcoord.v;
lastwindow->DispatchMouseEvent(mouseevent);
}
break;
}
}
//==============================================================
void
nsMacMessagePump::DoKey(EventRecord *aTheEvent)
{
char ch;
WindowPtr whichwindow;
ch = (char)(aTheEvent->message & charCodeMask);
if(aTheEvent->modifiers&cmdKey)
{
// do a menu key command
}
else
{
whichwindow = FrontWindow();
if(whichwindow)
{
// generate a keydown event for the widget
}
}
}
//==============================================================