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,
20 Boston, MA 02111-1307, USA. */
24 #include <readline/readline.h>
25 #include <readline/history.h>
28 #include <Resources.h>
29 #include <QuickDraw.h>
37 #include <ToolUtils.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"
86 /* This is true if we are running as a standalone application. */
90 /* This is true if we are using WaitNextEvent. */
94 /* This is true if we have Color Quickdraw. */
98 /* This is true if we are using Color Quickdraw. */
105 {-32000, -32000, 32000, 32000};
110 /* Globals for the console window. */
112 WindowPtr console_window
;
114 ControlHandle console_v_scrollbar
;
116 Rect console_v_scroll_rect
;
118 TEHandle console_text
;
120 Rect console_text_rect
;
122 /* This will go away eventually. */
123 gdb_has_a_terminal (void)
131 int eventloopdone
= 0;
141 Handle siow_resource
;
145 str
= getenv ("DEBUG_GDB");
146 if (str
!= NULL
&& str
[0] != '\0')
148 if (strcmp (str
, "openp") == 0)
152 /* Don't do anything if we`re running under MPW. */
156 /* Don't do anything if we're using SIOW. */
157 /* This test requires that the siow 0 resource, as defined in
158 {RIncludes}siow.r, not be messed with. If it is, then the
159 standard Mac setup below will step on SIOW's Mac setup and
160 most likely crash the machine. */
161 siow_resource
= GetResource ('siow', 0);
162 if (siow_resource
!= nil
)
167 /* Do the standard Mac environment setup. */
168 InitGraf (&QD (thePort
));
170 FlushEvents (everyEvent
, 0);
177 /* Color Quickdraw is different from Classic QD. */
178 SysEnvirons (2, &se
);
179 has_color_qd
= se
.hasColorQD
;
180 /* Use it if we got it. */
181 use_color_qd
= has_color_qd
;
185 sizerect
.bottom
= 1000;
186 sizerect
.right
= 1000;
188 sizerect
.bottom
= screenBits
.bounds
.bottom
- screenBits
.bounds
.top
;
189 sizerect
.right
= screenBits
.bounds
.right
- screenBits
.bounds
.left
;
192 /* Set up the menus. */
193 menubar
= GetNewMBar (mbMain
);
194 SetMenuBar (menubar
);
195 /* Add the DAs etc as usual. */
196 menu
= GetMHandle (mApple
);
199 AddResMenu (menu
, 'DRVR');
203 new_console_window ();
206 new_console_window (void)
208 /* Create the main window we're going to play in. */
210 console_window
= GetNewCWindow (wConsole
, NULL
, (WindowPtr
) - 1L);
212 console_window
= GetNewWindow (wConsole
, NULL
, (WindowPtr
) - 1L);
214 SetPort (console_window
);
215 console_text_rect
= console_window
->portRect
;
216 /* Leave 8 pixels of blank space, for aesthetic reasons and to
217 make it easier to select from the beginning of a line. */
218 console_text_rect
.left
+= 8;
219 console_text_rect
.bottom
-= sbarwid
- 1;
220 console_text_rect
.right
-= sbarwid
- 1;
221 console_text
= TENew (&console_text_rect
, &console_text_rect
);
222 TESetSelect (0, 40000, console_text
);
223 TEDelete (console_text
);
224 TEAutoView (1, console_text
);
226 console_v_scroll_rect
= console_window
->portRect
;
227 console_v_scroll_rect
.bottom
-= sbarwid
- 1;
228 console_v_scroll_rect
.left
= console_v_scroll_rect
.right
- sbarwid
;
229 console_v_scrollbar
=
230 NewControl (console_window
, &console_v_scroll_rect
,
231 "\p", 1, 0, 0, 0, scrollBarProc
, 0L);
233 ShowWindow (console_window
);
234 SelectWindow (console_window
);
237 mac_command_loop (void)
240 int eventloopdone
= 0;
250 /* Figure out if the WaitNextEvent Trap is available. */
252 (NGetTrapAddress (0x60, ToolTrap
) != NGetTrapAddress (0x9f, ToolTrap
));
253 /* Pass WaitNextEvent an empty region the first time through. */
254 cursorRgn
= NewRgn ();
255 /* Go into the main event-handling loop. */
256 while (!eventloopdone
)
258 /* Use WaitNextEvent if it is available, otherwise GetNextEvent. */
261 get_global_mouse (&mouse
);
262 adjust_cursor (mouse
, cursorRgn
);
263 tm
= GetCaretTime ();
264 gotevent
= WaitNextEvent (everyEvent
, &event
, tm
, cursorRgn
);
269 gotevent
= GetNextEvent (everyEvent
, &event
);
271 /* First decide if the event is for a dialog or is just any old event. */
272 if (FrontWindow () != nil
&& IsDialogEvent (&event
))
277 /* Handle all the modeless dialogs here. */
278 if (DialogSelect (&event
, &dialog
, &itemhit
))
284 /* Make sure we have the right cursor before handling the event. */
285 adjust_cursor (event
.where
, cursorRgn
);
295 /* Collect the global coordinates of the mouse pointer. */
297 get_global_mouse (Point
*mouse
)
301 OSEventAvail (0, &evt
);
305 /* Change the cursor's appearance to be appropriate for the given mouse
308 adjust_cursor (Point mouse
, RgnHandle region
)
312 /* Decipher an event, maybe do something with it. */
314 do_event (EventRecord
*evt
)
316 short part
, err
, rslt
= 0;
325 /* See if the click happened in a special part of the screen. */
326 part
= FindWindow (evt
->where
, &win
);
331 do_menu_command (MenuSelect (evt
->where
));
334 SystemClick (evt
, win
);
337 if (win
!= FrontWindow ())
339 /* Bring the clicked-on window to the front. */
341 /* Fix the menu to match the new front window. */
343 /* We always want to discard the event now, since clicks in a
344 windows are often irreversible actions. */
347 /* Mouse clicks in the front window do something useful. */
348 do_mouse_down (win
, evt
);
351 /* Standard drag behavior, no tricks necessary. */
352 DragWindow (win
, evt
->where
, &dragrect
);
355 grow_window (win
, evt
->where
);
359 zoom_window (win
, evt
->where
, part
);
368 key
= evt
->message
& charCodeMask
;
369 /* Check for menukey equivalents. */
370 if (evt
->modifiers
& cmdKey
)
372 if (evt
->what
== keyDown
)
375 do_menu_command (MenuKey (key
));
380 if (evt
->what
== keyDown
)
382 /* Random keypress, interpret it. */
383 do_keyboard_command (key
);
388 activate_window ((WindowPtr
) evt
->message
, evt
->modifiers
& activeFlag
);
391 update_window ((WindowPtr
) evt
->message
);
394 /* Call DIBadMount in response to a diskEvt, so that the user can format
395 a floppy. (from DTS Sample) */
396 if (HiWord (evt
->message
) != noErr
)
398 SetPt (&pnt
, 50, 50);
399 err
= DIBadMount (pnt
, evt
->message
);
403 /* Grab only a single byte. */
404 switch ((evt
->message
>> 24) & 0xFF)
409 inbackground
= !(evt
->message
& 1);
410 activate_window (FrontWindow (), !inbackground
);
414 case kHighLevelEvent
:
415 AEProcessAppleEvent (evt
);
427 /* Do any idle-time activities. */
431 TEIdle (console_text
);
434 grow_window (WindowPtr win
, Point where
)
440 winsize
= GrowWindow (win
, where
, &sizerect
);
441 /* Only do anything if it actually changed size. */
446 if (win
== console_window
)
448 EraseRect (&win
->portRect
);
449 h
= LoWord (winsize
);
450 v
= HiWord (winsize
);
451 SizeWindow (win
, h
, v
, 1);
452 resize_console_window ();
458 zoom_window (WindowPtr win
, Point where
, short part
)
460 ZoomWindow (win
, part
, (win
== FrontWindow ()));
461 if (win
== console_window
)
463 resize_console_window ();
467 resize_console_window (void)
469 adjust_console_sizes ();
470 adjust_console_scrollbars ();
471 adjust_console_text ();
472 InvalRect (&console_window
->portRect
);
475 close_window (WindowPtr win
)
480 v_scroll_proc (ControlHandle control
, short part
)
482 int oldval
, amount
= 0, newval
;
483 int pagesize
= ((*console_text
)->viewRect
.bottom
- (*console_text
)->viewRect
.top
) / (*console_text
)->lineHeight
;
486 oldval
= GetCtlValue (control
);
502 /* (should freak out) */
505 SetCtlValue (control
, oldval
- amount
);
506 newval
= GetCtlValue (control
);
507 amount
= oldval
- newval
;
509 TEScroll (0, amount
* (*console_text
)->lineHeight
, console_text
);
513 do_mouse_down (WindowPtr win
, EventRecord
* event
)
517 ControlHandle control
;
519 if (1 /*is_app_window(win) */ )
522 mouse
= event
->where
;
523 GlobalToLocal (&mouse
);
524 part
= FindControl (mouse
, win
, &control
);
525 if (control
== console_v_scrollbar
)
530 value
= GetCtlValue (control
);
531 part
= TrackControl (control
, mouse
, nil
);
534 value
-= GetCtlValue (control
);
536 TEScroll (0, value
* (*console_text
)->lineHeight
,
541 #if 0 /* don't deal with right now */
542 #if 1 /* universal headers */
543 value
= TrackControl (control
, mouse
, (ControlActionUPP
) v_scroll_proc
);
545 value
= TrackControl (control
, mouse
, (ProcPtr
) v_scroll_proc
);
553 TEClick (mouse
, 0, console_text
);
558 scroll_text (int hlines
, int vlines
)
562 activate_window (WindowPtr win
, int activate
)
568 /* It's convenient to make the activated window also be the
572 /* Activate the console window's scrollbar. */
573 if (win
== console_window
)
577 TEActivate (console_text
);
578 /* Cause the grow icon to be redrawn at the next update. */
579 grow_rect
= console_window
->portRect
;
580 grow_rect
.top
= grow_rect
.bottom
- sbarwid
;
581 grow_rect
.left
= grow_rect
.right
- sbarwid
;
582 InvalRect (&grow_rect
);
586 TEDeactivate (console_text
);
587 DrawGrowIcon (console_window
);
589 HiliteControl (console_v_scrollbar
, (activate
? 0 : 255));
593 update_window (WindowPtr win
)
595 int controls
= 1, growbox
= 0;
598 /* Set the updating window to be the current grafport. */
601 /* recalc_depths(); */
603 if (win
== console_window
)
610 UpdateControls (win
, win
->visRgn
);
621 do_menu_command (long which
)
623 short menuid
, menuitem
;
634 menuid
= HiWord (which
);
635 menuitem
= LoWord (which
);
646 /* (should pop up help info) */
650 GetItem (GetMHandle (mApple
), menuitem
, daname
);
651 daRefNum
= OpenDeskAcc (daname
);
658 if (console_window
== FrontWindow ())
660 close_window (console_window
);
662 new_console_window ();
673 /* handledbyda = SystemEdit(menuitem-1); */
677 TECut (console_text
);
680 TECopy (console_text
);
683 TEPaste (console_text
);
686 TEDelete (console_text
);
689 /* All of these operations need the same postprocessing. */
690 adjust_console_sizes ();
691 adjust_console_scrollbars ();
692 adjust_console_text ();
698 sprintf (cmdbuf
, "target %s", "remote");
701 sprintf (cmdbuf
, "run");
703 case miDebugContinue
:
704 sprintf (cmdbuf
, "continue");
707 sprintf (cmdbuf
, "step");
710 sprintf (cmdbuf
, "next");
716 /* Execute a command if one had been given. Do here because a command
717 may longjmp before we get a chance to unhilite the menu. */
718 if (strlen (cmdbuf
) > 0)
719 execute_command (cmdbuf
, 0);
722 char commandbuf
[1000];
724 do_keyboard_command (int key
)
726 int startpos
, endpos
, i
, len
;
728 char buf
[10], *text_str
, *command
, *cmd_start
;
731 if (key
== '\015' || key
== '\003')
733 text
= TEGetText (console_text
);
734 HLock ((Handle
) text
);
736 startpos
= (*console_text
)->selStart
;
737 endpos
= (*console_text
)->selEnd
;
738 if (startpos
!= endpos
)
740 len
= endpos
- startpos
;
741 cmd_start
= text_str
+ startpos
;
745 for (i
= startpos
- 1; i
>= 0; --i
)
746 if (text_str
[i
] == '\015')
748 last_newline
= text_str
+ i
;
749 len
= (text_str
+ startpos
) - 1 - last_newline
;
750 cmd_start
= last_newline
+ 1;
756 strncpy (commandbuf
+ 1, cmd_start
, len
);
757 commandbuf
[1 + len
] = 0;
758 command
= commandbuf
+ 1;
759 HUnlock ((Handle
) text
);
760 commandbuf
[0] = strlen (command
);
762 /* Insert a newline and recalculate before doing any command. */
764 TEKey (key
, console_text
);
765 TEInsert (buf
, 1, console_text
);
766 adjust_console_sizes ();
767 adjust_console_scrollbars ();
768 adjust_console_text ();
770 if (strlen (command
) > 0)
772 execute_command (command
, 0);
773 bpstat_do_actions (&stop_bpstat
);
778 /* A self-inserting character. This includes delete. */
779 TEKey (key
, console_text
);
783 /* Draw all graphical stuff in the console window. */
787 SetPort (console_window
);
788 TEUpdate (&(console_window
->portRect
), console_text
);
791 /* Cause an update of a given window's entire contents. */
793 force_update (WindowPtr win
)
801 EraseRect (&win
->portRect
);
802 InvalRect (&win
->portRect
);
806 adjust_console_sizes (void)
810 tmprect
= console_window
->portRect
;
811 /* Move and size the scrollbar. */
812 MoveControl (console_v_scrollbar
, tmprect
.right
- sbarwid
, 0);
813 SizeControl (console_v_scrollbar
, sbarwid
+ 1, tmprect
.bottom
- sbarwid
+ 1);
814 /* Move and size the text. */
816 tmprect
.right
-= sbarwid
;
817 tmprect
.bottom
-= sbarwid
;
818 InsetRect (&tmprect
, 1, 1);
819 (*console_text
)->destRect
= tmprect
;
820 /* Fiddle bottom of viewrect to be even multiple of text lines. */
821 tmprect
.bottom
= tmprect
.top
822 + ((tmprect
.bottom
- tmprect
.top
) / (*console_text
)->lineHeight
)
823 * (*console_text
)->lineHeight
;
824 (*console_text
)->viewRect
= tmprect
;
827 adjust_console_scrollbars (void)
829 int lines
, newmax
, value
;
831 (*console_v_scrollbar
)->contrlVis
= 0;
832 lines
= (*console_text
)->nLines
;
833 newmax
= lines
- (((*console_text
)->viewRect
.bottom
834 - (*console_text
)->viewRect
.top
)
835 / (*console_text
)->lineHeight
);
838 SetCtlMax (console_v_scrollbar
, newmax
);
839 value
= ((*console_text
)->viewRect
.top
- (*console_text
)->destRect
.top
)
840 / (*console_text
)->lineHeight
;
841 SetCtlValue (console_v_scrollbar
, value
);
842 (*console_v_scrollbar
)->contrlVis
= 0xff;
843 ShowControl (console_v_scrollbar
);
846 /* Scroll the TE record so that it is consistent with the scrollbar(s). */
848 adjust_console_text (void)
850 TEScroll (((*console_text
)->viewRect
.left
851 - (*console_text
)->destRect
.left
)
852 - 0 /* get h scroll value */ ,
853 ((((*console_text
)->viewRect
.top
- (*console_text
)->destRect
.top
)
854 / (*console_text
)->lineHeight
)
855 - GetCtlValue (console_v_scrollbar
))
856 * (*console_text
)->lineHeight
,
860 /* Readline substitute. */
863 readline (char *prrompt
)
865 return gdb_readline (prrompt
);
868 char *rl_completer_word_break_characters
;
870 char *rl_completer_quote_characters
;
872 int (*rl_completion_entry_function
) ();
876 char *rl_line_buffer
;
878 char *rl_readline_name
;
880 /* History substitute. */
883 add_history (char *buf
)
888 stifle_history (int n
)
893 unstifle_history (void)
898 read_history (char *name
)
903 write_history (char *name
)
908 history_expand (char *x
, char **y
)
913 history_get (int xxx
)
921 filename_completion_function (char *text
, char *name
)
927 tilde_expand (char *str
)
929 return strsave (str
);
932 /* Modified versions of standard I/O. */
937 hacked_fprintf (FILE * fp
, const char *fmt
,...)
943 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
947 ret
= vsprintf (buf
, fmt
, ap
);
948 TEInsert (buf
, strlen (buf
), console_text
);
951 ret
= vfprintf (fp
, fmt
, ap
);
959 hacked_printf (const char *fmt
,...)
965 ret
= hacked_vfprintf (stdout
, fmt
, ap
);
973 hacked_vfprintf (FILE * fp
, const char *format
, va_list args
)
975 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
980 ret
= vsprintf (buf
, format
, args
);
981 TEInsert (buf
, strlen (buf
), console_text
);
982 if (strchr (buf
, '\n'))
984 adjust_console_sizes ();
985 adjust_console_scrollbars ();
986 adjust_console_text ();
991 return vfprintf (fp
, format
, args
);
996 hacked_fputs (const char *s
, FILE * fp
)
998 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
1000 TEInsert (s
, strlen (s
), console_text
);
1001 if (strchr (s
, '\n'))
1003 adjust_console_sizes ();
1004 adjust_console_scrollbars ();
1005 adjust_console_text ();
1010 return fputs (s
, fp
);
1015 hacked_fputc (const char c
, FILE * fp
)
1017 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
1022 TEInsert (buf
, 1, console_text
);
1025 adjust_console_sizes ();
1026 adjust_console_scrollbars ();
1027 adjust_console_text ();
1032 return fputc (c
, fp
);
1037 hacked_putc (const char c
, FILE * fp
)
1039 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
1044 TEInsert (buf
, 1, console_text
);
1047 adjust_console_sizes ();
1048 adjust_console_scrollbars ();
1049 adjust_console_text ();
1054 return fputc (c
, fp
);
1059 hacked_fflush (FILE * fp
)
1061 if (mac_app
&& (fp
== stdout
|| fp
== stderr
))
1063 adjust_console_sizes ();
1064 adjust_console_scrollbars ();
1065 adjust_console_text ();
1073 hacked_fgetc (FILE * fp
)
1075 if (mac_app
&& (fp
== stdin
))
1077 /* Catch any attempts to use this. */
1078 DebugStr ("\pShould not be reading from stdin!");