- added instructions how to update the online documentation
[bochs-mirror.git] / gui / macintosh.cc
blobe10446ff450c70d5367df41aee33ab7b990d92c9
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: macintosh.cc,v 1.29 2008/02/15 22:05:40 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2001 MandrakeSoft S.A.
6 //
7 // MandrakeSoft S.A.
8 // 43, rue d'Aboukir
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 /////////////////////////////////////////////////////////////////////////
28 // macintosh.cc -- bochs GUI file for the Macintosh
29 // written by David Batterham <drbatter@progsoc.uts.edu.au>
30 // with contributions from Tim Senecal
32 // Define BX_PLUGGABLE in files that can be compiled into plugins. For
33 // platforms that require a special tag on exported symbols, BX_PLUGGABLE
34 // is used to know when we are exporting symbols and when we are importing.
35 #define BX_PLUGGABLE
37 // BOCHS INCLUDES
38 #include <MacTypes.h>
39 #include "bochs.h"
40 #include "iodev.h"
42 // decide whether to enable this file or not
43 #if BX_WITH_MACOS
45 #include "icon_bochs.h"
46 #include "font/vga.bitmap.h"
48 // MAC OS INCLUDES
49 #undef ACCESSOR_CALLS_ARE_FUNCTIONS
50 #define ACCESSOR_CALLS_ARE_FUNCTIONS 1
51 #include <Quickdraw.h>
52 #include <QuickdrawText.h>
53 #include <QDOffscreen.h>
54 #include <Icons.h>
55 #include <ImageCompression.h>
56 #include <Palettes.h>
57 #include <Windows.h>
58 #include <Memory.h>
59 #include <Events.h>
60 #include <TextUtils.h>
61 #include <ToolUtils.h>
62 #include <Dialogs.h>
63 #include <LowMem.h>
64 #include <Disks.h>
65 #include <CursorDevices.h>
66 #include <Menus.h>
67 #include <Sound.h>
68 #include <SIOUX.h>
69 #include <Devices.h>
71 // CONSTANTS
73 #define rMBarID 128
74 #define mApple 128
75 #define iAbout 1
76 #define mFile 129
77 #define iQuit 1
78 #define mEdit 130
79 #define mBochs 131
80 #define iFloppy 1
81 #define iCursor 3
82 #define iTool 4
83 #define iMenuBar 5
84 #define iFullScreen 6
85 #define iConsole 7
86 #define iSnapshot 9
87 #define iReset 10
89 #define SLEEP_TIME 0 // Number of ticks to surrender the processor during a WaitNextEvent()
90 // Change this to 15 or higher if you don't want Bochs to hog the processor!
92 #define FONT_WIDTH 8
93 #define FONT_HEIGHT 16
95 #define WINBITMAP(w) (((GrafPtr)(w))->portBits)
97 #define ASCII_1_MASK 0x00FF0000
98 #define ASCII_2_MASK 0x000000FF
100 const RGBColor black = {0, 0, 0};
101 const RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
102 const RGBColor medGrey = {0xCCCC, 0xCCCC, 0xCCCC};
103 const RGBColor ltGrey = {0xEEEE, 0xEEEE, 0xEEEE};
105 class bx_macintosh_gui_c : public bx_gui_c {
106 public:
107 bx_macintosh_gui_c (void) {}
108 DECLARE_GUI_VIRTUAL_METHODS()
111 // declare one instance of the gui object and call macro to insert the
112 // plugin code
113 static bx_macintosh_gui_c *theGui = NULL;
114 IMPLEMENT_GUI_PLUGIN_CODE(macintosh)
116 #define LOG_THIS theGui->
118 // GLOBALS
120 WindowPtr win, toolwin, fullwin, backdrop, hidden, SouixWin;
121 SInt16 gOldMBarHeight;
122 bx_bool menubarVisible = true, cursorVisible = true;
123 RgnHandle mBarRgn, cnrRgn;
124 unsigned mouse_button_state = 0;
125 CTabHandle gCTable;
126 PixMapHandle gTile;
127 BitMap *vgafont[256];
128 Rect srcTextRect, srcTileRect;
129 Point scrCenter = {320, 240};
130 Ptr KCHR;
131 short gheaderbar_y;
132 Point prevPt;
133 unsigned width, height, gMinTop, gMaxTop, gLeft;
134 GWorldPtr gOffWorld;
135 Ptr gMyBuffer;
136 static unsigned vga_bpp=8;
137 static EventModifiers oldMods = 0;
138 static unsigned int text_rows=25, text_cols=80;
140 // HEADERBAR STUFF
141 int numPixMaps = 0, toolPixMaps = 0;
142 unsigned bx_bitmap_left_xorigin = 2; // pixels from left
143 unsigned bx_bitmap_right_xorigin = 2; // pixels from right
144 //PixMapHandle bx_pixmap[BX_MAX_PIXMAPS];
145 CIconHandle bx_cicn[BX_MAX_PIXMAPS];
147 struct {
148 CIconHandle cicn;
149 // PixMapHandle pm;
150 unsigned xdim;
151 unsigned ydim;
152 unsigned xorigin;
153 unsigned yorigin;
154 unsigned alignment;
155 void (*f)(void);
156 } bx_tool_pixmap[BX_MAX_PIXMAPS];
158 // Event handlers
159 BX_CPP_INLINE void HandleKey(EventRecord *event, Bit32u keyState);
160 BX_CPP_INLINE void HandleToolClick(Point where);
161 void HandleMenuChoice(long menuChoice);
162 BX_CPP_INLINE void HandleClick(EventRecord *event);
164 // Update routines
165 void UpdateWindow(WindowPtr window);
166 void UpdateRgn(RgnHandle rgn);
168 // Show/hide UI elements
169 void HidePointer(void);
170 void ShowPointer(void);
171 void HideTools(void);
172 void ShowTools(void);
173 void HideMenubar(void);
174 void ShowMenubar(void);
175 void HideConsole(void);
176 void ShowConsole(void);
178 // Initialisation
179 void FixWindow(void);
180 void MacPanic(void);
181 void InitToolbox(void);
182 void CreateTile(void);
183 void CreateMenus(void);
184 void CreateWindows(void);
185 void CreateKeyMap(void);
186 void CreateVGAFont(void);
187 BitMap *CreateBitMap(unsigned width, unsigned height);
188 PixMapHandle CreatePixMap(unsigned left, unsigned top, unsigned width,
189 unsigned height, unsigned depth, CTabHandle clut);
190 unsigned char reverse_bitorder(unsigned char);
192 //this routine moves the initial window position so that it is entirely onscreen
193 //it is needed for os 8.x with appearance managaer
194 void FixWindow(void)
196 RgnHandle wStruct;
197 Region *wRgn;
198 CWindowRecord *thing;
199 Rect wRect;
200 RgnHandle tStruct;
201 Region *tRgn;
202 Rect tRect;
203 short MinVal;
205 thing = (CWindowRecord *)win;
206 wStruct = thing->strucRgn;
207 wRgn = (Region *)*wStruct;
208 wRect = wRgn->rgnBBox;
210 thing = (CWindowRecord *)toolwin;
211 tStruct = thing->strucRgn;
212 tRgn = (Region *)*tStruct;
213 tRect = tRgn->rgnBBox;
215 if (wRect.left < 2)
217 gLeft = gLeft + (2 - wRect.left);
220 MinVal = tRect.bottom+2;
221 //MinVal = MinVal + GetMBarHeight();
223 if (wRect.top < MinVal)
225 // gMinTop = gMinTop + (MinVal - wRect.top);
226 gMaxTop = gMaxTop + (MinVal - wRect.top);
229 MoveWindow(win, gLeft, gMaxTop, false);
232 void MacPanic(void)
234 StopAlert(200, NULL);
237 void InitToolbox(void)
239 InitGraf(&qd.thePort);
240 InitWindows();
241 InitMenus();
242 InitDialogs(nil);
243 InitCursor();
244 MaxApplZone();
245 // Initialise the toolbox
248 void CreateTile(void)
250 GDHandle saveDevice;
251 CGrafPtr savePort;
252 OSErr err;
253 unsigned long p_f;
254 long theRowBytes = ((((long) (vga_bpp==24?32:(((vga_bpp+1)>>1)<<1)) * ((long) (srcTileRect.right-srcTileRect.left)) + 31) >> 5) << 2);
256 //if (SIM->get_param_bool(BXPN_PRIVATE_COLORMAP)->get())
259 GetGWorld(&savePort, &saveDevice);
260 switch(vga_bpp)
262 case 1:
263 p_f = k1MonochromePixelFormat;
264 break;
265 case 2:
266 p_f = k2IndexedPixelFormat;
267 break;
268 case 4:
269 p_f = k4IndexedPixelFormat;
270 break;
271 case 8:
272 p_f = k8IndexedPixelFormat;
273 break;
274 case 15:
275 p_f = k16LE555PixelFormat;
276 break;
277 case 16:
278 p_f = k16LE565PixelFormat;
279 break;
280 case 24:
281 //p_f = k24BGRPixelFormat;
282 //break;
283 case 32:
284 p_f = k32ARGBPixelFormat;//k32BGRAPixelFormat;
285 break;
288 BX_ASSERT((gMyBuffer = (Ptr)malloc(theRowBytes * (srcTileRect.bottom - srcTileRect.top))) != NULL);
289 err = QTNewGWorldFromPtr(&gOffWorld, p_f,
290 &srcTileRect, vga_bpp>8 ? NULL : gCTable, NULL, keepLocal, gMyBuffer, theRowBytes);
291 if (err != noErr || gOffWorld == NULL)
292 BX_PANIC(("mac: can't create gOffWorld; err=%hd", err));
294 SetGWorld(gOffWorld, NULL);
295 RGBForeColor(&black);
296 RGBBackColor(&white);
298 gTile = GetGWorldPixMap(gOffWorld);
300 if (gTile != NULL)
302 NoPurgePixels(gTile);
303 if (!LockPixels(gTile))
304 BX_ERROR(("mac: can't LockPixels gTile"));
305 if ((**gTile).pixelType != RGBDirect && (**gTile).pmTable != gCTable)
307 DisposeCTable(gCTable);
308 gCTable = (**gTile).pmTable;
311 (**gCTable).ctFlags |= 0x4000; //use palette manager indexes
312 CTabChanged(gCTable);
314 else
315 BX_PANIC(("mac: can't create gTile"));
317 SetGWorld(savePort, saveDevice);
320 else
322 gOffWorld = NULL;
323 gTile = CreatePixMap(0, 0, srcTileRect.right, srcTileRect.bottom, 8, gCTable);
324 if (gTile == NULL)
325 BX_PANIC(("mac: can't create gTile"));
329 void CreateMenus(void)
331 Handle menu;
333 menu = GetNewMBar(rMBarID); // get our menus from resource
334 if (menu != nil)
336 SetMenuBar(menu);
337 DisposeHandle(menu);
338 AppendResMenu(GetMenuHandle(mApple), 'DRVR'); // add apple menu items
339 DrawMenuBar();
341 else
342 BX_PANIC(("can't create menu"));
345 void CreateWindows(void)
347 int l, t, r, b;
348 Rect winRect;
350 SetRect(&winRect, 0, 0, qd.screenBits.bounds.right, qd.screenBits.bounds.bottom);
351 backdrop = NewWindow(NULL, &winRect, "\p", false, plainDBox, (WindowPtr)-1, false, 0);
353 width = 640;
354 height = 480;
355 gLeft = 4;
356 gMinTop = 44;
357 gMaxTop = 44 + gheaderbar_y;
359 l = (qd.screenBits.bounds.right - width)/2;
360 r = l + width;
361 t = (qd.screenBits.bounds.bottom - height)/2;
362 b = t + height;
364 SetRect(&winRect, 0, 20, qd.screenBits.bounds.right, 22+gheaderbar_y);
365 toolwin = NewCWindow(NULL, &winRect, "\pMacBochs 586", true, floatProc,
366 (WindowPtr)-1, false, 0);
367 if (toolwin == NULL)
368 BX_PANIC(("mac: can't create tool window"));
369 // Create a moveable tool window for the "headerbar"
371 SetRect(&winRect, l, t, r, b);
372 fullwin = NewCWindow(NULL, &winRect, "\p", false, plainDBox, (WindowPtr)-1, false, 1);
374 SetRect(&winRect, gLeft, gMaxTop, gLeft+width, gMaxTop+height);
375 win = NewCWindow(NULL, &winRect, "\pMacBochs 586", true, documentProc,
376 (WindowPtr)-1, true, 1);
377 if (win == NULL)
378 BX_PANIC(("mac: can't create emulator window"));
380 FixWindow();
382 hidden = fullwin;
384 HiliteWindow(win, true);
386 SetPort(win);
389 // ::SPECIFIC_INIT()
391 // Called from gui.cc, once upon program startup, to allow for the
392 // specific GUI code (X11, BeOS, ...) to be initialized.
394 // argc, argv: not used right now, but the intention is to pass native GUI
395 // specific options from the command line. (X11 options, BeOS options,...)
397 // tilewidth, tileheight: for optimization, graphics_tile_update() passes
398 // only updated regions of the screen to the gui code to be redrawn.
399 // These define the dimensions of a region (tile).
400 // headerbar_y: A headerbar (toolbar) is display on the top of the
401 // VGA window, showing floppy status, and other information. It
402 // always assumes the width of the current VGA mode width, but
403 // it's height is defined by this parameter.
405 void bx_macintosh_gui_c::specific_init(int argc, char **argv, unsigned tilewidth, unsigned tileheight, unsigned headerbar_y)
407 put("MGUI");
408 InitToolbox();
410 //SouixWin = FrontWindow();
412 atexit(MacPanic);
414 gheaderbar_y = headerbar_y;
416 CreateKeyMap();
418 gCTable = GetCTable(128);
419 BX_ASSERT (gCTable != NULL);
420 CTabChanged(gCTable); //(*gCTable)->ctSeed = GetCTSeed();
421 SetRect(&srcTextRect, 0, 0, FONT_WIDTH, FONT_HEIGHT);
422 SetRect(&srcTileRect, 0, 0, tilewidth, tileheight);
424 CreateMenus();
425 CreateVGAFont();
426 CreateTile();
427 CreateWindows();
429 GetMouse(&prevPt);
430 SetEventMask(everyEvent);
432 SIOUXSettings.setupmenus = false;
433 SIOUXSettings.autocloseonquit = true;
434 SIOUXSettings.asktosaveonclose = false;
435 SIOUXSettings.standalone = false;
437 UNUSED(argc);
438 UNUSED(argv);
440 //HideWindow(SouixWin);
443 // HandleKey()
445 // Handles keyboard-related events.
447 BX_CPP_INLINE void HandleKey(EventRecord *event, Bit32u keyState)
449 UInt32 key;
450 UInt32 trans;
451 static UInt32 transState = 0;
453 key = event->message & charCodeMask;
455 if (event->modifiers & cmdKey)
457 HandleMenuChoice(MenuKey(key));
459 //else if (FrontWindow() == SouixWin)
461 // SIOUXHandleOneEvent(event);
463 else
465 /* if (event->modifiers & shiftKey)
466 DEV_kbd_gen_scancode(BX_KEY_SHIFT_L | keyState);
467 if (event->modifiers & controlKey)
468 DEV_kbd_gen_scancode(BX_KEY_CTRL_L | keyState);
469 if (event->modifiers & optionKey)
470 DEV_kbd_gen_scancode(BX_KEY_ALT_L | keyState);*/
472 key = (event->message & keyCodeMask) >> 8;
474 trans = KeyTranslate(KCHR, key, &transState);
475 if ((trans == BX_KEY_PRINT) && ((oldMods & optionKey) || (oldMods & rightOptionKey)))
476 trans = BX_KEY_ALT_SYSREQ;
477 if ((trans == BX_KEY_PAUSE) && ((oldMods & controlKey) || (oldMods & rightControlKey)))
478 trans = BX_KEY_CTRL_BREAK;
480 // KeyTranslate maps Mac virtual key codes to any type of character code
481 // you like (in this case, Bochs key codes). Much nicer than a huge switch
482 // statement!
484 if (trans > 0)
485 DEV_kbd_gen_scancode(trans | keyState);
487 /* if (event->modifiers & shiftKey)
488 DEV_kbd_gen_scancode(BX_KEY_SHIFT_L | BX_KEY_RELEASED);
489 if (event->modifiers & controlKey)
490 DEV_kbd_gen_scancode(BX_KEY_CTRL_L | BX_KEY_RELEASED);
491 if (event->modifiers & optionKey)
492 DEV_kbd_gen_scancode(BX_KEY_ALT_L | BX_KEY_RELEASED);*/
496 // HandleToolClick()
498 // Handles mouse clicks in the Bochs tool window
500 BX_CPP_INLINE void HandleToolClick(Point where)
502 unsigned i;
503 int xorigin;
504 Rect bounds;
506 SetPort(toolwin);
507 GlobalToLocal(&where);
508 for (i=0; i<toolPixMaps; i++)
510 if (bx_tool_pixmap[i].alignment == BX_GRAVITY_LEFT)
511 xorigin = bx_tool_pixmap[i].xorigin;
512 else
513 xorigin = toolwin->portRect.right - bx_tool_pixmap[i].xorigin;
514 SetRect(&bounds, xorigin, 0, xorigin+32, 32);
515 if (PtInRect(where, &bounds))
516 bx_tool_pixmap[i].f();
518 theGui->show_headerbar();
521 BX_CPP_INLINE void ResetPointer(void)
523 #if 0
524 CursorDevice *theMouse;
525 if (true)
527 theMouse = NULL;
528 CrsrDevNextDevice(&theMouse);
529 CrsrDevMoveTo(theMouse, (long)scrCenter.h, (long)scrCenter.v);
531 #endif
533 #define MouseCur 0x082C
534 #define MouseTemp 0x0828
535 #define MouseNew 0x08CE
536 #define MouseAttached 0x08CF
538 *(Point *)MouseCur = scrCenter;
539 *(Point *)MouseTemp = scrCenter;
540 *(Ptr)MouseNew = *(Ptr)MouseAttached;
541 //*(char *)CrsrNew = 0xFF;
544 // HandleClick()
546 // Handles mouse click events.
549 void HandleMenuChoice(long menuChoice)
551 OSErr err = noErr;
552 short item, menu, i;
553 short daRefNum;
554 Rect bounds;
555 Str255 daName;
556 WindowRef newWindow;
557 DialogPtr theDlog;
559 item = LoWord(menuChoice);
560 menu = HiWord(menuChoice);
562 switch(menu) {
563 case mApple:
564 switch(item) {
565 case iAbout:
566 theDlog = GetNewDialog(128, NULL, (WindowPtr)-1);
567 ModalDialog(NULL, &i);
568 DisposeDialog(theDlog);
569 break;
571 default:
572 GetMenuItemText(GetMenuHandle(mApple), item, daName);
573 daRefNum = OpenDeskAcc(daName);
574 break;
576 break;
578 case mFile:
579 switch(item) {
580 case iQuit:
581 BX_PANIC(("User terminated"));
582 break;
584 default:
585 break;
587 break;
589 case mBochs:
590 switch(item) {
591 case iFloppy:
592 DiskEject(1);
593 break;
595 case iCursor:
596 if (cursorVisible)
597 HidePointer();
598 else
599 ShowPointer();
600 break;
602 case iTool:
603 if (IsWindowVisible(toolwin))
604 HideTools();
605 else
606 ShowTools();
607 break;
609 case iMenuBar:
610 if (menubarVisible)
611 HideMenubar();
612 else
613 ShowMenubar();
614 break;
616 case iFullScreen:
617 if (cursorVisible || IsWindowVisible(toolwin) || menubarVisible)
619 if (cursorVisible)
620 HidePointer();
621 if (menubarVisible)
622 HideMenubar();
623 if (IsWindowVisible(toolwin))
624 HideTools();
626 else
628 if (!cursorVisible)
629 ShowPointer();
630 if (!menubarVisible)
631 ShowMenubar();
632 if (!IsWindowVisible(toolwin))
633 ShowTools();
635 break;
637 case iConsole:
638 if (IsWindowVisible(SouixWin))
639 HideConsole();
640 else
641 ShowConsole();
642 break;
644 case iSnapshot:
645 // the following will break if snapshot is not last bitmap button instantiated
646 bx_tool_pixmap[toolPixMaps-1].f();
647 break;
650 default:
651 break;
654 HiliteMenu(0);
657 BX_CPP_INLINE void HandleClick(EventRecord *event)
659 short part;
660 WindowPtr whichWindow;
661 Rect dRect;
663 part = FindWindow(event->where, &whichWindow);
665 switch(part)
667 case inContent:
668 if (whichWindow == win)
670 if (win != FrontWindow())
671 SelectWindow(win);
672 if (event->modifiers & cmdKey)
673 mouse_button_state |= 0x02;
674 else
675 mouse_button_state |= 0x01;
677 else if (whichWindow == toolwin)
679 HiliteWindow(win, true);
680 HandleToolClick(event->where);
682 else if (whichWindow == backdrop)
684 SelectWindow(win);
686 else if (whichWindow == SouixWin)
688 SelectWindow(SouixWin);
690 break;
692 case inDrag:
693 dRect = qd.screenBits.bounds;
694 if (IsWindowVisible(toolwin))
695 dRect.top = gMaxTop;
696 DragWindow(whichWindow, event->where, &dRect);
697 break;
699 case inMenuBar:
700 HandleMenuChoice(MenuSelect(event->where));
701 break;
705 void UpdateWindow(WindowPtr window)
707 GrafPtr oldPort;
708 Rect box;
710 GetPort(&oldPort);
712 SetPort(window);
713 BeginUpdate(window);
715 if (window == win)
717 box = window->portRect;
718 DEV_vga_redraw_area(box.left, box.top, box.right, box.bottom);
720 else if (window == backdrop)
722 box = window->portRect;
723 FillRect(&box, &qd.black);
725 else if (window == toolwin)
727 theGui->show_headerbar();
730 EndUpdate(window);
731 SetPort(oldPort);
734 // ::HANDLE_EVENTS()
736 // Called periodically (vga_update_interval in .bochsrc) so the
737 // the gui code can poll for keyboard, mouse, and other
738 // relevant events.
740 void bx_macintosh_gui_c::handle_events(void)
742 EventRecord event;
743 Point mousePt;
744 int dx, dy;
745 int oldMods1=0;
746 EventModifiers newMods;
747 unsigned curstate;
748 GrafPtr oldport;
750 curstate = mouse_button_state; //so we can compare the old and the new mouse state
752 if (WaitNextEvent(everyEvent, &event, SLEEP_TIME, NULL))
754 switch(event.what)
756 case nullEvent:
757 break;
759 case mouseDown:
760 HandleClick(&event);
761 break;
763 case mouseUp:
764 if (event.modifiers & cmdKey)
765 mouse_button_state &= ~0x02;
766 else
767 mouse_button_state &= ~0x01;
768 break;
770 case keyDown:
771 case autoKey:
772 oldMods1 = event.modifiers;
773 HandleKey(&event, BX_KEY_PRESSED);
774 break;
776 case keyUp:
777 event.modifiers = oldMods1;
778 HandleKey(&event, BX_KEY_RELEASED);
779 break;
781 case updateEvt:
782 if ((WindowPtr)event.message == SouixWin)
783 SIOUXHandleOneEvent(&event);
784 else
785 UpdateWindow((WindowPtr)event.message);
786 break;
788 case diskEvt:
789 floppyA_handler();
791 default:
792 break;
795 else if (oldMods != (newMods = (event.modifiers & 0xfe00)))
797 if ((newMods ^ oldMods) & shiftKey)
798 DEV_kbd_gen_scancode(BX_KEY_SHIFT_L | ((newMods & shiftKey)?BX_KEY_PRESSED:BX_KEY_RELEASED));
799 if ((newMods ^ oldMods) & alphaLock)
800 DEV_kbd_gen_scancode(BX_KEY_CAPS_LOCK | ((newMods & alphaLock)?BX_KEY_PRESSED:BX_KEY_RELEASED));
801 if ((newMods ^ oldMods) & optionKey)
802 DEV_kbd_gen_scancode(BX_KEY_ALT_L | ((newMods & optionKey)?BX_KEY_PRESSED:BX_KEY_RELEASED));
803 if ((newMods ^ oldMods) & controlKey)
804 DEV_kbd_gen_scancode(BX_KEY_CTRL_L | ((newMods & controlKey)?BX_KEY_PRESSED:BX_KEY_RELEASED));
805 if ((newMods ^ oldMods) & rightShiftKey)
806 DEV_kbd_gen_scancode(BX_KEY_SHIFT_R | ((newMods & rightShiftKey)?BX_KEY_PRESSED:BX_KEY_RELEASED));
807 if ((newMods ^ oldMods) & rightOptionKey)
808 DEV_kbd_gen_scancode(BX_KEY_ALT_R | ((newMods & rightOptionKey)?BX_KEY_PRESSED:BX_KEY_RELEASED));
809 if ((newMods ^ oldMods) & rightControlKey)
810 DEV_kbd_gen_scancode(BX_KEY_CTRL_R | ((newMods & rightControlKey)?BX_KEY_PRESSED:BX_KEY_RELEASED));
811 oldMods = newMods;
814 GetPort(&oldport);
815 SetPort(win);
817 GetMouse(&mousePt);
819 //if mouse has moved, or button has changed state
820 if ((!EqualPt(mousePt, prevPt)) || (curstate != mouse_button_state))
822 dx = mousePt.h - prevPt.h;
823 dy = prevPt.v - mousePt.v;
825 DEV_mouse_motion(dx, dy, mouse_button_state);
827 if (!cursorVisible)
829 SetPt(&scrCenter, 320, 240);
830 LocalToGlobal(&scrCenter);
831 ResetPointer(); //next getmouse should be 320, 240
832 SetPt(&mousePt, 320, 240);
836 prevPt = mousePt;
838 SetPort(oldport);
841 // ::FLUSH()
843 // Called periodically, requesting that the gui code flush all pending
844 // screen update requests.
846 void bx_macintosh_gui_c::flush(void)
848 // an opportunity to make the Window Manager happy.
849 // not needed on the macintosh....
852 // ::CLEAR_SCREEN()
854 // Called to request that the VGA region is cleared. Don't
855 // clear the area that defines the headerbar.
857 void bx_macintosh_gui_c::clear_screen(void)
859 SetPort(win);
861 RGBForeColor(&black);
862 RGBBackColor(&white);
864 FillRect(&win->portRect, &qd.black);
867 // ::TEXT_UPDATE()
869 // Called in a VGA text mode, to update the screen with
870 // new content.
872 // old_text: array of character/attributes making up the contents
873 // of the screen from the last call. See below
874 // new_text: array of character/attributes making up the current
875 // contents, which should now be displayed. See below
877 // format of old_text & new_text: each is tm_info.line_offset*text_rows
878 // bytes long. Each character consists of 2 bytes. The first by is
879 // the character value, the second is the attribute byte.
881 // cursor_x: new x location of cursor
882 // cursor_y: new y location of cursor
883 // tm_info: this structure contains information for additional
884 // features in text mode (cursor shape, line offset,...)
886 void bx_macintosh_gui_c::text_update(Bit8u *old_text, Bit8u *new_text,
887 unsigned long cursor_x, unsigned long cursor_y,
888 bx_vga_tminfo_t tm_info)
890 int i;
891 unsigned char achar;
892 int x, y;
893 static int previ;
894 int cursori;
895 Rect destRect;
896 RGBColor fgColor, bgColor;
897 GrafPtr oldPort;
898 unsigned nchars;
899 OSErr theError;
901 GetPort(&oldPort);
903 SetPort(win);
905 //current cursor position
906 cursori = (cursor_y * text_cols + cursor_x) * 2;
908 // Number of characters on screen, variable number of rows
909 nchars = text_cols * text_rows;
911 for (i=0; i<nchars*2; i+=2)
913 if (i == cursori || i == previ || new_text[i] != old_text[i] || new_text[i+1] != old_text[i+1])
915 achar = new_text[i];
917 // fgColor = (**gCTable).ctTable[new_text[i+1] & 0x0F].rgb;
918 // bgColor = (**gCTable).ctTable[(new_text[i+1] & 0xF0) >> 4].rgb;
920 // RGBForeColor(&fgColor);
921 // RGBBackColor(&bgColor);
923 if (SIM->get_param_bool(BXPN_PRIVATE_COLORMAP)->get())
925 PmForeColor(new_text[i+1] & 0x0F);
926 PmBackColor((new_text[i+1] & 0xF0) >> 4);
928 else
930 fgColor = (**gCTable).ctTable[new_text[i+1] & 0x0F].rgb;
931 bgColor = (**gCTable).ctTable[(new_text[i+1] & 0xF0) >> 4].rgb;
933 RGBForeColor(&fgColor);
934 RGBBackColor(&bgColor);
937 x = ((i/2) % text_cols)*FONT_WIDTH;
938 y = ((i/2) / text_cols)*FONT_HEIGHT;
940 SetRect(&destRect, x, y, x+FONT_WIDTH, y+FONT_HEIGHT);
942 CopyBits(vgafont[achar], &WINBITMAP(win),
943 &srcTextRect, &destRect, srcCopy, NULL);
944 if ((theError = QDError()) != noErr)
945 BX_ERROR(("mac: CopyBits returned %hd", theError));
947 if (i == cursori) //invert the current cursor block
949 InvertRect(&destRect);
954 //previous cursor position
955 previ = cursori;
957 SetPort(oldPort);
960 int bx_macintosh_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)
962 return 0;
965 int bx_macintosh_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len)
967 return 0;
970 // ::PALETTE_CHANGE()
972 // Allocate a color in the native GUI, for this color, and put
973 // it in the colormap location 'index'.
974 // returns: 0=no screen update needed (color map change has direct effect)
975 // 1=screen updated needed (redraw using current colormap)
977 bx_bool bx_macintosh_gui_c::palette_change(unsigned index, unsigned red, unsigned green, unsigned blue)
979 PaletteHandle thePal, oldpal;
980 GDHandle saveDevice;
981 CGrafPtr savePort;
982 GrafPtr oldPort;
984 /*if (gOffWorld != NULL) //(SIM->get_param_bool(BXPN_PRIVATE_COLORMAP)->get())
986 GetGWorld(&savePort, &saveDevice);
988 SetGWorld(gOffWorld, NULL);
991 if ((**gTile).pixelType != RGBDirect)
993 GetPort(&oldPort);
994 SetPort(win);
996 (**gCTable).ctTable[index].value = index;
997 (**gCTable).ctTable[index].rgb.red = (red << 8);
998 (**gCTable).ctTable[index].rgb.green = (green << 8);
999 (**gCTable).ctTable[index].rgb.blue = (blue << 8);
1001 SetEntries(index, index, (**gCTable).ctTable);
1003 CTabChanged(gCTable);
1005 SetPort(oldPort);
1008 /*if (gOffWorld != NULL) //(SIM->get_param_bool(BXPN_PRIVATE_COLORMAP)->get())
1009 SetGWorld(savePort, saveDevice);*/
1011 if (SIM->get_param_bool(BXPN_PRIVATE_COLORMAP)->get())
1013 thePal = NewPalette(index, gCTable, pmTolerant, 0x5000);
1014 oldpal = GetPalette(win);
1016 SetPalette(win, thePal, false);
1017 SetPalette(fullwin, thePal, false);
1018 SetPalette(hidden, thePal, false);
1020 return(1);
1023 return((**gTile).pixelType != RGBDirect);
1026 // ::GRAPHICS_TILE_UPDATE()
1028 // Called to request that a tile of graphics be drawn to the
1029 // screen, since info in this region has changed.
1031 // tile: array of 8bit values representing a block of pixels with
1032 // dimension equal to the 'tilewidth' & 'tileheight' parameters to
1033 // ::specific_init(). Each value specifies an index into the
1034 // array of colors you allocated for ::palette_change()
1035 // x0: x origin of tile
1036 // y0: y origin of tile
1038 // note: origin of tile and of window based on (0,0) being in the upper
1039 // left of the window.
1041 void bx_macintosh_gui_c::graphics_tile_update(Bit8u *tile, unsigned x0, unsigned y0)
1043 Rect destRect;
1044 OSErr theError;
1045 Ptr theBaseAddr;
1046 GrafPtr oldPort;
1047 /*GDHandle saveDevice;
1048 CGrafPtr savePort;
1050 GetGWorld(&savePort, &saveDevice);
1052 SetGWorld(gOffWorld, NULL); */
1053 GetPort(&oldPort);
1054 SetPort(win);
1055 destRect = srcTileRect;
1056 OffsetRect(&destRect, x0, y0);
1058 //(**gTile).baseAddr = (Ptr)tile;
1059 if ((theBaseAddr = GetPixBaseAddr(gTile)) == NULL)
1060 BX_PANIC(("mac: gTile has NULL baseAddr (offscreen buffer purged)"));
1061 else if (vga_bpp == 24 || vga_bpp == 32)
1063 for (unsigned iY = 0; iY < (srcTileRect.bottom-srcTileRect.top); iY++)
1065 Bit8u *iA = ((Bit8u *)theBaseAddr) + iY * GetPixRowBytes(gTile);
1066 for (unsigned iX = 0; iX < (srcTileRect.right-srcTileRect.left); iX++)
1068 iA[iX*4 + 3] = tile[((srcTileRect.right-srcTileRect.left)*iY+iX)*(vga_bpp>>3)];
1069 iA[iX*4 + 2] = tile[((srcTileRect.right-srcTileRect.left)*iY+iX)*(vga_bpp>>3) + 1];
1070 iA[iX*4 + 1] = tile[((srcTileRect.right-srcTileRect.left)*iY+iX)*(vga_bpp>>3) + 2];
1071 iA[iX*4] = vga_bpp == 24 ? 0 : tile[((srcTileRect.right-srcTileRect.left)*iY+iX)*4 + 3];
1075 else
1076 BlockMoveData(tile, theBaseAddr, (srcTileRect.bottom-srcTileRect.top) * GetPixRowBytes(gTile));
1077 RGBForeColor(&black);
1078 RGBBackColor(&white);
1079 CopyBits(GetPortBitMapForCopyBits(gOffWorld), &WINBITMAP(win),
1080 &srcTileRect, &destRect, srcCopy, NULL);
1081 if ((theError = QDError()) != noErr)
1082 BX_ERROR(("mac: CopyBits returned %hd", theError));
1083 SetPort(oldPort);
1085 //SetGWorld(savePort, saveDevice);
1088 // ::DIMENSION_UPDATE()
1090 // Called when the VGA mode changes it's X,Y dimensions.
1091 // Resize the window to this size, but you need to add on
1092 // the height of the headerbar to the Y value.
1094 // x: new VGA x size
1095 // y: new VGA y size (add headerbar_y parameter from ::specific_init().
1096 // fheight: new VGA character height in text mode
1097 // fwidth : new VGA character width in text mode
1098 // bpp : bits per pixel in graphics mode
1100 void bx_macintosh_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight, unsigned fwidth, unsigned bpp)
1102 if ((bpp != 1) && (bpp != 2) && (bpp != 4) && (bpp != 8) && (bpp != 15) && (bpp != 16) && (bpp != 24) && (bpp != 32)) {
1103 BX_PANIC(("%d bpp graphics mode not supported yet", bpp));
1105 if (bpp != vga_bpp)
1107 free(gMyBuffer);
1108 if ((**gTile).pixelType == RGBDirect)
1109 gCTable = GetCTable(128);
1110 DisposeGWorld(gOffWorld);
1111 vga_bpp = bpp;
1112 CreateTile();
1114 if (fheight > 0) {
1115 text_cols = x / fwidth;
1116 text_rows = y / fheight;
1117 if (fwidth != 8) {
1118 x = x * 8 / fwidth;
1120 if (fheight != 16) {
1121 y = y * 16 / fheight;
1125 if (x != width || y != height)
1127 SizeWindow(win, x, y, false);
1128 SizeWindow(fullwin, x, y, false);
1129 SizeWindow(hidden, x, y, false);
1130 width = x;
1131 height = y;
1134 host_xres = x;
1135 host_yres = y;
1136 host_bpp = bpp;
1139 // ::CREATE_BITMAP()
1141 // Create a monochrome bitmap of size 'xdim' by 'ydim', which will
1142 // be drawn in the headerbar. Return an integer ID to the bitmap,
1143 // with which the bitmap can be referenced later.
1145 // bmap: packed 8 pixels-per-byte bitmap. The pixel order is:
1146 // bit0 is the left most pixel, bit7 is the right most pixel.
1147 // xdim: x dimension of bitmap
1148 // ydim: y dimension of bitmap
1150 // rewritten by tim senecal to use the cicn (color icon) resources instead
1152 unsigned bx_macintosh_gui_c::create_bitmap(const unsigned char *bmap, unsigned xdim, unsigned ydim)
1154 unsigned i;
1155 unsigned char *data;
1156 long row_bytes, bytecount;
1158 bx_cicn[numPixMaps] = GetCIcon(numPixMaps+128);
1159 BX_ASSERT(bx_cicn[numPixMaps]);
1161 numPixMaps++;
1163 return(numPixMaps-1);
1166 // ::HEADERBAR_BITMAP()
1168 // Called to install a bitmap in the bochs headerbar (toolbar).
1170 // bmap_id: will correspond to an ID returned from
1171 // ::create_bitmap(). 'alignment' is either BX_GRAVITY_LEFT
1172 // or BX_GRAVITY_RIGHT, meaning install the bitmap in the next
1173 // available leftmost or rightmost space.
1174 // f: a 'C' function pointer to callback when the mouse is clicked in
1175 // the boundaries of this bitmap.
1177 unsigned bx_macintosh_gui_c::headerbar_bitmap(unsigned bmap_id, unsigned alignment, void (*f)(void))
1179 unsigned hb_index;
1181 toolPixMaps++;
1182 hb_index = toolPixMaps-1;
1183 //bx_tool_pixmap[hb_index].pm = bx_pixmap[bmap_id];
1184 bx_tool_pixmap[hb_index].cicn = bx_cicn[bmap_id];
1185 bx_tool_pixmap[hb_index].alignment = alignment;
1186 bx_tool_pixmap[hb_index].f = f;
1188 if (alignment == BX_GRAVITY_LEFT)
1190 bx_tool_pixmap[hb_index].xorigin = bx_bitmap_left_xorigin;
1191 bx_tool_pixmap[hb_index].yorigin = 0;
1192 // bx_bitmap_left_xorigin += (**bx_pixmap[bmap_id]).bounds.right;
1193 bx_bitmap_left_xorigin += 34;
1195 else
1197 // bx_bitmap_right_xorigin += (**bx_pixmap[bmap_id]).bounds.right;
1198 bx_bitmap_right_xorigin += 34;
1199 bx_tool_pixmap[hb_index].xorigin = bx_bitmap_right_xorigin;
1200 bx_tool_pixmap[hb_index].yorigin = 0;
1202 return(hb_index);
1205 // ::SHOW_HEADERBAR()
1207 // Show (redraw) the current headerbar, which is composed of
1208 // currently installed bitmaps.
1210 void bx_macintosh_gui_c::show_headerbar(void)
1212 Rect destRect;
1213 int i, xorigin;
1215 SetPort(toolwin);
1216 RGBForeColor(&medGrey);
1217 FillRect(&toolwin->portRect, &qd.black);
1218 for (i=0; i<toolPixMaps; i++)
1220 if (bx_tool_pixmap[i].alignment == BX_GRAVITY_LEFT)
1221 xorigin = bx_tool_pixmap[i].xorigin;
1222 else
1223 xorigin = toolwin->portRect.right - bx_tool_pixmap[i].xorigin;
1225 SetRect(&destRect, xorigin, 0, xorigin+32, 32);
1227 //changed, simply plot the cicn for that button, in the prescribed rectangle
1228 PlotCIcon(&destRect, bx_tool_pixmap[i].cicn);
1230 RGBForeColor(&black);
1234 // ::REPLACE_BITMAP()
1236 // Replace the bitmap installed in the headerbar ID slot 'hbar_id',
1237 // with the one specified by 'bmap_id'. 'bmap_id' will have
1238 // been generated by ::create_bitmap(). The old and new bitmap
1239 // must be of the same size. This allows the bitmap the user
1240 // sees to change, when some action occurs. For example when
1241 // the user presses on the floppy icon, it then displays
1242 // the ejected status.
1244 // hbar_id: headerbar slot ID
1245 // bmap_id: bitmap ID
1247 void bx_macintosh_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id)
1249 //bx_tool_pixmap[hbar_id].pm = bx_pixmap[bmap_id];
1250 bx_tool_pixmap[hbar_id].cicn = bx_cicn[bmap_id];
1251 show_headerbar();
1254 // ::EXIT()
1256 // Called before bochs terminates, to allow for a graceful
1257 // exit from the native GUI mechanism.
1259 void bx_macintosh_gui_c::exit(void)
1261 if (!menubarVisible)
1262 ShowMenubar(); // Make the menubar visible again
1263 InitCursor();
1266 #if 0
1267 void bx_macintosh_gui_c::snapshot_handler(void)
1269 PicHandle ScreenShot;
1270 long val;
1272 SetPort(win);
1274 ScreenShot = OpenPicture(&win->portRect);
1276 CopyBits(&win->portBits, &win->portBits, &win->portRect, &win->portRect, srcCopy, NULL);
1278 ClosePicture();
1280 val = ZeroScrap();
1282 HLock((Handle)ScreenShot);
1283 PutScrap(GetHandleSize((Handle)ScreenShot), 'PICT', *ScreenShot);
1284 HUnlock((Handle)ScreenShot);
1286 KillPicture(ScreenShot);
1288 #endif
1290 // UpdateRgn()
1292 // Updates the screen after the menubar and round corners have been hidden
1294 void UpdateRgn(RgnHandle rgn)
1296 WindowPtr window;
1298 window = FrontWindow();
1299 PaintBehind(window, rgn);
1300 CalcVisBehind(window, rgn);
1303 // HidePointer()
1305 // Hides the Mac mouse pointer
1307 void HidePointer()
1309 HiliteMenu(0);
1310 HideCursor();
1311 SetPort(win);
1312 SetPt(&scrCenter, 320, 240);
1313 LocalToGlobal(&scrCenter);
1314 ResetPointer();
1315 GetMouse(&prevPt);
1316 cursorVisible = false;
1317 CheckItem(GetMenuHandle(mBochs), iCursor, false);
1320 // ShowPointer()
1322 // Shows the Mac mouse pointer
1324 void ShowPointer()
1326 InitCursor();
1327 cursorVisible = true;
1328 CheckItem(GetMenuHandle(mBochs), iCursor, true);
1331 // HideTools()
1333 // Hides the Bochs toolbar
1335 void HideTools()
1337 HideWindow(toolwin);
1338 if (menubarVisible)
1340 MoveWindow(win, gLeft, gMinTop, false);
1342 else
1344 MoveWindow(hidden, gLeft, gMinTop, false);
1346 CheckItem(GetMenuHandle(mBochs), iTool, false);
1347 HiliteWindow(win, true);
1350 // ShowTools()
1352 // Shows the Bochs toolbar
1354 void ShowTools()
1356 if (menubarVisible)
1358 MoveWindow(win, gLeft, gMaxTop, false);
1360 else
1362 MoveWindow(hidden, gLeft, gMaxTop, false);
1364 ShowWindow(toolwin);
1365 BringToFront(toolwin);
1366 SelectWindow(toolwin);
1367 HiliteWindow(win, true);
1368 //theGui->show_headerbar();
1369 CheckItem(GetMenuHandle(mBochs), iTool, true);
1370 HiliteWindow(win, true);
1373 // HideMenubar()
1375 // Hides the menubar (obviously)
1377 void HideMenubar()
1379 Rect mBarRect;
1380 RgnHandle grayRgn;
1382 grayRgn = LMGetGrayRgn();
1383 gOldMBarHeight = GetMBarHeight();
1384 LMSetMBarHeight(0);
1385 mBarRgn = NewRgn();
1386 mBarRect = qd.screenBits.bounds;
1387 mBarRect.bottom = mBarRect.top + gOldMBarHeight;
1388 RectRgn(mBarRgn, &mBarRect);
1389 UnionRgn(grayRgn, mBarRgn, grayRgn);
1390 UpdateRgn(mBarRgn);
1392 cnrRgn = NewRgn();
1393 RectRgn(cnrRgn, &qd.screenBits.bounds);
1394 DiffRgn(cnrRgn, grayRgn, cnrRgn);
1395 UnionRgn(grayRgn, cnrRgn, grayRgn);
1396 UpdateRgn(mBarRgn);
1398 HideWindow(win);
1399 ShowWindow(backdrop);
1400 SelectWindow(backdrop);
1401 hidden = win;
1402 win = fullwin;
1403 ShowWindow(win);
1405 SelectWindow(win);
1406 menubarVisible = false;
1407 CheckItem(GetMenuHandle(mBochs), iMenuBar, false);
1410 // ShowMenubar()
1412 // Makes the menubar visible again so other programs will display correctly.
1414 void ShowMenubar()
1416 RgnHandle grayRgn;
1417 GrafPtr savePort;
1419 grayRgn = LMGetGrayRgn();
1420 LMSetMBarHeight(gOldMBarHeight);
1421 DiffRgn(grayRgn, mBarRgn, grayRgn);
1422 DisposeRgn(mBarRgn);
1423 DrawMenuBar();
1425 GetPort(&savePort);
1426 SetPort(LMGetWMgrPort());
1427 SetClip(cnrRgn);
1428 FillRgn(cnrRgn, &qd.black);
1429 SetPort(savePort);
1430 DiffRgn(grayRgn, cnrRgn, grayRgn);
1431 DisposeRgn(cnrRgn);
1433 HideWindow(backdrop);
1434 win = hidden;
1435 hidden = fullwin;
1436 HideWindow(hidden);
1437 ShowWindow(win);
1438 HiliteWindow(win, true);
1440 menubarVisible = true;
1441 CheckItem(GetMenuHandle(mBochs), iMenuBar, true);
1444 void HideConsole()
1446 HideWindow(SouixWin);
1447 CheckItem(GetMenuHandle(mBochs), iConsole, false);
1450 void ShowConsole()
1452 ShowWindow(SouixWin);
1453 SelectWindow(SouixWin);
1454 CheckItem(GetMenuHandle(mBochs), iConsole, true);
1457 // CreateKeyMap()
1459 // Create a KCHR data structure to map Mac virtual key codes to Bochs key codes
1461 void CreateKeyMap(void)
1463 const unsigned char KCHRHeader [258] = { 0, 1 };
1465 const unsigned char KCHRTable [130] = {
1468 BX_KEY_A,
1469 BX_KEY_S,
1470 BX_KEY_D,
1471 BX_KEY_F,
1472 BX_KEY_H,
1473 BX_KEY_G,
1474 BX_KEY_Z,
1475 BX_KEY_X,
1476 BX_KEY_C,
1477 BX_KEY_V,
1478 BX_KEY_LEFT_BACKSLASH,
1479 BX_KEY_B,
1480 BX_KEY_Q,
1481 BX_KEY_W,
1482 BX_KEY_E,
1483 BX_KEY_R,
1484 BX_KEY_Y,
1485 BX_KEY_T,
1486 BX_KEY_1,
1487 BX_KEY_2,
1488 BX_KEY_3,
1489 BX_KEY_4,
1490 BX_KEY_6,
1491 BX_KEY_5,
1492 BX_KEY_EQUALS,
1493 BX_KEY_9,
1494 BX_KEY_7,
1495 BX_KEY_MINUS,
1496 BX_KEY_8,
1497 BX_KEY_0,
1498 BX_KEY_RIGHT_BRACKET,
1499 BX_KEY_O,
1500 BX_KEY_U,
1501 BX_KEY_LEFT_BRACKET,
1502 BX_KEY_I,
1503 BX_KEY_P,
1504 BX_KEY_ENTER,
1505 BX_KEY_L,
1506 BX_KEY_J,
1507 BX_KEY_SINGLE_QUOTE,
1508 BX_KEY_K,
1509 BX_KEY_SEMICOLON,
1510 BX_KEY_BACKSLASH,
1511 BX_KEY_COMMA,
1512 BX_KEY_SLASH,
1513 BX_KEY_N,
1514 BX_KEY_M,
1515 BX_KEY_PERIOD,
1516 BX_KEY_TAB,
1517 BX_KEY_SPACE,
1518 BX_KEY_GRAVE,
1519 BX_KEY_BACKSPACE,
1520 BX_KEY_KP_ENTER,
1521 BX_KEY_ESC,
1522 0, // 0x36 (record button)
1523 0, // 0x37 (cmd key)
1524 0, // 0x38 (left shift)
1525 0, // 0x39 (caps lock)
1526 0, // 0x3A (left option/alt)
1527 0, // 0x3B (left ctrl)
1528 0, // 0x3C (right shift)
1529 0, // 0x3D (right option/alt)
1530 0, // 0x3E (right ctrl)
1531 0, // 0x3F (fn key -- laptops)
1532 0, // 0x40
1533 BX_KEY_KP_DELETE, // KP_PERIOD
1534 0, // 0x42 (move right/multiply)
1535 BX_KEY_KP_MULTIPLY,
1536 0, // 0x44
1537 BX_KEY_KP_ADD,
1538 0, // 0x46 (move left/add)
1539 BX_KEY_NUM_LOCK,
1540 0, // 0x48 (move down/equals)
1541 0, // 0x49
1542 0, // 0x4A
1543 BX_KEY_KP_DIVIDE,
1544 BX_KEY_KP_ENTER,
1545 0, // 0x4D (move up/divide)
1546 BX_KEY_KP_SUBTRACT,
1547 0, // 0x4F
1548 0, // 0x50
1549 BX_KEY_EQUALS, // 0x51 (kp equals)
1550 BX_KEY_KP_INSERT, // 0x52 (kp 0)
1551 BX_KEY_KP_END, // 0x53 (kp 1)
1552 BX_KEY_KP_DOWN, // 0x54 (kp 2)
1553 BX_KEY_KP_PAGE_DOWN, // 0x55 (kp 3)
1554 BX_KEY_KP_LEFT, // 0x56 (kp 4)
1555 BX_KEY_KP_5,
1556 BX_KEY_KP_RIGHT, // 0x58 (kp 6)
1557 BX_KEY_KP_HOME, // 0x59 (kp 7)
1558 0, // 0x5A
1559 BX_KEY_KP_UP, // 0x5B (kp 8)
1560 BX_KEY_KP_PAGE_UP, // 0x5C (kp 9)
1561 0, // 0x5D
1562 0, // 0x5E
1563 0, // 0x5F
1564 BX_KEY_F5,
1565 BX_KEY_F6,
1566 BX_KEY_F7,
1567 BX_KEY_F3,
1568 BX_KEY_F8,
1569 BX_KEY_F9,
1570 0, // 0x66
1571 BX_KEY_F11,
1572 0, // 0x68
1573 BX_KEY_PRINT, // 0x69 (print screen)
1574 0, // 0x6A
1575 BX_KEY_SCRL_LOCK, // 0x6B (scroll lock)
1576 0, // 0x6C
1577 BX_KEY_F10,
1578 BX_KEY_MENU, // 0x6E
1579 BX_KEY_F12,
1580 0, // 0x70
1581 BX_KEY_PAUSE, // 0x71 (pause)
1582 BX_KEY_INSERT,
1583 BX_KEY_HOME,
1584 BX_KEY_PAGE_UP,
1585 BX_KEY_DELETE,
1586 BX_KEY_F4,
1587 BX_KEY_END,
1588 BX_KEY_F2,
1589 BX_KEY_PAGE_DOWN,
1590 BX_KEY_F1,
1591 BX_KEY_LEFT,
1592 BX_KEY_RIGHT,
1593 BX_KEY_DOWN,
1594 BX_KEY_UP
1597 KCHR = NewPtrClear(390);
1598 if (KCHR == NULL)
1599 BX_PANIC(("mac: can't allocate memory for key map"));
1601 BlockMove(KCHRHeader, KCHR, sizeof(KCHRHeader));
1602 BlockMove(KCHRTable, Ptr(KCHR + sizeof(KCHRHeader)), sizeof(KCHRTable));
1605 // CreateVGAFont()
1607 // Create an array of PixMaps for the PC screen font
1609 void CreateVGAFont(void)
1611 int i, x;
1612 unsigned char *fontData, curPixel;
1613 long row_bytes, bytecount;
1615 for (i=0; i<256; i++)
1617 vgafont[i] = CreateBitMap(FONT_WIDTH, FONT_HEIGHT);
1618 row_bytes = (*(vgafont[i])).rowBytes;
1619 bytecount = row_bytes * FONT_HEIGHT;
1620 fontData = (unsigned char *)NewPtrClear(bytecount);
1622 for (x=0; x<16; x++)
1624 //curPixel = ~(bx_vgafont[i].data[x]);
1625 curPixel = (bx_vgafont[i].data[x]);
1626 fontData[x*row_bytes] = reverse_bitorder(curPixel);
1629 vgafont[i]->baseAddr = Ptr(fontData);
1633 // CreateBitMap()
1634 // Allocate a new bitmap and fill in the fields with appropriate
1635 // values.
1637 BitMap *CreateBitMap(unsigned width, unsigned height)
1639 BitMap *bm;
1640 long row_bytes;
1642 row_bytes = ((width + 31) >> 5) << 2;
1643 bm = (BitMap *)calloc(1, sizeof(BitMap));
1644 if (bm == NULL)
1645 BX_PANIC(("mac: can't allocate memory for pixmap"));
1646 SetRect(&bm->bounds, 0, 0, width, height);
1647 bm->rowBytes = row_bytes;
1648 // Quickdraw allocates a new color table by default, but we want to
1649 // use one we created earlier.
1651 return bm;
1654 // CreatePixMap()
1655 // Allocate a new pixmap handle and fill in the fields with appropriate
1656 // values.
1658 PixMapHandle CreatePixMap(unsigned left, unsigned top, unsigned width,
1659 unsigned height, unsigned depth, CTabHandle clut)
1661 PixMapHandle pm;
1662 long row_bytes;
1664 row_bytes = (((long) depth * ((long) width) + 31) >> 5) << 2;
1665 pm = NewPixMap();
1666 if (pm == NULL)
1667 BX_PANIC(("mac: can't allocate memory for pixmap"));
1668 (**pm).bounds.left = left;
1669 (**pm).bounds.top = top;
1670 (**pm).bounds.right = left+width;
1671 (**pm).bounds.bottom = top+height;
1672 (**pm).pixelSize = depth;
1673 (**pm).rowBytes = row_bytes | 0x8000;
1675 DisposeCTable((**pm).pmTable);
1676 (**pm).pmTable = clut;
1677 // Quickdraw allocates a new color table by default, but we want to
1678 // use one we created earlier.
1680 return pm;
1683 unsigned char reverse_bitorder(unsigned char b)
1685 unsigned char ret=0;
1687 for (unsigned i=0; i<8; i++)
1689 ret |= (b & 0x01) << (7-i);
1690 b >>= 1;
1693 return(ret);
1696 void bx_macintosh_gui_c::mouse_enabled_changed_specific (bx_bool val)
1700 #endif /* if BX_WITH_MACOS */