Bochs/bochs/patches/patch.macosx-carbon-ui
2002-03-09 02:39:34 +00:00

1087 lines
33 KiB
Plaintext

----------------------------------------------------------------------
Patch name: patch.macosx-carbon-ui
Author: Jeremy Parsons <brefin@mac.com>
Date: Thur Jan 16 2002
Detailed description:
A reworking of the MacOS X gui code to use Carbon Events instead
of the older style MacOS event handling scheme.
Specific changes include:
Fixed the emulator's mouse tracking when the Mac mouse is turned
off. (Previously it would crash, Low memory globals can't be
directly accessed under MacOS X)
Fixed the selection of ports so that updates to the emulator
window don't end up getting sent to the headerbar or backdrop
windows. (And draw randomly upon the screen)
Adjusted mouse tracking to not occur when the emulator window
is collapsed or Bochs isn't the foreground application.
Adjusted fullscreen mode to accept clicks in either the emulator
or background window.
Added emulator window updating in the dock when the emulator
window is collapsed.
Patch was created with:
cvs diff -u
Apply patch to what version:
cvs checked out on Sat Jan 16, 2002
Instructions:
To patch, go to main bochs directory.
Type "patch -p0 < THIS_PATCH_FILE".
----------------------------------------------------------------------
Index: gui/carbon.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/gui/carbon.cc,v
retrieving revision 1.6
diff -u -r1.6 carbon.cc
--- gui/carbon.cc 2001/12/13 18:36:29 1.6
+++ gui/carbon.cc 2002/01/17 19:58:25
@@ -57,6 +57,14 @@
#define iSnapshot 9
#define iReset 10
+const MenuCommand kCommandFloppy = FOUR_CHAR_CODE ('FLPY');
+const MenuCommand kCommandCursor = FOUR_CHAR_CODE ('CRSR');
+const MenuCommand kCommandTool = FOUR_CHAR_CODE ('TOOL');
+const MenuCommand kCommandMenuBar = FOUR_CHAR_CODE ('MENU');
+const MenuCommand kCommandFullScreen = FOUR_CHAR_CODE ('SCRN');
+const MenuCommand kCommandSnapshot = FOUR_CHAR_CODE ('SNAP');
+const MenuCommand kCommandReset = FOUR_CHAR_CODE ('RSET');
+
#define SLEEP_TIME 0 // Number of ticks to surrender the processor during a WaitNextEvent()
// Change this to 15 or higher if you don't want Bochs to hog the processor!
@@ -76,21 +84,24 @@
// GLOBALS
WindowPtr win, toolwin, fullwin, backdrop, hidden, SouixWin;
+WindowGroupRef fullwinGroup;
bx_gui_c *thisGUI;
SInt16 gOldMBarHeight;
Boolean menubarVisible = true, cursorVisible = true;
+Boolean windowUpdatesPending = true, mouseMoved = false;
RgnHandle mBarRgn, cnrRgn;
unsigned mouse_button_state = 0;
CTabHandle gCTable;
PixMapHandle gTile;
BitMap *vgafont[256];
Rect srcTextRect, srcTileRect;
-Point scrCenter = {320, 240};
+Point scrCenter = {300, 240};
Ptr KCHR;
short gheaderbar_y;
Point prevPt;
unsigned width, height, gMinTop, gMaxTop, gLeft;
GWorldPtr gOffWorld;
+ProcessSerialNumber gProcessSerNum;
// HEADERBAR STUFF
int numPixMaps = 0, toolPixMaps = 0;
@@ -110,16 +121,23 @@
void (*f)(void);
} bx_tool_pixmap[BX_MAX_PIXMAPS];
+// Carbon Event Handlers
+pascal OSStatus CEvtHandleWindowToolClick (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus CEvtHandleWindowToolUpdate (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus CEvtHandleWindowBackdropUpdate (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus CEvtHandleWindowEmulatorClick (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus CEvtHandleWindowEmulatorUpdate (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus CEvtHandleWindowEmulatorKeys (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus CEvtHandleApplicationAppleEvent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus CEvtHandleApplicationMouseMoved (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus CEvtHandleApplicationMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus CEvtHandleApplicationMenuClick (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+pascal OSStatus CEvtHandleApplicationMenus (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData);
+
// Event handlers
BX_CPP_INLINE void HandleKey(EventRecord *event, Bit32u keyState);
BX_CPP_INLINE void HandleToolClick(Point where);
-void HandleMenuChoice(long menuChoice);
-BX_CPP_INLINE void HandleClick(EventRecord *event);
-// Update routines
-void UpdateWindow(WindowRef window);
-void UpdateRgn(RgnHandle rgn);
-
// Show/hide UI elements
void HidePointer(void);
void ShowPointer(void);
@@ -127,8 +145,8 @@
void ShowTools(void);
void HideMenubar(void);
void ShowMenubar(void);
-void HideConsole(void);
-void ShowConsole(void);
+// void HideConsole(void);
+// void ShowConsole(void);
// Initialisation
void FixWindow(void);
@@ -143,15 +161,289 @@
PixMapHandle CreatePixMap(unsigned left, unsigned top, unsigned width,
unsigned height, unsigned depth, CTabHandle clut);
unsigned char reverse_bitorder(unsigned char);
-
-static OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon );
+static pascal OSErr QuitAppleEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, SInt32 refcon);
extern bx_gui_c bx_gui;
#define BX_GUI_THIS bx_gui.
#define LOG_THIS BX_GUI_THIS
+// Carbon Event Handlers
+
+pascal OSStatus CEvtHandleWindowToolClick (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ Point wheresMyMouse;
+ GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint,
+ NULL, sizeof(Point), NULL, &wheresMyMouse);
+
+ HiliteWindow(win, true);
+ HandleToolClick(wheresMyMouse);
+
+ return noErr; // Report success
+}
+
+pascal OSStatus CEvtHandleWindowToolUpdate (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ thisGUI->show_headerbar();
+
+ return noErr; // Report success
+}
+
+pascal OSStatus CEvtHandleWindowBackdropUpdate (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ Rect box;
+ Pattern qdBlackPattern;
+
+ WindowRef myWindow;
+ GetEventParameter (theEvent, kEventParamDirectObject, typeWindowRef,
+ NULL, sizeof(WindowRef), NULL, &myWindow);
+
+ GetQDGlobalsBlack(&qdBlackPattern);
+ GetWindowPortBounds(myWindow, &box);
+ FillRect(&box, &qdBlackPattern);
+
+ return noErr; // Report success
+}
+
+// Translate MouseDowns in a handled window into Bochs events
+// Main ::HANDLE_EVENTS will feed all mouse updates to Bochs
+pascal OSStatus CEvtHandleWindowEmulatorClick (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ UInt32 keyModifiers;
+ GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32,
+ NULL, sizeof(UInt32), NULL, &keyModifiers);
+
+// if (!IsWindowActive(win))
+// {
+ // SelectWindow(win);
+// }
+ if (keyModifiers & cmdKey)
+ mouse_button_state |= 0x02;
+ else
+ mouse_button_state |= 0x01;
+
+ return noErr; // Report success
+}
+
+pascal OSStatus CEvtHandleWindowEmulatorUpdate (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ Rect box;
+ Pattern qdBlackPattern;
+
+ WindowRef myWindow;
+ GetEventParameter (theEvent, kEventParamDirectObject, typeWindowRef,
+ NULL, sizeof(WindowRef), NULL, &myWindow);
+
+ GetWindowPortBounds(myWindow, &box);
+ bx_vga.redraw_area(box.left, box.top, box.right, box.bottom);
+
+ return noErr; // Report success
+}
+
+pascal OSStatus CEvtHandleWindowEmulatorKeys (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ EventRecord event;
+ int oldMods=0;
+
+ if(ConvertEventRefToEventRecord(theEvent, &event))
+ {
+ int key = event.message & charCodeMask;
+
+ switch(event.what)
+ {
+ case keyDown:
+ case autoKey:
+ oldMods = event.modifiers;
+ HandleKey(&event, BX_KEY_PRESSED);
+ break;
+
+ case keyUp:
+ event.modifiers = oldMods;
+ HandleKey(&event, BX_KEY_RELEASED);
+ break;
+ }
+ }
+ else
+ BX_PANIC(("Can't convert keyboard event"));
+
+ return noErr;
+}
+
+#if 0
+// This stuff does work... it gets called, but converting the record
+// and then calling AEProcessAppleEvent consistently results in noOutstandingHLE(err result -608)
+// And its going to take more work to get RunApplicationLoop to work...
+pascal OSStatus CEvtHandleApplicationAppleEvent (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ EventRecord eventRec;
+
+ fprintf(stderr, "# Carbon apple event handler called\n");
+ if(ConvertEventRefToEventRecord(theEvent, &eventRec))
+ {
+ fprintf(stderr, "# Calling AEProcessAppleEvent\n");
+ OSStatus result = AEProcessAppleEvent(&eventRec);
+ fprintf(stderr, "# Received AE result: %i\n", result);
+ returm result;
+ }
+ else
+ BX_PANIC(("Can't convert apple event"));
+
+ return noErr; // Report success
+}
+#endif
+
+// Only have our application deal with mouseEvents when we catch the movement
+pascal OSStatus CEvtHandleApplicationMouseMoved (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ mouseMoved = true;
+
+ return eventNotHandledErr;
+}
+
+pascal OSStatus CEvtHandleApplicationMouseUp (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ UInt32 keyModifiers;
+ GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32,
+ NULL, sizeof(UInt32), NULL, &keyModifiers);
+
+ if (keyModifiers & cmdKey)
+ mouse_button_state &= ~0x02;
+ else
+ mouse_button_state &= ~0x01;
+
+ return eventNotHandledErr; // Don't want to eat all the mouseups
+}
+
+// Catch MouseDown's in the menubar, trigger menu browsing
+pascal OSStatus CEvtHandleApplicationMenuClick (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ short part;
+ WindowPtr whichWindow;
+
+ Point wheresMyMouse;
+ GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint,
+ NULL, sizeof(Point), NULL, &wheresMyMouse);
+
+ part = FindWindow(wheresMyMouse, &whichWindow);
+
+ if(part == inMenuBar)
+ {
+ // MenuSelect will actually trigger an event cascade,
+ // Triggering command events for any selected menu item
+ MenuSelect(wheresMyMouse);
+ return noErr;
+ }
+
+ return eventNotHandledErr; // Don't want to eat all the clicks
+}
+
+pascal OSStatus CEvtHandleApplicationMenus (EventHandlerCallRef nextHandler,
+ EventRef theEvent,
+ void* userData)
+{
+ HICommand commandStruct;
+
+ OSErr err = noErr;
+ short i;
+ DialogPtr theDlog;
+
+ GetEventParameter (theEvent, kEventParamDirectObject,
+ typeHICommand, NULL, sizeof(HICommand),
+ NULL, &commandStruct);
+
+ switch(commandStruct.commandID)
+ {
+ case kHICommandAbout:
+ theDlog = GetNewDialog(128, NULL, (WindowPtr)-1);
+ ModalDialog(NULL, &i);
+ DisposeDialog(theDlog);
+ break;
+
+ case kHICommandQuit:
+ BX_PANIC(("User terminated"));
+ break;
+
+ case kCommandFloppy:
+ //DiskEject(1);
+ break;
+
+ case kCommandCursor:
+ if (cursorVisible)
+ HidePointer();
+ else
+ ShowPointer();
+ break;
+
+ case kCommandTool:
+ if (IsWindowVisible(toolwin))
+ HideTools();
+ else
+ ShowTools();
+ break;
+
+ case kCommandMenuBar:
+ if (menubarVisible)
+ HideMenubar();
+ else
+ ShowMenubar();
+ break;
+
+ case kCommandFullScreen:
+ if (IsWindowVisible(toolwin) || menubarVisible)
+ {
+ if (menubarVisible)
+ HideMenubar();
+ if (IsWindowVisible(toolwin))
+ HideTools();
+ }
+ else
+ {
+ if (!menubarVisible)
+ ShowMenubar();
+ if (!IsWindowVisible(toolwin))
+ ShowTools();
+ }
+ break;
+
+/*
+ // Codewarrior programatic console that isn't available under Carbon without Codewarrior
+ case iConsole:
+ if (IsWindowVisible(SouixWin))
+ HideConsole();
+ else
+ ShowConsole();
+ break;
+*/
+ case kCommandSnapshot:
+ //the following will break if snapshot is not last bitmap button instantiated
+ bx_tool_pixmap[toolPixMaps-1].f();
+ break;
+ }
+
+ return noErr; // Report success
+}
+
//this routine moves the initial window position so that it is entirely onscreen
//it is needed for os 8.x with appearance managaer
void FixWindow(void)
@@ -200,13 +492,21 @@
// gQuitFlag = false;
InitCursor();
+
+#if 0
+ // Our handler gets called... but I can't AEProcesAppleEvent successfully upon it?
+ EventTypeSpec appleEvent = { kEventClassAppleEvent, kEventAppleEvent };
+ InstallApplicationEventHandler(NewEventHandlerUPP(CEvtHandleApplicationAppleEvent),
+ 1, &appleEvent, 0, NULL);
+#endif
- err = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP((AEEventHandlerProcPtr)QuitAppleEventHandler), 0, false );
+ err = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication,
+ NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false);
if (err != noErr)
ExitToShell();
}
-static OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon )
+static pascal OSErr QuitAppleEventHandler(const AppleEvent *appleEvt, AppleEvent* reply, SInt32 refcon)
{
//gQuitFlag = true;
BX_PANIC(("User terminated"));
@@ -265,6 +565,23 @@
}
else
BX_PANIC(("can't create menu"));
+
+ SetMenuItemCommandID (GetMenuRef(mApple), iAbout, kHICommandAbout);
+ SetMenuItemCommandID (GetMenuRef(mFile), iQuit, kHICommandQuit);
+ SetMenuItemCommandID (GetMenuRef(mBochs), iFloppy, kCommandFloppy);
+ SetMenuItemCommandID (GetMenuRef(mBochs), iCursor, kCommandCursor);
+ SetMenuItemCommandID (GetMenuRef(mBochs), iTool, kCommandTool);
+ SetMenuItemCommandID (GetMenuRef(mBochs), iMenuBar, kCommandMenuBar);
+ SetMenuItemCommandID (GetMenuRef(mBochs), iFullScreen, kCommandFullScreen);
+ SetMenuItemCommandID (GetMenuRef(mBochs), iSnapshot, kCommandSnapshot);
+ SetMenuItemCommandID (GetMenuRef(mBochs), iReset, kCommandReset);
+
+ EventTypeSpec commandEvents = {kEventClassCommand, kEventCommandProcess};
+ EventTypeSpec menuEvents = {kEventClassMouse, kEventMouseDown};
+ InstallApplicationEventHandler(NewEventHandlerUPP(CEvtHandleApplicationMenus),
+ 1, &commandEvents, 0, NULL);
+ InstallApplicationEventHandler(NewEventHandlerUPP(CEvtHandleApplicationMenuClick),
+ 1, &menuEvents, 0, NULL);
}
void CreateWindows(void)
@@ -273,9 +590,21 @@
Rect winRect;
Rect screenBitsBounds;
+ EventTypeSpec eventClick = { kEventClassWindow, kEventWindowHandleContentClick };
+ EventTypeSpec eventUpdate = { kEventClassWindow, kEventWindowDrawContent };
+ EventTypeSpec keyboardEvents[3] = {
+ { kEventClassKeyboard, kEventRawKeyDown }, { kEventClassKeyboard, kEventRawKeyRepeat },
+ { kEventClassKeyboard, kEventRawKeyUp }};
+
+ // Create a backdrop window for fullscreen mode
GetRegionBounds(GetGrayRgn(), &screenBitsBounds);
SetRect(&winRect, 0, 0, screenBitsBounds.right, screenBitsBounds.bottom + GetMBarHeight());
- backdrop = NewWindow(NULL, &winRect, "\p", false, plainDBox, (WindowPtr)-1, false, 0);
+ CreateNewWindow(kDocumentWindowClass, (kWindowStandardHandlerAttribute ), &winRect, &backdrop);
+ if (backdrop == NULL)
+ {BX_PANIC(("mac: can't create backdrop window"));}
+ InstallWindowEventHandler(backdrop, NewEventHandlerUPP(CEvtHandleWindowBackdropUpdate), 1, &eventUpdate, NULL, NULL);
+ InstallWindowEventHandler(backdrop, NewEventHandlerUPP(CEvtHandleWindowEmulatorClick), 1, &eventClick, NULL, NULL);
+ InstallWindowEventHandler(backdrop, NewEventHandlerUPP(CEvtHandleWindowEmulatorKeys), 3, keyboardEvents, 0, NULL);
width = 640;
height = 480;
@@ -288,26 +617,58 @@
t = (screenBitsBounds.bottom - height)/2;
b = t + height;
+ // Create a moveable tool window for the "headerbar"
SetRect(&winRect, 0, 20, screenBitsBounds.right , 22+gheaderbar_y); //qd.screenBits.bounds.right, 22+gheaderbar_y);
- toolwin = NewCWindow(NULL, &winRect, "\pMacBochs 586", true, floatProc,
- (WindowPtr)-1, false, 0);
+ CreateNewWindow(kFloatingWindowClass, kWindowStandardHandlerAttribute ,&winRect, &toolwin);
if (toolwin == NULL)
{BX_PANIC(("mac: can't create tool window"));}
- // Create a moveable tool window for the "headerbar"
-
+
+ SetWindowTitleWithCFString (toolwin, CFSTR("MacBochs 586")); // Set title
+ InstallWindowEventHandler(toolwin, NewEventHandlerUPP(CEvtHandleWindowToolClick), 1, &eventClick, NULL, NULL);
+ InstallWindowEventHandler(toolwin, NewEventHandlerUPP(CEvtHandleWindowToolUpdate), 1, &eventUpdate, NULL, NULL);
+
+ // Create the emulator window for full screen mode
SetRect(&winRect, l, t, r, b);
- fullwin = NewCWindow(NULL, &winRect, "\p", false, plainDBox, (WindowPtr)-1, false, 1);
-
+ CreateNewWindow(kPlainWindowClass, (kWindowStandardHandlerAttribute), &winRect, &fullwin);
+ if (fullwin == NULL)
+ BX_PANIC(("mac: can't create fullscreen emulator window"));
+
+ InstallWindowEventHandler(fullwin, NewEventHandlerUPP(CEvtHandleWindowEmulatorUpdate), 1, &eventUpdate, NULL, NULL);
+ InstallWindowEventHandler(fullwin, NewEventHandlerUPP(CEvtHandleWindowEmulatorClick), 1, &eventClick, NULL, NULL); InstallWindowEventHandler(fullwin, NewEventHandlerUPP(CEvtHandleWindowEmulatorKeys), 3, keyboardEvents, 0, NULL);
+
+ // Create the regular emulator window
SetRect(&winRect, gLeft, gMaxTop, gLeft+width, gMaxTop+height);
- win = NewCWindow(NULL, &winRect, "\pMacBochs 586", true, documentProc,
- (WindowPtr)-1, true, 1);
+ CreateNewWindow(kDocumentWindowClass,
+ (kWindowStandardHandlerAttribute | kWindowCollapseBoxAttribute),
+ &winRect, &win);
if (win == NULL)
BX_PANIC(("mac: can't create emulator window"));
+ SetWindowTitleWithCFString (win, CFSTR("MacBochs 586")); // Set title
+ InstallWindowEventHandler(win, NewEventHandlerUPP(CEvtHandleWindowEmulatorUpdate), 1, &eventUpdate, NULL, NULL);
+ InstallWindowEventHandler(win, NewEventHandlerUPP(CEvtHandleWindowEmulatorClick), 1, &eventClick, NULL, NULL);
+ InstallWindowEventHandler(win, NewEventHandlerUPP(CEvtHandleWindowEmulatorKeys), 3, keyboardEvents, 0, NULL);
+
+ // Group the fullscreen and backdrop windows together, since they also share the same click
+ // event handler they will effectively act as a single window for layering and events
+
+ CreateWindowGroup((kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation), &fullwinGroup);
+ SetWindowGroupName(fullwinGroup, CFSTR("net.sourceforge.bochs.windowgroups.fullscreen"));
+
+ // This *can't* be the right way, then again groups aren't yet the right way
+ // For the life of me I couldn't find a right way of making sure my created group stayed
+ // below the layer of Floating Windows. But with the windows we have there's no current
+ // harm from making it part of the same group.
+ SetWindowGroup(toolwin, fullwinGroup);
+ SetWindowGroup(fullwin, fullwinGroup);
+ SetWindowGroup(backdrop, fullwinGroup);
+
FixWindow();
hidden = fullwin;
+ ShowWindow(toolwin);
+ ShowWindow(win);
HiliteWindow(win, true);
SetPort(GetWindowPort(win));
@@ -357,6 +718,16 @@
CreateTile();
CreateWindows();
+ EventTypeSpec mouseUpEvent = { kEventClassMouse, kEventMouseUp };
+ EventTypeSpec mouseMoved[2] = { { kEventClassMouse, kEventMouseMoved },
+ { kEventClassMouse, kEventMouseDragged } };
+ InstallApplicationEventHandler(NewEventHandlerUPP(CEvtHandleApplicationMouseUp),
+ 1, &mouseUpEvent, 0, NULL);
+ InstallApplicationEventHandler(NewEventHandlerUPP(CEvtHandleApplicationMouseMoved),
+ 2, mouseMoved, 0, NULL);
+
+ GetCurrentProcess(&gProcessSerNum);
+
GetMouse(&prevPt);
UNUSED(argc);
@@ -378,16 +749,18 @@
key = event->message & charCodeMask;
- if (event->modifiers & cmdKey)
- {
- HandleMenuChoice(MenuKey(key));
- }
+// if (event->modifiers & cmdKey)
+// {
+// // Like MenuSelect, MenuKey also triggers a cascade of
+// // events that results in sending a command event
+// MenuKey(key);
+// }
// else if (FrontWindow() == SouixWin)
// {
// SIOUXHandleOneEvent(event);
// }
- else
- {
+// else
+// {
if (event->modifiers & shiftKey)
bx_devices.keyboard->gen_scancode(BX_KEY_SHIFT_L | keyState);
if (event->modifiers & controlKey)
@@ -412,7 +785,7 @@
bx_devices.keyboard->gen_scancode(BX_KEY_CTRL_L | BX_KEY_RELEASED);
if (event->modifiers & optionKey)
bx_devices.keyboard->gen_scancode(BX_KEY_ALT_L | BX_KEY_RELEASED);
- }
+// }
}
// HandleToolClick()
@@ -446,210 +819,14 @@
BX_CPP_INLINE void ResetPointer(void)
{
-#if 0
- CursorDevice *theMouse;
- if (true)
- {
- theMouse = NULL;
- CrsrDevNextDevice(&theMouse);
- CrsrDevMoveTo(theMouse, (long)scrCenter.h, (long)scrCenter.v);
- }
-#endif
-
-#define MouseCur 0x082C
-#define MouseTemp 0x0828
-#define MouseNew 0x08CE
-#define MouseAttached 0x08CF
-
- *(Point *)MouseCur = scrCenter;
- *(Point *)MouseTemp = scrCenter;
- *(Ptr)MouseNew = *(Ptr)MouseAttached;
- //*(char *)CrsrNew = 0xFF;
-}
-
-// HandleClick()
-//
-// Handles mouse click events.
-
-
-void HandleMenuChoice(long menuChoice)
-{
- OSErr err = noErr;
- short item, menu, i;
- DialogPtr theDlog;
-
- item = LoWord(menuChoice);
- menu = HiWord(menuChoice);
-
- switch(menu) {
- case mApple:
- switch(item)
- {
- case iAbout:
- theDlog = GetNewDialog(128, NULL, (WindowPtr)-1);
- ModalDialog(NULL, &i);
- DisposeDialog(theDlog);
- break;
-
- default:
- break;
- }
- break;
-
- case mFile:
- switch(item)
- {
- case iQuit:
- BX_PANIC(("User terminated"));
- break;
-
- default:
- break;
- }
- break;
-
- case mBochs:
- switch(item)
- {
- case iFloppy:
- //DiskEject(1);
- break;
- case iCursor:
- if (cursorVisible)
- HidePointer();
- else
- ShowPointer();
- break;
- case iTool:
- if (IsWindowVisible(toolwin))
- HideTools();
- else
- ShowTools();
- break;
- case iMenuBar:
- if (menubarVisible)
- HideMenubar();
- else
- ShowMenubar();
- break;
- case iFullScreen:
- if (IsWindowVisible(toolwin) || menubarVisible)
- {
- if (menubarVisible)
- HideMenubar();
- if (IsWindowVisible(toolwin))
- HideTools();
- }
- else
- {
- if (!menubarVisible)
- ShowMenubar();
- if (!IsWindowVisible(toolwin))
- ShowTools();
- }
- break;
- case iConsole:
- if (IsWindowVisible(SouixWin))
- HideConsole();
- else
- ShowConsole();
- break;
- case iSnapshot:
- //the following will break if snapshot is not last bitmap button instantiated
- bx_tool_pixmap[toolPixMaps-1].f();
- break;
- }
-
- default:
- break;
-
- }
-
- HiliteMenu(0);
-}
-
-BX_CPP_INLINE void HandleClick(EventRecord *event)
-{
- short part;
- WindowPtr whichWindow;
- Rect dRect;
-
- part = FindWindow(event->where, &whichWindow);
-
- switch(part)
- {
- case inContent:
- if (whichWindow == win)
- {
- if (win != FrontWindow())
- SelectWindow(win);
- if (event->modifiers & cmdKey)
- mouse_button_state |= 0x02;
- else
- mouse_button_state |= 0x01;
- }
- else if (whichWindow == toolwin)
- {
- HiliteWindow(win, true);
- HandleToolClick(event->where);
- }
- else if (whichWindow == backdrop)
- {
- SelectWindow(win);
- }
- else if (whichWindow == SouixWin)
- {
- SelectWindow(SouixWin);
- }
- break;
-
- case inDrag:
- GetRegionBounds(GetGrayRgn(), &dRect);
- if (IsWindowVisible(toolwin))
- dRect.top = gMaxTop;
- DragWindow(whichWindow, event->where, &dRect);
- break;
-
- case inMenuBar:
- HandleMenuChoice(MenuSelect(event->where));
- break;
- }
+ // this appears to work well, especially when combined with
+ // mouse processing on the MouseMoved events
+ if(CGWarpMouseCursorPosition(CGPointMake(scrCenter.h, scrCenter.v)))
+ {
+ fprintf(stderr, "# Failed to warp cursor");
+ }
}
-void UpdateWindow(WindowPtr window)
-{
- GrafPtr oldPort;
- Rect box;
- Pattern qdBlackPattern;
-
- GetQDGlobalsBlack(&qdBlackPattern);
-
- GetPort(&oldPort);
-
- SetPort(GetWindowPort(window));
- BeginUpdate(window);
-
- if (window == win)
- {
- GetWindowPortBounds(window, &box);
- bx_vga.redraw_area(box.left, box.top, box.right, box.bottom);
- }
- else if (window == backdrop)
- {
- GetWindowPortBounds(window, &box);
- FillRect(&box, &qdBlackPattern);
- }
- else if (window == toolwin)
- {
- thisGUI->show_headerbar();
- }
- else
- {
- }
- EndUpdate(window);
- SetPort(oldPort);
-}
-
// ::HANDLE_EVENTS()
//
// Called periodically (vga_update_interval in .bochsrc) so the
@@ -671,73 +848,99 @@
{
switch(event.what)
{
+/*
+ // This event is just redundant
case nullEvent:
- break;
-
+
+ // These events are all covered by installed carbon event handlers
case mouseDown:
- HandleClick(&event);
- break;
-
case mouseUp:
- if (event.modifiers & cmdKey)
- mouse_button_state &= ~0x02;
- else
- mouse_button_state &= ~0x01;
- break;
-
case keyDown:
case autoKey:
- oldMods = event.modifiers;
- HandleKey(&event, BX_KEY_PRESSED);
- break;
-
case keyUp:
- event.modifiers = oldMods;
- HandleKey(&event, BX_KEY_RELEASED);
- break;
-
case updateEvt:
- UpdateWindow((WindowPtr)event.message);
break;
-
+*/
case diskEvt:
// floppyA_handler();
break;
case kHighLevelEvent:
+ fprintf(stderr, "# Classic apple event handler called\n");
AEProcessAppleEvent(&event);
default:
break;
}
}
-
- GetPort(&oldport);
- SetPort(GetWindowPort(win));
- GetMouse(&mousePt);
-
-
-//if mouse has moved, or button has changed state
- if ((!EqualPt(mousePt, prevPt)) || (curstate != mouse_button_state))
- {
- dx = mousePt.h - prevPt.h;
- dy = prevPt.v - mousePt.v;
-
- bx_devices.keyboard->mouse_motion(dx, dy, mouse_button_state);
-
- if (!cursorVisible)
- {
- SetPt(&scrCenter, 320, 240);
- LocalToGlobal(&scrCenter);
- ResetPointer(); //next getmouse should be 320, 240
- SetPt(&mousePt, 320, 240);
- }
- }
+ // Only update mouse if we're not in the dock
+ // and we are the frontmost app.
+ ProcessSerialNumber frontProcessSerNum;
+ Boolean isSameProcess;
+
+ GetFrontProcess(&frontProcessSerNum);
+ SameProcess(&frontProcessSerNum, &gProcessSerNum, &isSameProcess);
- prevPt = mousePt;
-
- SetPort(oldport);
+ if(isSameProcess && !IsWindowCollapsed(win))
+ {
+ GetPort(&oldport);
+ SetPort(GetWindowPort(win));
+
+ GetMouse(&mousePt);
+
+ if(menubarVisible && cursorVisible)
+ {
+ // Don't track the mouse if we're working with the main window
+ // and we're outside the window
+ if(mouseMoved &&
+ (mousePt.v < 0 || mousePt.v > height || mousePt.h < 0 || mousePt.h > width) &&
+ (prevPt.v < 0 || prevPt.v > height || prevPt.h < 0 || prevPt.h > width))
+ {
+ mouseMoved = false;
+ }
+/*
+ // Limit mouse action to window
+ // Grr, any better ways to sync host and bochs cursor?
+ if(mousePt.h < 0) { mousePt.h = 0; }
+ else if(mousePt.h > width) { mousePt.h = width; }
+ if(mousePt.v < 0) { mousePt.v = 0; }
+ else if(mousePt.v > height) { mousePt.v = height; }
+*/
+ }
+
+ //if mouse has moved, or button has changed state
+ if (mouseMoved || (curstate != mouse_button_state))
+ {
+ if(mouseMoved)
+ {
+ CGMouseDelta CGdX, CGdY;
+ CGGetLastMouseDelta( &CGdX, &CGdY );
+ dx = CGdX;
+ dy = - CGdY; // Windows has an opposing grid
+ }
+ else
+ {
+ dx = 0;
+ dy = 0;
+ }
+
+ bx_devices.keyboard->mouse_motion(dx, dy, mouse_button_state);
+
+ if (!cursorVisible && mouseMoved)
+ {
+ SetPt(&scrCenter, 300, 240);
+ LocalToGlobal(&scrCenter);
+ ResetPointer(); //next getmouse should be 300, 240
+ SetPt(&mousePt, 300, 240);
+ }
+ mouseMoved = false;
+ }
+
+ prevPt = mousePt;
+
+ SetPort(oldport);
+ }
}
@@ -750,6 +953,17 @@
{
// an opportunity to make the Window Manager happy.
// not needed on the macintosh....
+
+ // Unless you don't want to needlessly update the dock icon
+ // umpteen zillion times a second for each tile.
+ // A further note, UpdateCollapsedWindowDockTile is not
+ // recommended for animation. Setup like this my performance
+ // seems reasonable for little fuss.
+ if(windowUpdatesPending && IsWindowCollapsed(win))
+ {
+ UpdateCollapsedWindowDockTile(win);
+ }
+ windowUpdatesPending = false;
}
@@ -771,6 +985,8 @@
RGBBackColor(&white);
GetWindowPortBounds(win, &r);
FillRect (&r, &qdBlackPattern);
+
+ windowUpdatesPending = true;
}
@@ -866,6 +1082,8 @@
previ = cursori;
SetPort(oldPort);
+
+ windowUpdatesPending = true;
}
@@ -938,7 +1156,9 @@
GetGWorld(&savePort, &saveDevice);
SetGWorld(gOffWorld, NULL); */
-// SetPort(win);
+
+ // SetPort - Otherwise an update happens to the headerbar and ooomph, we're drawing weirdly on the screen
+ SetPort(GetWindowPort(win));
destRect = srcTileRect;
OffsetRect(&destRect, x0, y0);
@@ -947,6 +1167,7 @@
CopyBits( & (** ((BitMapHandle)gTile) ), WINBITMAP(win),
&srcTileRect, &destRect, srcCopy, NULL);
+ windowUpdatesPending = true;
// SetGWorld(savePort, saveDevice);
}
@@ -965,12 +1186,27 @@
{
if (x != width || y != height)
{
+#if 1
SizeWindow(win, x, y, false);
+#endif
+
+#if 0
+ // Animates the resizing, cute, but gratuitous
+ Rect box, frame;
+ GetWindowBounds(win, kWindowStructureRgn, &frame);
+ GetWindowPortBounds(win, &box);
+ frame.right = frame.right - box.right + x;
+ frame.bottom = frame.bottom - box.bottom + y;
+
+ TransitionWindow(win, kWindowSlideTransitionEffect, kWindowResizeTransitionAction, &frame);
+#endif
SizeWindow(fullwin, x, y, false);
SizeWindow(hidden, x, y, false);
width = x;
height = y;
}
+
+ windowUpdatesPending = true;
}
@@ -1134,19 +1370,6 @@
}
#endif
-// UpdateRgn()
-//
-// Updates the screen after the menubar and round corners have been hidden
-
-void UpdateRgn(RgnHandle rgn)
-{
- WindowPtr window;
-
- window = FrontWindow();
- PaintBehind(window, rgn);
- CalcVisBehind(window, rgn);
-}
-
// HidePointer()
//
// Hides the Mac mouse pointer
@@ -1156,7 +1379,7 @@
HiliteMenu(0);
HideCursor();
SetPort(GetWindowPort(win));
- SetPt(&scrCenter, 320, 240);
+ SetPt(&scrCenter, 300, 240);
LocalToGlobal(&scrCenter);
ResetPointer();
GetMouse(&prevPt);
@@ -1228,7 +1451,6 @@
HideWindow(win);
ShowWindow(backdrop);
- SelectWindow(backdrop);
hidden = win;
win = fullwin;
ShowWindow(win);