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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 #include <Resources.h>
28 #include <QuickDraw.h>
36 #include <ToolUtils.h>
48 #include <PPCToolbox.h>
49 #include <AppleEvents.h>
50 #include <StandardFile.h>
54 #define QD(whatever) (qd.##whatever)
55 #define QDPat(whatever) (&(qd.##whatever))
59 #define QD(whatever) (whatever)
62 #define p2c(pstr,cbuf) \
63 strncpy(cbuf, ((char *) (pstr) + 1), pstr[0]); \
66 #define pascalify(STR) \
67 sprintf(tmpbuf, " %s", STR); \
68 tmpbuf[0] = strlen(STR);
71 #include "call-cmds.h"
76 #include "breakpoint.h"
78 #include "expression.h"
85 /* This is true if we are running as a standalone application. */
89 /* This is true if we are using WaitNextEvent. */
93 /* This is true if we have Color Quickdraw. */
97 /* This is true if we are using Color Quickdraw. */
103 Rect dragrect
= { -32000, -32000, 32000, 32000 };
108 /* Globals for the console window. */
110 WindowPtr console_window
;
112 ControlHandle console_v_scrollbar
;
114 Rect console_v_scroll_rect
;
116 TEHandle console_text
;
118 Rect console_text_rect
;
120 /* This will go away eventually. */
121 gdb_has_a_terminal () { return 1; }
126 int eventloopdone
= 0;
136 Handle siow_resource
;
140 str
= getenv("DEBUG_GDB");
141 if (str
!= NULL
&& str
[0] != '\0')
143 if (strcmp(str
, "openp") == 0)
147 /* Don't do anything if we`re running under MPW. */
151 /* Don't do anything if we're using SIOW. */
152 /* This test requires that the siow 0 resource, as defined in
153 {RIncludes}siow.r, not be messed with. If it is, then the
154 standard Mac setup below will step on SIOW's Mac setup and
155 most likely crash the machine. */
156 siow_resource
= GetResource('siow', 0);
157 if (siow_resource
!= nil
)
162 /* Do the standard Mac environment setup. */
163 InitGraf (&QD (thePort
));
165 FlushEvents (everyEvent
, 0);
172 /* Color Quickdraw is different from Classic QD. */
174 has_color_qd
= se
.hasColorQD
;
175 /* Use it if we got it. */
176 use_color_qd
= has_color_qd
;
180 sizerect
.bottom
= 1000;
181 sizerect
.right
= 1000;
183 sizerect
.bottom
= screenBits
.bounds
.bottom
- screenBits
.bounds
.top
;
184 sizerect
.right
= screenBits
.bounds
.right
- screenBits
.bounds
.left
;
187 /* Set up the menus. */
188 menubar
= GetNewMBar (mbMain
);
189 SetMenuBar (menubar
);
190 /* Add the DAs etc as usual. */
191 menu
= GetMHandle (mApple
);
193 AddResMenu (menu
, 'DRVR');
197 new_console_window ();
200 new_console_window ()
202 /* Create the main window we're going to play in. */
204 console_window
= GetNewCWindow (wConsole
, NULL
, (WindowPtr
) -1L);
206 console_window
= GetNewWindow (wConsole
, NULL
, (WindowPtr
) -1L);
208 SetPort (console_window
);
209 console_text_rect
= console_window
->portRect
;
210 /* Leave 8 pixels of blank space, for aesthetic reasons and to
211 make it easier to select from the beginning of a line. */
212 console_text_rect
.left
+= 8;
213 console_text_rect
.bottom
-= sbarwid
- 1;
214 console_text_rect
.right
-= sbarwid
- 1;
215 console_text
= TENew (&console_text_rect
, &console_text_rect
);
216 TESetSelect (0, 40000, console_text
);
217 TEDelete (console_text
);
218 TEAutoView (1, console_text
);
220 console_v_scroll_rect
= console_window
->portRect
;
221 console_v_scroll_rect
.bottom
-= sbarwid
- 1;
222 console_v_scroll_rect
.left
= console_v_scroll_rect
.right
- sbarwid
;
223 console_v_scrollbar
=
224 NewControl (console_window
, &console_v_scroll_rect
,
225 "\p", 1, 0, 0, 0, scrollBarProc
, 0L);
227 ShowWindow (console_window
);
228 SelectWindow (console_window
);
234 int eventloopdone
= 0;
244 /* Figure out if the WaitNextEvent Trap is available. */
246 (NGetTrapAddress (0x60, ToolTrap
) != NGetTrapAddress (0x9f, ToolTrap
));
247 /* Pass WaitNextEvent an empty region the first time through. */
248 cursorRgn
= NewRgn ();
249 /* Go into the main event-handling loop. */
250 while (!eventloopdone
)
252 /* Use WaitNextEvent if it is available, otherwise GetNextEvent. */
255 get_global_mouse (&mouse
);
256 adjust_cursor (mouse
, cursorRgn
);
258 gotevent
= WaitNextEvent (everyEvent
, &event
, tm
, cursorRgn
);
263 gotevent
= GetNextEvent (everyEvent
, &event
);
265 /* First decide if the event is for a dialog or is just any old event. */
266 if (FrontWindow () != nil
&& IsDialogEvent (&event
))
271 /* Handle all the modeless dialogs here. */
272 if (DialogSelect (&event
, &dialog
, &itemhit
))
278 /* Make sure we have the right cursor before handling the event. */
279 adjust_cursor (event
.where
, cursorRgn
);
289 /* Collect the global coordinates of the mouse pointer. */
291 get_global_mouse (mouse
)
296 OSEventAvail (0, &evt
);
300 /* Change the cursor's appearance to be appropriate for the given mouse
303 adjust_cursor (mouse
, region
)
309 /* Decipher an event, maybe do something with it. */
314 short part
, err
, rslt
= 0;
323 /* See if the click happened in a special part of the screen. */
324 part
= FindWindow (evt
->where
, &win
);
329 do_menu_command (MenuSelect (evt
->where
));
332 SystemClick (evt
, win
);
335 if (win
!= FrontWindow ())
337 /* Bring the clicked-on window to the front. */
339 /* Fix the menu to match the new front window. */
341 /* We always want to discard the event now, since clicks in a
342 windows are often irreversible actions. */
344 /* Mouse clicks in the front window do something useful. */
345 do_mouse_down (win
, evt
);
348 /* Standard drag behavior, no tricks necessary. */
349 DragWindow (win
, evt
->where
, &dragrect
);
352 grow_window (win
, evt
->where
);
356 zoom_window (win
, evt
->where
, part
);
365 key
= evt
->message
& charCodeMask
;
366 /* Check for menukey equivalents. */
367 if (evt
->modifiers
& cmdKey
)
369 if (evt
->what
== keyDown
)
372 do_menu_command (MenuKey (key
));
377 if (evt
->what
== keyDown
)
379 /* Random keypress, interpret it. */
380 do_keyboard_command (key
);
385 activate_window ((WindowPtr
) evt
->message
, evt
->modifiers
& activeFlag
);
388 update_window ((WindowPtr
) evt
->message
);
391 /* Call DIBadMount in response to a diskEvt, so that the user can format
392 a floppy. (from DTS Sample) */
393 if (HiWord (evt
->message
) != noErr
)
395 SetPt (&pnt
, 50, 50);
396 err
= DIBadMount (pnt
, evt
->message
);
400 /* Grab only a single byte. */
401 switch ((evt
->message
>> 24) & 0xFF)
406 inbackground
= !(evt
->message
& 1);
407 activate_window (FrontWindow (), !inbackground
);
411 case kHighLevelEvent
:
412 AEProcessAppleEvent (evt
);
424 /* Do any idle-time activities. */
428 TEIdle (console_text
);
431 grow_window (win
, where
)
439 winsize
= GrowWindow (win
, where
, &sizerect
);
440 /* Only do anything if it actually changed size. */
445 if (win
== console_window
)
447 EraseRect (&win
->portRect
);
448 h
= LoWord (winsize
);
449 v
= HiWord (winsize
);
450 SizeWindow (win
, h
, v
, 1);
451 resize_console_window ();
457 zoom_window (win
, where
, part
)
462 ZoomWindow (win
, part
, (win
== FrontWindow ()));
463 if (win
== console_window
)
465 resize_console_window ();
469 resize_console_window ()
471 adjust_console_sizes ();
472 adjust_console_scrollbars ();
473 adjust_console_text ();
474 InvalRect (&console_window
->portRect
);
483 v_scroll_proc (ControlHandle control
, short part
)
485 int oldval
, amount
= 0, newval
;
486 int pagesize
= ((*console_text
)->viewRect
.bottom
- (*console_text
)->viewRect
.top
) / (*console_text
)->lineHeight
;
489 oldval
= GetCtlValue (control
);
505 /* (should freak out) */
508 SetCtlValue(control
, oldval
- amount
);
509 newval
= GetCtlValue (control
);
510 amount
= oldval
- newval
;
512 TEScroll (0, amount
* (*console_text
)->lineHeight
, console_text
);
516 do_mouse_down (WindowPtr win
, EventRecord
*event
)
520 ControlHandle control
;
522 if (1 /*is_app_window(win)*/)
525 mouse
= event
->where
;
526 GlobalToLocal (&mouse
);
527 part
= FindControl(mouse
, win
, &control
);
528 if (control
== console_v_scrollbar
)
533 value
= GetCtlValue (control
);
534 part
= TrackControl (control
, mouse
, nil
);
537 value
-= GetCtlValue (control
);
539 TEScroll(0, value
* (*console_text
)->lineHeight
,
544 #if 0 /* don't deal with right now */
545 #if 1 /* universal headers */
546 value
= TrackControl (control
, mouse
, (ControlActionUPP
) v_scroll_proc
);
548 value
= TrackControl (control
, mouse
, (ProcPtr
) v_scroll_proc
);
556 TEClick (mouse
, 0, console_text
);
561 scroll_text (hlines
, vlines
)
566 activate_window (win
, activate
)
572 if (win
== nil
) return;
573 /* It's convenient to make the activated window also be the
577 /* Activate the console window's scrollbar. */
578 if (win
== console_window
)
582 TEActivate (console_text
);
583 /* Cause the grow icon to be redrawn at the next update. */
584 grow_rect
= console_window
->portRect
;
585 grow_rect
.top
= grow_rect
.bottom
- sbarwid
;
586 grow_rect
.left
= grow_rect
.right
- sbarwid
;
587 InvalRect (&grow_rect
);
591 TEDeactivate (console_text
);
592 DrawGrowIcon (console_window
);
594 HiliteControl (console_v_scrollbar
, (activate
? 0 : 255));
601 int controls
= 1, growbox
= 0;
604 /* Set the updating window to be the current grafport. */
607 /* recalc_depths(); */
609 if (win
== console_window
)
616 UpdateControls (win
, win
->visRgn
);
627 do_menu_command (which
)
630 short menuid
, menuitem
;
641 menuid
= HiWord (which
);
642 menuitem
= LoWord (which
);
653 /* (should pop up help info) */
657 GetItem (GetMHandle (mApple
), menuitem
, daname
);
658 daRefNum
= OpenDeskAcc (daname
);
665 if (console_window
== FrontWindow ())
667 close_window (console_window
);
669 new_console_window ();
680 /* handledbyda = SystemEdit(menuitem-1); */
684 TECut (console_text
);
687 TECopy (console_text
);
690 TEPaste (console_text
);
693 TEDelete (console_text
);
696 /* All of these operations need the same postprocessing. */
697 adjust_console_sizes ();
698 adjust_console_scrollbars ();
699 adjust_console_text ();
705 sprintf (cmdbuf
, "target %s", "remote");
708 sprintf (cmdbuf
, "run");
710 case miDebugContinue
:
711 sprintf (cmdbuf
, "continue");
714 sprintf (cmdbuf
, "step");
717 sprintf (cmdbuf
, "next");
723 /* Execute a command if one had been given. Do here because a command
724 may longjmp before we get a chance to unhilite the menu. */
725 if (strlen (cmdbuf
) > 0)
726 execute_command (cmdbuf
, 0);
729 char commandbuf
[1000];
731 do_keyboard_command (key
)
734 int startpos
, endpos
, i
, len
;
736 char buf
[10], *text_str
, *command
, *cmd_start
;
739 if (key
== '\015' || key
== '\003')
741 text
= TEGetText (console_text
);
742 HLock ((Handle
) text
);
744 startpos
= (*console_text
)->selStart
;
745 endpos
= (*console_text
)->selEnd
;
746 if (startpos
!= endpos
)
748 len
= endpos
- startpos
;
749 cmd_start
= text_str
+ startpos
;
753 for (i
= startpos
- 1; i
>= 0; --i
)
754 if (text_str
[i
] == '\015')
756 last_newline
= text_str
+ i
;
757 len
= (text_str
+ startpos
) - 1 - last_newline
;
758 cmd_start
= last_newline
+ 1;
760 if (len
> 1000) len
= 999;
761 if (len
< 0) len
= 0;
762 strncpy (commandbuf
+ 1, cmd_start
, len
);
763 commandbuf
[1 + len
] = 0;
764 command
= commandbuf
+ 1;
765 HUnlock ((Handle
) text
);
766 commandbuf
[0] = strlen(command
);
768 /* Insert a newline and recalculate before doing any command. */
770 TEKey (key
, console_text
);
771 TEInsert (buf
, 1, console_text
);
772 adjust_console_sizes ();
773 adjust_console_scrollbars ();
774 adjust_console_text ();
776 if (strlen (command
) > 0)
778 execute_command (command
, 0);
779 bpstat_do_actions (&stop_bpstat
);
784 /* A self-inserting character. This includes delete. */
785 TEKey (key
, console_text
);
789 /* Draw all graphical stuff in the console window. */
793 SetPort (console_window
);
794 TEUpdate (&(console_window
->portRect
), console_text
);
797 /* Cause an update of a given window's entire contents. */
804 if (win
== nil
) return;
807 EraseRect (&win
->portRect
);
808 InvalRect (&win
->portRect
);
812 adjust_console_sizes ()
816 tmprect
= console_window
->portRect
;
817 /* Move and size the scrollbar. */
818 MoveControl (console_v_scrollbar
, tmprect
.right
- sbarwid
, 0);
819 SizeControl (console_v_scrollbar
, sbarwid
+ 1, tmprect
.bottom
- sbarwid
+ 1);
820 /* Move and size the text. */
822 tmprect
.right
-= sbarwid
;
823 tmprect
.bottom
-= sbarwid
;
824 InsetRect(&tmprect
, 1, 1);
825 (*console_text
)->destRect
= tmprect
;
826 /* Fiddle bottom of viewrect to be even multiple of text lines. */
827 tmprect
.bottom
= tmprect
.top
828 + ((tmprect
.bottom
- tmprect
.top
) / (*console_text
)->lineHeight
)
829 * (*console_text
)->lineHeight
;
830 (*console_text
)->viewRect
= tmprect
;
833 adjust_console_scrollbars ()
835 int lines
, newmax
, value
;
837 (*console_v_scrollbar
)->contrlVis
= 0;
838 lines
= (*console_text
)->nLines
;
839 newmax
= lines
- (((*console_text
)->viewRect
.bottom
840 - (*console_text
)->viewRect
.top
)
841 / (*console_text
)->lineHeight
);
842 if (newmax
< 0) newmax
= 0;
843 SetCtlMax (console_v_scrollbar
, newmax
);
844 value
= ((*console_text
)->viewRect
.top
- (*console_text
)->destRect
.top
)
845 / (*console_text
)->lineHeight
;
846 SetCtlValue (console_v_scrollbar
, value
);
847 (*console_v_scrollbar
)->contrlVis
= 0xff;
848 ShowControl (console_v_scrollbar
);
851 /* Scroll the TE record so that it is consistent with the scrollbar(s). */
853 adjust_console_text ()
855 TEScroll (((*console_text
)->viewRect
.left
856 - (*console_text
)->destRect
.left
)
857 - 0 /* get h scroll value */,
858 ((((*console_text
)->viewRect
.top
- (*console_text
)->destRect
.top
)
859 / (*console_text
)->lineHeight
)
860 - GetCtlValue (console_v_scrollbar
))
861 * (*console_text
)->lineHeight
,
865 /* Readline substitute. */
868 readline (char *prrompt
)
870 return gdb_readline (prrompt
);
873 char *rl_completer_word_break_characters
;
875 char *rl_completer_quote_characters
;
877 int (*rl_completion_entry_function
) ();
881 char *rl_line_buffer
;
883 char *rl_readline_name
;
885 /* History substitute. */
888 add_history (char *buf
)
893 stifle_history (int n
)
903 read_history (char *name
)
908 write_history (char *name
)
913 history_expand (char *x
, char **y
)
918 history_get (int xxx
)
926 filename_completion_function (char *text
, char *name
)
932 tilde_expand (char *str
)
934 return strsave (str
);
937 /* Modified versions of standard I/O. */
942 hacked_fprintf (FILE *fp
, const char *fmt
, ...)
948 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
952 ret
= vsprintf(buf
, fmt
, ap
);
953 TEInsert (buf
, strlen(buf
), console_text
);
956 ret
= vfprintf (fp
, fmt
, ap
);
964 hacked_printf (const char *fmt
, ...)
970 ret
= hacked_vfprintf(stdout
, fmt
, ap
);
978 hacked_vfprintf (FILE *fp
, const char *format
, va_list args
)
980 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
985 ret
= vsprintf(buf
, format
, args
);
986 TEInsert (buf
, strlen(buf
), console_text
);
987 if (strchr(buf
, '\n'))
989 adjust_console_sizes ();
990 adjust_console_scrollbars ();
991 adjust_console_text ();
996 return vfprintf (fp
, format
, args
);
1001 hacked_fputs (const char *s
, FILE *fp
)
1003 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
1005 TEInsert (s
, strlen(s
), console_text
);
1006 if (strchr(s
, '\n'))
1008 adjust_console_sizes ();
1009 adjust_console_scrollbars ();
1010 adjust_console_text ();
1015 return fputs (s
, fp
);
1020 hacked_fputc (const char c
, FILE *fp
)
1022 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
1027 TEInsert (buf
, 1, console_text
);
1030 adjust_console_sizes ();
1031 adjust_console_scrollbars ();
1032 adjust_console_text ();
1037 return fputc (c
, fp
);
1042 hacked_putc (const char c
, FILE *fp
)
1044 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
1049 TEInsert (buf
, 1, console_text
);
1052 adjust_console_sizes ();
1053 adjust_console_scrollbars ();
1054 adjust_console_text ();
1059 return fputc (c
, fp
);
1064 hacked_fflush (FILE *fp
)
1066 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
1068 adjust_console_sizes ();
1069 adjust_console_scrollbars ();
1070 adjust_console_text ();
1078 hacked_fgetc (FILE *fp
)
1080 if (mac_app
&& (fp
== stdin
))
1082 /* Catch any attempts to use this. */
1083 DebugStr("\pShould not be reading from stdin!");