1 /* Top level support for Mac interface to GDB, the GNU debugger.
2 Copyright 1994 Free Software Foundation, Inc.
3 Contributed by Cygnus Support. Written by Stan Shebs.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
28 #include <Resources.h>
29 #include <QuickDraw.h>
37 #include <ToolUtils.h>
48 #include <GestaltEqu.h>
49 #include <PPCToolbox.h>
50 #include <AppleEvents.h>
51 #include <StandardFile.h>
55 #define QD(whatever) (qd.##whatever)
56 #define QDPat(whatever) (&(qd.##whatever))
60 #define QD(whatever) (whatever)
63 #define p2c(pstr,cbuf) \
64 strncpy(cbuf, ((char *) (pstr) + 1), pstr[0]); \
67 #define pascalify(STR) \
68 sprintf(tmpbuf, " %s", STR); \
69 tmpbuf[0] = strlen(STR);
72 #include "call-cmds.h"
77 #include "breakpoint.h"
79 #include "expression.h"
92 Rect dragrect = { -32000, -32000, 32000, 32000 };
97 /* Globals for the console window. */
99 WindowPtr console_window;
101 ControlHandle console_v_scrollbar;
103 Rect console_v_scroll_rect;
105 TEHandle console_text;
107 Rect console_text_rect;
109 /* This will go away eventually. */
110 gdb_has_a_terminal () { return 1; }
116 int eventloopdone = 0;
126 /* Do the standard Mac environment setup. */
127 InitGraf (&QD (thePort));
129 FlushEvents (everyEvent, 0);
136 /* Color Quickdraw is different from Classic QD. */
138 hasColorQD = se.hasColorQD;
142 sizerect.bottom = 1000;
143 sizerect.right = 1000;
145 sizerect.bottom = screenBits.bounds.bottom - screenBits.bounds.top;
146 sizerect.right = screenBits.bounds.right - screenBits.bounds.left;
149 /* Set up the menus. */
150 menubar = GetNewMBar (mbMain);
151 SetMenuBar (menubar);
152 /* Add the DAs etc as usual. */
153 menu = GetMHandle (mApple);
155 AddResMenu (menu, 'DRVR');
159 new_console_window ();
164 new_console_window ()
166 /* Create the main window we're going to play in. */
168 console_window = GetNewCWindow (wConsole, NULL, (WindowPtr) -1L);
170 console_window = GetNewWindow (wConsole, NULL, (WindowPtr) -1L);
172 SetPort (console_window);
173 console_text_rect = console_window->portRect;
174 /* Leave 8 pixels of blank space, for aesthetic reasons and to
175 make it easier to select from the beginning of a line. */
176 console_text_rect.left += 8;
177 console_text_rect.bottom -= sbarwid - 1;
178 console_text_rect.right -= sbarwid - 1;
179 console_text = TENew (&console_text_rect, &console_text_rect);
180 TESetSelect (0, 40000, console_text);
181 TEDelete (console_text);
182 TEAutoView (1, console_text);
184 console_v_scroll_rect = console_window->portRect;
185 console_v_scroll_rect.bottom -= sbarwid - 1;
186 console_v_scroll_rect.left = console_v_scroll_rect.right - sbarwid;
187 console_v_scrollbar =
188 NewControl (console_window, &console_v_scroll_rect,
189 "\p", 1, 0, 0, 0, scrollBarProc, 0L);
191 ShowWindow (console_window);
192 SelectWindow (console_window);
198 int eventloopdone = 0;
208 /* Figure out if the WaitNextEvent Trap is available. */
210 (NGetTrapAddress (0x60, ToolTrap) != NGetTrapAddress (0x9f, ToolTrap));
211 /* Pass WNE an empty region the 1st time thru. */
212 cursorRgn = NewRgn ();
213 /* Go into the main event-handling loop. */
214 while (!eventloopdone)
216 /* Use WaitNextEvent if it is available, otherwise GetNextEvent. */
219 get_global_mouse (&mouse);
220 adjust_cursor (mouse, cursorRgn);
221 gotevent = WaitNextEvent (everyEvent, &event, GetCaretTime(), cursorRgn);
226 gotevent = GetNextEvent (everyEvent, &event);
228 /* First decide if the event is for a dialog or is just any old event. */
229 if (FrontWindow () != nil && IsDialogEvent (&event))
234 /* Handle all the modeless dialogs here. */
235 if (DialogSelect (&event, &dialog, &itemhit))
241 /* Make sure we have the right cursor before handling the event. */
242 adjust_cursor (event.where, cursorRgn);
252 get_global_mouse (mouse)
257 OSEventAvail (0, &evt);
261 adjust_cursor (mouse, region)
267 /* Decipher an event, maybe do something with it. */
272 short part, err, rslt = 0;
281 /* See if the click happened in a special part of the screen. */
282 part = FindWindow (evt->where, &win);
287 do_menu_command (MenuSelect (evt->where));
290 SystemClick (evt, win);
293 if (win != FrontWindow ())
295 /* Bring the clicked-on window to the front. */
297 /* Fix the menu to match the new front window. */
299 /* We always want to discard the event now, since clicks in a
300 windows are often irreversible actions. */
302 /* Mouse clicks in the front window do something useful. */
303 do_mouse_down (win, evt);
306 /* Standard drag behavior, no tricks necessary. */
307 DragWindow (win, evt->where, &dragrect);
310 grow_window (win, evt->where);
314 zoom_window (win, evt->where, part);
323 key = evt->message & charCodeMask;
324 /* Check for menukey equivalents. */
325 if (evt->modifiers & cmdKey)
327 if (evt->what == keyDown)
330 do_menu_command (MenuKey (key));
335 if (evt->what == keyDown)
337 /* Random keypress, interpret it. */
338 do_keyboard_command (key);
343 activate_window ((WindowPtr) evt->message, evt->modifiers & activeFlag);
346 update_window ((WindowPtr) evt->message);
349 /* Call DIBadMount in response to a diskEvt, so that the user can format
350 a floppy. (from DTS Sample) */
351 if (HiWord (evt->message) != noErr)
353 SetPt (&pnt, 50, 50);
354 err = DIBadMount (pnt, evt->message);
358 /* Grab only a single byte. */
359 switch ((evt->message >> 24) & 0xFF)
364 inbackground = !(evt->message & 1);
365 activate_window (FrontWindow (), !inbackground);
369 case kHighLevelEvent:
370 AEProcessAppleEvent (evt);
382 /* Do any idle-time activities. */
386 TEIdle (console_text);
389 grow_window (win, where)
397 winsize = GrowWindow (win, where, &sizerect);
402 EraseRect (&win->portRect);
403 h = LoWord (winsize);
404 v = HiWord (winsize);
405 SizeWindow (win, h, v, 1);
406 adjust_console_sizes ();
407 adjust_console_scrollbars ();
408 adjust_console_text ();
409 InvalRect (&win->portRect);
414 zoom_window (win, where, part)
419 ZoomWindow (win, part, (win == FrontWindow ()));
420 adjust_console_sizes ();
421 adjust_console_scrollbars ();
422 adjust_console_text ();
423 InvalRect (&(win->portRect));
432 v_scroll_proc (ControlHandle control, short part)
434 int oldval, amount = 0, newval;
435 int pagesize = ((*console_text)->viewRect.bottom - (*console_text)->viewRect.top) / (*console_text)->lineHeight;
438 oldval = GetCtlValue (control);
454 /* (should freak out) */
457 SetCtlValue(control, oldval - amount);
458 newval = GetCtlValue (control);
459 amount = oldval - newval;
461 TEScroll (0, amount * (*console_text)->lineHeight, console_text);
465 do_mouse_down (WindowPtr win, EventRecord *event)
469 ControlHandle control;
471 if (1 /*is_app_window(win)*/)
474 mouse = event->where;
475 GlobalToLocal (&mouse);
476 part = FindControl(mouse, win, &control);
477 if (control == console_v_scrollbar)
482 value = GetCtlValue (control);
483 part = TrackControl (control, mouse, nil);
486 value -= GetCtlValue (control);
488 TEScroll(0, value * (*console_text)->lineHeight,
493 value = TrackControl (control, mouse, (ProcPtr) v_scroll_proc);
499 TEClick (mouse, 0, console_text);
504 activate_window (win, activate)
510 if (win == nil) return;
511 /* It's convenient to make the activated window also be the
515 /* Activate the console window's scrollbar. */
516 if (win == console_window)
520 TEActivate (console_text);
521 /* Cause the grow icon to be redrawn at the next update. */
522 grow_rect = console_window->portRect;
523 grow_rect.top = grow_rect.bottom - sbarwid;
524 grow_rect.left = grow_rect.right - sbarwid;
525 InvalRect (&grow_rect);
529 TEDeactivate (console_text);
530 DrawGrowIcon (console_window);
532 HiliteControl (console_v_scrollbar, (activate ? 0 : 255));
539 int controls = 1, growbox = 0;
542 /* Set the updating window to be the current grafport. */
545 /* recalc_depths(); */
547 if (win == console_window)
554 UpdateControls (win, win->visRgn);
565 do_menu_command (which)
568 short menuid, menuitem;
579 menuid = HiWord (which);
580 menuitem = LoWord (which);
591 /* (should pop up help info) */
595 GetItem (GetMHandle (mApple), menuitem, daname);
596 daRefNum = OpenDeskAcc (daname);
603 if (console_window == FrontWindow ())
605 close_window (console_window);
607 new_console_window ();
618 /* handledbyda = SystemEdit(menuitem-1); */
622 TECut (console_text);
625 TECopy (console_text);
628 TEPaste (console_text);
631 TEDelete (console_text);
634 /* All of these operations need the same postprocessing. */
635 adjust_console_sizes ();
636 adjust_console_scrollbars ();
637 adjust_console_text ();
643 sprintf (cmdbuf, "target %s", "remote");
646 sprintf (cmdbuf, "run");
648 case miDebugContinue:
649 sprintf (cmdbuf, "continue");
652 sprintf (cmdbuf, "step");
655 sprintf (cmdbuf, "next");
661 /* Execute a command if one had been given. Do here because a command
662 may longjmp before we get a chance to unhilite the menu. */
663 if (strlen (cmdbuf) > 0)
664 execute_command (cmdbuf, 0);
667 char commandbuf[1000];
669 do_keyboard_command (key)
672 int startpos, endpos, i, len;
674 char buf[10], *text_str, *command, *cmd_start;
677 if (key == '\015' || key == '\003')
679 text = TEGetText (console_text);
680 HLock ((Handle) text);
682 startpos = (*console_text)->selStart;
683 endpos = (*console_text)->selEnd;
684 if (startpos != endpos)
686 len = endpos - startpos;
687 cmd_start = text_str + startpos;
691 for (i = startpos - 1; i >= 0; --i)
692 if (text_str[i] == '\015')
694 last_newline = text_str + i;
695 len = (text_str + startpos) - 1 - last_newline;
696 cmd_start = last_newline + 1;
698 if (len > 1000) len = 999;
699 if (len < 0) len = 0;
700 strncpy (commandbuf + 1, cmd_start, len);
701 commandbuf[1 + len] = 0;
702 command = commandbuf + 1;
703 HUnlock ((Handle) text);
704 commandbuf[0] = strlen(command);
706 /* Insert a newline and recalculate before doing any command. */
708 TEKey (key, console_text);
709 TEInsert (buf, 1, console_text);
710 adjust_console_sizes ();
711 adjust_console_scrollbars ();
712 adjust_console_text ();
714 if (strlen (command) > 0)
716 execute_command (command, 0);
717 bpstat_do_actions (&stop_bpstat);
720 else if (0 /* editing chars... */)
725 /* A self-inserting character. */
726 TEKey (key, console_text);
732 SetPort (console_window);
733 TEUpdate (&(console_window->portRect), console_text);
735 FrameRect (&((*console_text)->viewRect));
736 FrameRect (&((*console_text)->destRect));
740 /* Cause an update of a window's entire contents. */
747 if (win == nil) return;
750 EraseRect (&win->portRect);
751 InvalRect (&win->portRect);
755 adjust_console_sizes ()
759 tmprect = console_window->portRect;
760 MoveControl (console_v_scrollbar, tmprect.right - sbarwid, 0);
761 SizeControl (console_v_scrollbar, sbarwid + 1, tmprect.bottom - sbarwid + 1);
763 tmprect.right -= sbarwid;
764 tmprect.bottom -= sbarwid;
765 InsetRect(&tmprect, 1, 1);
766 (*console_text)->viewRect = tmprect;
767 (*console_text)->destRect = tmprect;
768 /* (should fiddle bottom of viewrect to be even multiple of lines?) */
771 adjust_console_scrollbars ()
773 int lines, newmax, value;
775 (*console_v_scrollbar)->contrlVis = 0;
776 lines = (*console_text)->nLines;
777 newmax = lines - (((*console_text)->viewRect.bottom
778 - (*console_text)->viewRect.top)
779 / (*console_text)->lineHeight);
780 if (newmax < 0) newmax = 0;
781 SetCtlMax (console_v_scrollbar, newmax);
782 value = ((*console_text)->viewRect.top - (*console_text)->destRect.top)
783 / (*console_text)->lineHeight;
784 SetCtlValue (console_v_scrollbar, value);
785 (*console_v_scrollbar)->contrlVis = 0xff;
786 ShowControl (console_v_scrollbar);
789 /* Scroll the TE record so that it is consistent with the scrollbar(s). */
791 adjust_console_text ()
793 TEScroll (((*console_text)->viewRect.left
794 - (*console_text)->destRect.left)
795 - 0 /* get h scroll value */,
796 (((*console_text)->viewRect.top
797 - (*console_text)->destRect.top)
798 - GetCtlValue (console_v_scrollbar))
799 * (*console_text)->lineHeight,
803 /* Readline substitute. */
806 readline (char *prrompt)
808 return gdb_readline (prrompt);
811 char *rl_completer_word_break_characters;
813 char *rl_completer_quote_characters;
815 int (*rl_completion_entry_function) ();
819 char *rl_line_buffer;
821 char *rl_readline_name;
823 /* History substitute. */
826 add_history (char *buf)
831 stifle_history (int n)
841 read_history (char *name)
846 write_history (char *name)
851 history_expand (char *x, char **y)
856 history_get (int xxx)
864 filename_completion_function (char *text, char *name)
870 tilde_expand (char *str)
872 return strsave (str);
875 /* Modified versions of standard I/O. */
882 hacked_fprintf (FILE *fp, const char *fmt, ...)
888 if (mac_app && (fp == stdout || fp == stderr))
892 ret = vsprintf(buf, fmt, ap);
893 TESetSelect (40000, 40000, console_text);
894 TEInsert (buf, strlen(buf), console_text);
897 ret = vfprintf (fp, fmt, ap);
905 hacked_printf (const char *fmt, ...)
913 ret = hacked_vfprintf(stdout, fmt, ap);
916 ret = vfprintf (stdout, fmt, ap);
924 hacked_vfprintf (FILE *fp, const char *format, va_list args)
926 if (mac_app && (fp == stdout || fp == stderr))
931 ret = vsprintf(buf, format, args);
932 TESetSelect (40000, 40000, console_text);
933 TEInsert (buf, strlen(buf), console_text);
937 return vfprintf (fp, format, args);
942 hacked_fputs (const char *s, FILE *fp)
944 if (mac_app && (fp == stdout || fp == stderr))
946 TESetSelect (40000, 40000, console_text);
947 TEInsert (s, strlen(s), console_text);
951 return fputs (s, fp);
956 hacked_fputc (const char c, FILE *fp)
958 if (mac_app && (fp == stdout || fp == stderr))
963 TESetSelect (40000, 40000, console_text);
964 TEInsert (buf, 1, console_text);
968 return fputc (c, fp);
973 hacked_putc (const char c, FILE *fp)
975 if (mac_app && (fp == stdout || fp == stderr))
980 TESetSelect (40000, 40000, console_text);
981 TEInsert (buf, 1, console_text);
984 return fputc (c, fp);
989 hacked_fflush (FILE *fp)
991 if (mac_app && (fp == stdout || fp == stderr))