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"
84 /* This is true if we are running as a standalone application. */
88 /* This is true if we are using WaitNextEvent. */
92 /* This is true if we have Color Quickdraw. */
96 /* This is true if we are using Color Quickdraw. */
102 Rect dragrect = { -32000, -32000, 32000, 32000 };
107 /* Globals for the console window. */
109 WindowPtr console_window;
111 ControlHandle console_v_scrollbar;
113 Rect console_v_scroll_rect;
115 TEHandle console_text;
117 Rect console_text_rect;
119 /* This will go away eventually. */
120 gdb_has_a_terminal () { return 1; }
125 int eventloopdone = 0;
134 Handle siow_resource;
138 /* Don't do anything if we`re running under MPW. */
142 /* Don't do anything if we're using SIOW. */
143 /* This test requires that the siow 0 resource, as defined in
144 {RIncludes}siow.r, not be messed with. If it is, then the
145 standard Mac setup below will step on SIOW's Mac setup and
146 most likely crash the machine. */
147 siow_resource = GetResource('siow', 0);
148 if (siow_resource != nil)
153 /* Do the standard Mac environment setup. */
154 InitGraf (&QD (thePort));
156 FlushEvents (everyEvent, 0);
163 /* Color Quickdraw is different from Classic QD. */
165 has_color_qd = se.hasColorQD;
166 /* Use it if we got it. */
167 use_color_qd = has_color_qd;
171 sizerect.bottom = 1000;
172 sizerect.right = 1000;
174 sizerect.bottom = screenBits.bounds.bottom - screenBits.bounds.top;
175 sizerect.right = screenBits.bounds.right - screenBits.bounds.left;
178 /* Set up the menus. */
179 menubar = GetNewMBar (mbMain);
180 SetMenuBar (menubar);
181 /* Add the DAs etc as usual. */
182 menu = GetMHandle (mApple);
184 AddResMenu (menu, 'DRVR');
188 new_console_window ();
191 new_console_window ()
193 /* Create the main window we're going to play in. */
195 console_window = GetNewCWindow (wConsole, NULL, (WindowPtr) -1L);
197 console_window = GetNewWindow (wConsole, NULL, (WindowPtr) -1L);
199 SetPort (console_window);
200 console_text_rect = console_window->portRect;
201 /* Leave 8 pixels of blank space, for aesthetic reasons and to
202 make it easier to select from the beginning of a line. */
203 console_text_rect.left += 8;
204 console_text_rect.bottom -= sbarwid - 1;
205 console_text_rect.right -= sbarwid - 1;
206 console_text = TENew (&console_text_rect, &console_text_rect);
207 TESetSelect (0, 40000, console_text);
208 TEDelete (console_text);
209 TEAutoView (1, console_text);
211 console_v_scroll_rect = console_window->portRect;
212 console_v_scroll_rect.bottom -= sbarwid - 1;
213 console_v_scroll_rect.left = console_v_scroll_rect.right - sbarwid;
214 console_v_scrollbar =
215 NewControl (console_window, &console_v_scroll_rect,
216 "\p", 1, 0, 0, 0, scrollBarProc, 0L);
218 ShowWindow (console_window);
219 SelectWindow (console_window);
225 int eventloopdone = 0;
235 /* Figure out if the WaitNextEvent Trap is available. */
237 (NGetTrapAddress (0x60, ToolTrap) != NGetTrapAddress (0x9f, ToolTrap));
238 /* Pass WaitNextEvent an empty region the first time through. */
239 cursorRgn = NewRgn ();
240 /* Go into the main event-handling loop. */
241 while (!eventloopdone)
243 /* Use WaitNextEvent if it is available, otherwise GetNextEvent. */
246 get_global_mouse (&mouse);
247 adjust_cursor (mouse, cursorRgn);
249 gotevent = WaitNextEvent (everyEvent, &event, tm, cursorRgn);
254 gotevent = GetNextEvent (everyEvent, &event);
256 /* First decide if the event is for a dialog or is just any old event. */
257 if (FrontWindow () != nil && IsDialogEvent (&event))
262 /* Handle all the modeless dialogs here. */
263 if (DialogSelect (&event, &dialog, &itemhit))
269 /* Make sure we have the right cursor before handling the event. */
270 adjust_cursor (event.where, cursorRgn);
280 /* Collect the global coordinates of the mouse pointer. */
282 get_global_mouse (mouse)
287 OSEventAvail (0, &evt);
291 /* Change the cursor's appearance to be appropriate for the given mouse
294 adjust_cursor (mouse, region)
300 /* Decipher an event, maybe do something with it. */
305 short part, err, rslt = 0;
314 /* See if the click happened in a special part of the screen. */
315 part = FindWindow (evt->where, &win);
320 do_menu_command (MenuSelect (evt->where));
323 SystemClick (evt, win);
326 if (win != FrontWindow ())
328 /* Bring the clicked-on window to the front. */
330 /* Fix the menu to match the new front window. */
332 /* We always want to discard the event now, since clicks in a
333 windows are often irreversible actions. */
335 /* Mouse clicks in the front window do something useful. */
336 do_mouse_down (win, evt);
339 /* Standard drag behavior, no tricks necessary. */
340 DragWindow (win, evt->where, &dragrect);
343 grow_window (win, evt->where);
347 zoom_window (win, evt->where, part);
356 key = evt->message & charCodeMask;
357 /* Check for menukey equivalents. */
358 if (evt->modifiers & cmdKey)
360 if (evt->what == keyDown)
363 do_menu_command (MenuKey (key));
368 if (evt->what == keyDown)
370 /* Random keypress, interpret it. */
371 do_keyboard_command (key);
376 activate_window ((WindowPtr) evt->message, evt->modifiers & activeFlag);
379 update_window ((WindowPtr) evt->message);
382 /* Call DIBadMount in response to a diskEvt, so that the user can format
383 a floppy. (from DTS Sample) */
384 if (HiWord (evt->message) != noErr)
386 SetPt (&pnt, 50, 50);
387 err = DIBadMount (pnt, evt->message);
391 /* Grab only a single byte. */
392 switch ((evt->message >> 24) & 0xFF)
397 inbackground = !(evt->message & 1);
398 activate_window (FrontWindow (), !inbackground);
402 case kHighLevelEvent:
403 AEProcessAppleEvent (evt);
415 /* Do any idle-time activities. */
419 TEIdle (console_text);
422 grow_window (win, where)
430 winsize = GrowWindow (win, where, &sizerect);
431 /* Only do anything if it actually changed size. */
436 if (win == console_window)
438 EraseRect (&win->portRect);
439 h = LoWord (winsize);
440 v = HiWord (winsize);
441 SizeWindow (win, h, v, 1);
442 resize_console_window ();
448 zoom_window (win, where, part)
453 ZoomWindow (win, part, (win == FrontWindow ()));
454 if (win == console_window)
456 resize_console_window ();
460 resize_console_window ()
462 adjust_console_sizes ();
463 adjust_console_scrollbars ();
464 adjust_console_text ();
465 InvalRect (&console_window->portRect);
474 v_scroll_proc (ControlHandle control, short part)
476 int oldval, amount = 0, newval;
477 int pagesize = ((*console_text)->viewRect.bottom - (*console_text)->viewRect.top) / (*console_text)->lineHeight;
480 oldval = GetCtlValue (control);
496 /* (should freak out) */
499 SetCtlValue(control, oldval - amount);
500 newval = GetCtlValue (control);
501 amount = oldval - newval;
503 TEScroll (0, amount * (*console_text)->lineHeight, console_text);
507 do_mouse_down (WindowPtr win, EventRecord *event)
511 ControlHandle control;
513 if (1 /*is_app_window(win)*/)
516 mouse = event->where;
517 GlobalToLocal (&mouse);
518 part = FindControl(mouse, win, &control);
519 if (control == console_v_scrollbar)
524 value = GetCtlValue (control);
525 part = TrackControl (control, mouse, nil);
528 value -= GetCtlValue (control);
530 TEScroll(0, value * (*console_text)->lineHeight,
535 value = TrackControl (control, mouse, (ProcPtr) v_scroll_proc);
541 TEClick (mouse, 0, console_text);
546 scroll_text (hlines, vlines)
551 activate_window (win, activate)
557 if (win == nil) return;
558 /* It's convenient to make the activated window also be the
562 /* Activate the console window's scrollbar. */
563 if (win == console_window)
567 TEActivate (console_text);
568 /* Cause the grow icon to be redrawn at the next update. */
569 grow_rect = console_window->portRect;
570 grow_rect.top = grow_rect.bottom - sbarwid;
571 grow_rect.left = grow_rect.right - sbarwid;
572 InvalRect (&grow_rect);
576 TEDeactivate (console_text);
577 DrawGrowIcon (console_window);
579 HiliteControl (console_v_scrollbar, (activate ? 0 : 255));
586 int controls = 1, growbox = 0;
589 /* Set the updating window to be the current grafport. */
592 /* recalc_depths(); */
594 if (win == console_window)
601 UpdateControls (win, win->visRgn);
612 do_menu_command (which)
615 short menuid, menuitem;
626 menuid = HiWord (which);
627 menuitem = LoWord (which);
638 /* (should pop up help info) */
642 GetItem (GetMHandle (mApple), menuitem, daname);
643 daRefNum = OpenDeskAcc (daname);
650 if (console_window == FrontWindow ())
652 close_window (console_window);
654 new_console_window ();
665 /* handledbyda = SystemEdit(menuitem-1); */
669 TECut (console_text);
672 TECopy (console_text);
675 TEPaste (console_text);
678 TEDelete (console_text);
681 /* All of these operations need the same postprocessing. */
682 adjust_console_sizes ();
683 adjust_console_scrollbars ();
684 adjust_console_text ();
690 sprintf (cmdbuf, "target %s", "remote");
693 sprintf (cmdbuf, "run");
695 case miDebugContinue:
696 sprintf (cmdbuf, "continue");
699 sprintf (cmdbuf, "step");
702 sprintf (cmdbuf, "next");
708 /* Execute a command if one had been given. Do here because a command
709 may longjmp before we get a chance to unhilite the menu. */
710 if (strlen (cmdbuf) > 0)
711 execute_command (cmdbuf, 0);
714 char commandbuf[1000];
716 do_keyboard_command (key)
719 int startpos, endpos, i, len;
721 char buf[10], *text_str, *command, *cmd_start;
724 if (key == '\015' || key == '\003')
726 text = TEGetText (console_text);
727 HLock ((Handle) text);
729 startpos = (*console_text)->selStart;
730 endpos = (*console_text)->selEnd;
731 if (startpos != endpos)
733 len = endpos - startpos;
734 cmd_start = text_str + startpos;
738 for (i = startpos - 1; i >= 0; --i)
739 if (text_str[i] == '\015')
741 last_newline = text_str + i;
742 len = (text_str + startpos) - 1 - last_newline;
743 cmd_start = last_newline + 1;
745 if (len > 1000) len = 999;
746 if (len < 0) len = 0;
747 strncpy (commandbuf + 1, cmd_start, len);
748 commandbuf[1 + len] = 0;
749 command = commandbuf + 1;
750 HUnlock ((Handle) text);
751 commandbuf[0] = strlen(command);
753 /* Insert a newline and recalculate before doing any command. */
755 TEKey (key, console_text);
756 TEInsert (buf, 1, console_text);
757 adjust_console_sizes ();
758 adjust_console_scrollbars ();
759 adjust_console_text ();
761 if (strlen (command) > 0)
763 execute_command (command, 0);
764 bpstat_do_actions (&stop_bpstat);
769 /* A self-inserting character. This includes delete. */
770 TEKey (key, console_text);
774 /* Draw all graphical stuff in the console window. */
778 SetPort (console_window);
779 TEUpdate (&(console_window->portRect), console_text);
782 /* Cause an update of a given window's entire contents. */
789 if (win == nil) return;
792 EraseRect (&win->portRect);
793 InvalRect (&win->portRect);
797 adjust_console_sizes ()
801 tmprect = console_window->portRect;
802 /* Move and size the scrollbar. */
803 MoveControl (console_v_scrollbar, tmprect.right - sbarwid, 0);
804 SizeControl (console_v_scrollbar, sbarwid + 1, tmprect.bottom - sbarwid + 1);
805 /* Move and size the text. */
807 tmprect.right -= sbarwid;
808 tmprect.bottom -= sbarwid;
809 InsetRect(&tmprect, 1, 1);
810 (*console_text)->destRect = tmprect;
811 /* Fiddle bottom of viewrect to be even multiple of text lines. */
812 tmprect.bottom = tmprect.top
813 + ((tmprect.bottom - tmprect.top) / (*console_text)->lineHeight)
814 * (*console_text)->lineHeight;
815 (*console_text)->viewRect = tmprect;
818 adjust_console_scrollbars ()
820 int lines, newmax, value;
822 (*console_v_scrollbar)->contrlVis = 0;
823 lines = (*console_text)->nLines;
824 newmax = lines - (((*console_text)->viewRect.bottom
825 - (*console_text)->viewRect.top)
826 / (*console_text)->lineHeight);
827 if (newmax < 0) newmax = 0;
828 SetCtlMax (console_v_scrollbar, newmax);
829 value = ((*console_text)->viewRect.top - (*console_text)->destRect.top)
830 / (*console_text)->lineHeight;
831 SetCtlValue (console_v_scrollbar, value);
832 (*console_v_scrollbar)->contrlVis = 0xff;
833 ShowControl (console_v_scrollbar);
836 /* Scroll the TE record so that it is consistent with the scrollbar(s). */
838 adjust_console_text ()
840 TEScroll (((*console_text)->viewRect.left
841 - (*console_text)->destRect.left)
842 - 0 /* get h scroll value */,
843 ((((*console_text)->viewRect.top - (*console_text)->destRect.top)
844 / (*console_text)->lineHeight)
845 - GetCtlValue (console_v_scrollbar))
846 * (*console_text)->lineHeight,
850 /* Readline substitute. */
853 readline (char *prrompt)
855 return gdb_readline (prrompt);
858 char *rl_completer_word_break_characters;
860 char *rl_completer_quote_characters;
862 int (*rl_completion_entry_function) ();
866 char *rl_line_buffer;
868 char *rl_readline_name;
870 /* History substitute. */
873 add_history (char *buf)
878 stifle_history (int n)
888 read_history (char *name)
893 write_history (char *name)
898 history_expand (char *x, char **y)
903 history_get (int xxx)
911 filename_completion_function (char *text, char *name)
917 tilde_expand (char *str)
919 return strsave (str);
922 /* Modified versions of standard I/O. */
929 hacked_fprintf (FILE *fp, const char *fmt, ...)
935 if (mac_app && (fp == stdout || fp == stderr))
939 ret = vsprintf(buf, fmt, ap);
940 TEInsert (buf, strlen(buf), console_text);
943 ret = vfprintf (fp, fmt, ap);
951 hacked_printf (const char *fmt, ...)
957 ret = hacked_vfprintf(stdout, fmt, ap);
965 hacked_vfprintf (FILE *fp, const char *format, va_list args)
967 if (mac_app && (fp == stdout || fp == stderr))
972 ret = vsprintf(buf, format, args);
973 TEInsert (buf, strlen(buf), console_text);
974 if (strchr(buf, '\n'))
976 adjust_console_sizes ();
977 adjust_console_scrollbars ();
978 adjust_console_text ();
983 return vfprintf (fp, format, args);
988 hacked_fputs (const char *s, FILE *fp)
990 if (mac_app && (fp == stdout || fp == stderr))
992 TEInsert (s, strlen(s), console_text);
995 adjust_console_sizes ();
996 adjust_console_scrollbars ();
997 adjust_console_text ();
1002 return fputs (s, fp);
1007 hacked_fputc (const char c, FILE *fp)
1009 if (mac_app && (fp == stdout || fp == stderr))
1014 TEInsert (buf, 1, console_text);
1017 adjust_console_sizes ();
1018 adjust_console_scrollbars ();
1019 adjust_console_text ();
1024 return fputc (c, fp);
1029 hacked_putc (const char c, FILE *fp)
1031 if (mac_app && (fp == stdout || fp == stderr))
1036 TEInsert (buf, 1, console_text);
1039 adjust_console_sizes ();
1040 adjust_console_scrollbars ();
1041 adjust_console_text ();
1046 return fputc (c, fp);
1051 hacked_fflush (FILE *fp)
1053 if (mac_app && (fp == stdout || fp == stderr))
1055 adjust_console_sizes ();
1056 adjust_console_scrollbars ();
1057 adjust_console_text ();
1065 hacked_fgetc (FILE *fp)
1067 if (mac_app && (fp == stdin))
1069 /* Catch any attempts to use this. */
1070 DebugStr("\pShould not be reading from stdin!");