319 lines
7.4 KiB
C
319 lines
7.4 KiB
C
/***********************************************************************/
|
|
/* */
|
|
/* Objective Caml */
|
|
/* */
|
|
/* Damien Doligez, projet Para, INRIA Rocquencourt */
|
|
/* */
|
|
/* Copyright 1997 Institut National de Recherche en Informatique et */
|
|
/* en Automatique. All rights reserved. This file is distributed */
|
|
/* under the terms of the GNU Library General Public License. */
|
|
/* */
|
|
/***********************************************************************/
|
|
|
|
/* $Id$ */
|
|
|
|
#include "main.h"
|
|
|
|
/* [intr_requested] is true if the user typed command-period and the
|
|
SIGINT signal was not yet delivered.
|
|
*/
|
|
int intr_requested = 0;
|
|
|
|
UInt32 last_event_date = 0;
|
|
|
|
UInt32 evtSleep = 0;
|
|
static RgnHandle mouseRegion = NULL;
|
|
static RgnHandle pointRegion = NULL;
|
|
|
|
static void AdjustCursor (Point mouse, RgnHandle mouseRegion)
|
|
{
|
|
WindowPtr w = FrontWindow ();
|
|
WEHandle we = WinGetWE (w);
|
|
int k = WinGetKind (w);
|
|
Boolean res;
|
|
|
|
SetRectRgn (mouseRegion, -SHRT_MAX, -SHRT_MAX, SHRT_MAX, SHRT_MAX);
|
|
if (we != NULL && k != kWinAbout){
|
|
if (w == winToplevel){
|
|
res = AdjustRotatingCursor ();
|
|
if (res) return;
|
|
}
|
|
res = WEAdjustCursor (mouse, mouseRegion, we);
|
|
if (res) return;
|
|
}
|
|
SetCursor (&qd.arrow);
|
|
}
|
|
|
|
static void DoActivate (EventRecord *evt)
|
|
{
|
|
WindowPtr w = (WindowPtr) evt->message;
|
|
|
|
if (GetWindowKind (w) != userKind) return; /*XXX*/
|
|
WinActivateDeactivate (evt->modifiers & activeFlag, w);
|
|
}
|
|
|
|
static void DoDiskEvent (EventRecord *evt)
|
|
{
|
|
OSErr err;
|
|
Point pt;
|
|
|
|
if (evt->message >> 16 != noErr){
|
|
DILoad ();
|
|
err = DIBadMount (pt, evt->message); /* [pt] is ignored */
|
|
if (err != noErr && err != 1 && err != 2){
|
|
ErrorAlertGeneric (err); /* XXX or nothing ? */
|
|
}
|
|
DIUnload ();
|
|
}
|
|
}
|
|
|
|
static void DoKeyDown (EventRecord *evt)
|
|
{
|
|
short chr = evt->message & charCodeMask;
|
|
Boolean isCmdKey = (evt->modifiers & cmdKey) != 0;
|
|
|
|
if (chr == 0x10){
|
|
switch ((evt->message & keyCodeMask) >> 8){
|
|
case keyF1:
|
|
isCmdKey = 1;
|
|
chr = 'z';
|
|
break;
|
|
case keyF2:
|
|
isCmdKey = 1;
|
|
chr = 'x';
|
|
break;
|
|
case keyF3:
|
|
isCmdKey = 1;
|
|
chr = 'c';
|
|
break;
|
|
case keyF4:
|
|
isCmdKey = 1;
|
|
chr = 'v';
|
|
break;
|
|
default:
|
|
chr = -1;
|
|
}
|
|
}
|
|
if (isCmdKey && chr == '.'
|
|
&& FrontWindow () == winToplevel
|
|
&& evt->what != autoKey){
|
|
FlushUnreadInput ();
|
|
raise (SIGINT);
|
|
}
|
|
if (isCmdKey && chr >= 0x20){
|
|
UpdateMenus ();
|
|
DoMenuChoice (MenuKey (chr), evt->modifiers);
|
|
}else{
|
|
WindowPtr w = FrontWindow ();
|
|
if (chr != -1 && w != NULL){
|
|
WinDoKey (w, chr, evt);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void DoMouseDown (EventRecord *event)
|
|
{
|
|
WindowPtr w;
|
|
short partCode;
|
|
|
|
partCode = FindWindow (event->where, &w);
|
|
switch (partCode){
|
|
case inMenuBar:
|
|
UpdateMenus ();
|
|
DoMenuChoice (MenuSelect (event->where), event->modifiers);
|
|
break;
|
|
case inSysWindow:
|
|
SystemClick (event, w);
|
|
break;
|
|
case inContent:
|
|
WinDoContentClick (event, w);
|
|
break;
|
|
case inDrag:
|
|
WinDoDrag (event->where, w);
|
|
break;
|
|
case inGrow:
|
|
WinDoGrow (event->where, w);
|
|
break;
|
|
case inGoAway:
|
|
if (TrackGoAway (w, event->where)) WinDoClose (closingWindow, w);
|
|
break;
|
|
case inZoomIn:
|
|
case inZoomOut:
|
|
if (TrackBox (w, event->where, partCode)) WinDoZoom (w, partCode);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* XXX recuperer les mouse-up pour matcher les mouse-down ? */
|
|
static void DoMouseUp (EventRecord *e)
|
|
{
|
|
short partCode;
|
|
WindowPtr w;
|
|
Point hitpt;
|
|
GrafPtr saveport;
|
|
Rect r;
|
|
|
|
if (FrontWindow () != winGraphics) return;
|
|
partCode = FindWindow (e->where, &w);
|
|
if (partCode != inContent) return;
|
|
PushWindowPort (winGraphics);
|
|
hitpt = e->where;
|
|
GlobalToLocal (&hitpt);
|
|
ScrollCalcGraph (winGraphics, &r);
|
|
if (PtInRect (hitpt, &r)) GraphGotEvent (e);
|
|
PopPort;
|
|
return;
|
|
}
|
|
|
|
static void DoNullEvent (EventRecord *event)
|
|
{
|
|
#pragma unused (event)
|
|
WindowPtr w = FrontWindow ();
|
|
|
|
if (w != NULL) WinDoIdle (w);
|
|
}
|
|
|
|
static void DoOSEvent (EventRecord *event)
|
|
{
|
|
int msg = (event->message & osEvtMessageMask) >> 24;
|
|
WindowPtr w;
|
|
|
|
switch (msg){
|
|
case suspendResumeMessage:
|
|
w = FrontWindow ();
|
|
if (w != NULL){
|
|
Boolean state = !! (event->message & resumeFlag);
|
|
WinActivateDeactivate (state, w);
|
|
}
|
|
if (event->message & convertClipboardFlag) ClipChanged ();
|
|
case mouseMovedMessage: ;
|
|
}
|
|
}
|
|
|
|
static void DoUpdate (EventRecord *evt)
|
|
{
|
|
WindowPtr w = (WindowPtr) evt->message;
|
|
|
|
if (GetWindowKind (w) != userKind) return; /*XXX*/
|
|
WinUpdate (w);
|
|
}
|
|
|
|
static void DoDialogEvent (EventRecord *evt)
|
|
{
|
|
DialogPtr dlg;
|
|
short itm;
|
|
|
|
if (evt->what == diskEvt){
|
|
DoDiskEvent (evt);
|
|
return;
|
|
}else if (evt->what == keyDown || evt->what == autoKey){
|
|
if (evt->modifiers & cmdKey){
|
|
DoKeyDown (evt);
|
|
return;
|
|
}else{
|
|
switch ((evt->message & charCodeMask) >> 8){
|
|
case '\n':
|
|
XXX (); /*XXX return key*/
|
|
return;
|
|
case '\033':
|
|
XXX (); /*XXX escape key */
|
|
return;
|
|
default: break;
|
|
}
|
|
}
|
|
}
|
|
if (DialogSelect (evt, &dlg, &itm)){
|
|
switch (WinGetKind (dlg)){
|
|
case kWinAbout:
|
|
Assert (0); /* No item is enabled. */
|
|
break;
|
|
case kWinPrefs:
|
|
XXX ();
|
|
break;
|
|
default:
|
|
Assert (0); /* Other windows are not dialogs. */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static pascal Boolean ProcessEvent (EventRecord *evt, long *sleep,
|
|
RgnHandle *rgn)
|
|
{
|
|
if (evt->what <= osEvt) AdjustCursor (evt->where, mouseRegion);
|
|
if (IsDialogEvent (evt)){
|
|
DoDialogEvent (evt);
|
|
}else{
|
|
switch (evt->what){
|
|
case nullEvent:
|
|
DoNullEvent (evt);
|
|
break;
|
|
case mouseDown:
|
|
DoMouseDown (evt);
|
|
break;
|
|
case mouseUp: /* Needed for the graphics window. */
|
|
DoMouseUp (evt);
|
|
break;
|
|
case keyDown:
|
|
case autoKey:
|
|
DoKeyDown (evt);
|
|
break;
|
|
case updateEvt:
|
|
DoUpdate (evt);
|
|
break;
|
|
case activateEvt:
|
|
DoActivate (evt);
|
|
break;
|
|
case diskEvt:
|
|
DoDiskEvent (evt);
|
|
break;
|
|
case osEvt:
|
|
DoOSEvent (evt);
|
|
break;
|
|
case kHighLevelEvent:
|
|
AEProcessAppleEvent (evt);
|
|
break;
|
|
}
|
|
}
|
|
*sleep = evt->what == nullEvent ? evtSleep : 0;
|
|
*rgn = mouseRegion;
|
|
return false;
|
|
}
|
|
|
|
void GetAndProcessEvents (WaitEventOption wait, short oldx, short oldy)
|
|
{
|
|
EventRecord evt;
|
|
long dummysleep;
|
|
RgnHandle dummyregion;
|
|
UInt32 cursleep = (wait == noWait) ? 0 : evtSleep;
|
|
RgnHandle currgn;
|
|
|
|
if (wait == waitMove){
|
|
currgn = pointRegion;
|
|
SetRectRgn (pointRegion, oldx, oldy, oldx+1, oldy+1);
|
|
}else{
|
|
currgn = mouseRegion;
|
|
}
|
|
|
|
WaitNextEvent (everyEvent, &evt, cursleep, currgn);
|
|
ProcessEvent (&evt, &dummysleep, &dummyregion);
|
|
|
|
while (evt.what != nullEvent){
|
|
WaitNextEvent (everyEvent, &evt, 0, NULL);
|
|
ProcessEvent (&evt, &dummysleep, &dummyregion);
|
|
}
|
|
}
|
|
|
|
AEIdleUPP ProcessEventUPP;
|
|
|
|
OSErr InitialiseEvents (void)
|
|
{
|
|
OSErr err;
|
|
|
|
mouseRegion = NewRgn (); /* XXX out of memory ? */
|
|
pointRegion = NewRgn (); /* XXX out of memory ? */
|
|
ProcessEventUPP = NewAEIdleProc (ProcessEvent);
|
|
err = InstallAEHandlers ();
|
|
return err;
|
|
}
|