Tue Apr 26 17:44:27 1994 Stan Shebs (shebs@andros.cygnus.com)
[deliverable/binutils-gdb.git] / gdb / mac-xdep.c
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 for Cygnus.
4
5 This file is part of GDB.
6
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.
11
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.
16
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. */
20
21 #include "defs.h"
22
23 #include <Values.h>
24 #include <Types.h>
25 #include <Resources.h>
26 #include <QuickDraw.h>
27 #include <Fonts.h>
28 #include <Events.h>
29 #include <Windows.h>
30 #include <Menus.h>
31 #include <TextEdit.h>
32 #include <Dialogs.h>
33 #include <Desk.h>
34 #include <ToolUtils.h>
35 #include <Memory.h>
36 #include <SegLoad.h>
37 #include <Files.h>
38 #include <Folders.h>
39 #include <OSUtils.h>
40 #include <OSEvents.h>
41 #include <DiskInit.h>
42 #include <Packages.h>
43 #include <Traps.h>
44 #include <Lists.h>
45 #include <GestaltEqu.h>
46 #include <PPCToolbox.h>
47 #include <AppleEvents.h>
48 #include <StandardFile.h>
49 #include <Sound.h>
50
51 #ifdef MPW
52 #define QD(whatever) (qd.##whatever)
53 #define QDPat(whatever) (&(qd.##whatever))
54 #endif
55
56 #ifdef THINK_C
57 #define QD(whatever) (whatever)
58 #endif
59
60 #define p2c(pstr,cbuf) \
61 strncpy(cbuf, ((char *) (pstr) + 1), pstr[0]); \
62 cbuf[pstr[0]] = '\0';
63
64 #define pascalify(STR) \
65 sprintf(tmpbuf, " %s", STR); \
66 tmpbuf[0] = strlen(STR);
67
68 #include "gdbcmd.h"
69 #include "call-cmds.h"
70 #include "symtab.h"
71 #include "inferior.h"
72 #include "signals.h"
73 #include "target.h"
74 #include "breakpoint.h"
75 #include "gdbtypes.h"
76 #include "expression.h"
77 #include "language.h"
78 #include "terminal.h" /* For job_control. */
79
80 #include "mac-defs.h"
81
82 int useWNE;
83
84 int hasColorQD;
85
86 int inbackground;
87
88 Rect dragrect = { -32000, -32000, 32000, 32000 };
89 Rect sizerect;
90
91 int sbarwid = 15;
92
93 /* Globals for the console window. */
94
95 WindowPtr console_window;
96
97 ControlHandle console_v_scrollbar;
98
99 Rect console_v_scroll_rect;
100
101 TEHandle console_text;
102
103 Rect console_text_rect;
104
105 mac_init ()
106 {
107 SysEnvRec se;
108 int eventloopdone = 0;
109 Boolean gotevent;
110 Point mouse;
111 EventRecord event;
112 WindowPtr win;
113 RgnHandle cursorRgn;
114 int i;
115 Handle menubar;
116 MenuHandle menu;
117
118 /* Do the standard Mac environment setup. */
119 InitGraf (&QD (thePort));
120 InitFonts ();
121 FlushEvents (everyEvent, 0);
122 InitWindows ();
123 InitMenus ();
124 TEInit ();
125 InitDialogs (NULL);
126 InitCursor ();
127
128 /* Color Quickdraw is different from Classic QD. */
129 SysEnvirons(2, &se);
130 hasColorQD = se.hasColorQD;
131
132 sizerect.top = 50;
133 sizerect.left = 50;
134 sizerect.bottom = 1000;
135 sizerect.right = 1000;
136 #if 0
137 sizerect.bottom = screenBits.bounds.bottom - screenBits.bounds.top;
138 sizerect.right = screenBits.bounds.right - screenBits.bounds.left;
139 #endif
140
141 /* Set up the menus. */
142 menubar = GetNewMBar (mbMain);
143 SetMenuBar (menubar);
144 /* Add the DAs etc as usual. */
145 menu = GetMHandle (mApple);
146 if (menu != nil) {
147 AddResMenu (menu, 'DRVR');
148 }
149 DrawMenuBar ();
150
151 /* Create the main window we're going to play in. */
152 if (hasColorQD)
153 console_window = GetNewCWindow (wConsole, NULL, (WindowPtr) -1L);
154 else
155 console_window = GetNewWindow (wConsole, NULL, (WindowPtr) -1L);
156
157 if (1) DebugStr("\pnear beginning");
158 SetPort (console_window);
159 console_text_rect = console_window->portRect;
160 console_text_rect.bottom -= sbarwid - 1;
161 console_text_rect.right -= sbarwid - 1;
162 console_text = TENew (&console_text_rect, &console_text_rect);
163 TESetSelect (0, 32767, console_text);
164 TEDelete (console_text);
165 TEInsert ("(gdb)", strlen("(gdb)"), console_text);
166
167 console_v_scroll_rect = console_window->portRect;
168 console_v_scroll_rect.bottom -= sbarwid - 1;
169 console_v_scroll_rect.left = console_v_scroll_rect.right - sbarwid;
170 console_v_scrollbar =
171 NewControl (console_window, &console_v_scroll_rect,
172 "\p", 1, 0, 0, 0, scrollBarProc, 0L);
173
174 ShowWindow (console_window);
175 SelectWindow (console_window);
176 /* force_update (console_window); */
177
178 return 1;
179 }
180
181 mac_command_loop()
182 {
183 SysEnvRec se;
184 int eventloopdone = 0;
185 Boolean gotevent;
186 Point mouse;
187 EventRecord event;
188 WindowPtr win;
189 RgnHandle cursorRgn;
190 int i;
191 Handle menubar;
192 MenuHandle menu;
193
194 /* Figure out if the WaitNextEvent Trap is available. */
195 useWNE =
196 (NGetTrapAddress (0x60, ToolTrap) != NGetTrapAddress (0x9f, ToolTrap));
197 /* Pass WNE an empty region the 1st time thru. */
198 cursorRgn = NewRgn ();
199 /* Go into the main event-handling loop. */
200 while (!eventloopdone)
201 {
202 /* Use WaitNextEvent if it is available, otherwise GetNextEvent. */
203 if (useWNE)
204 {
205 get_global_mouse (&mouse);
206 adjust_cursor (mouse, cursorRgn);
207 gotevent = WaitNextEvent (everyEvent, &event, 0L, cursorRgn);
208 }
209 else
210 {
211 SystemTask ();
212 gotevent = GetNextEvent (everyEvent, &event);
213 }
214 /* First decide if the event is for a dialog or is just any old event. */
215 if (FrontWindow () != nil && IsDialogEvent (&event))
216 {
217 short itemhit;
218 DialogPtr dialog;
219
220 /* Handle all the modeless dialogs here. */
221 if (DialogSelect (&event, &dialog, &itemhit))
222 {
223 }
224 }
225 else if (gotevent)
226 {
227 /* Make sure we have the right cursor before handling the event. */
228 adjust_cursor (event.where, cursorRgn);
229 do_event (&event);
230 }
231 }
232 }
233
234 get_global_mouse (mouse)
235 Point *mouse;
236 {
237 EventRecord evt;
238
239 OSEventAvail (0, &evt);
240 *mouse = evt.where;
241 }
242
243 adjust_cursor (mouse, region)
244 Point mouse;
245 RgnHandle region;
246 {
247 }
248
249 /* Decipher an event, maybe do something with it. */
250
251 do_event (evt)
252 EventRecord *evt;
253 {
254 short part, err, rslt = 0;
255 WindowPtr win;
256 Boolean hit;
257 char key;
258 Point pnt;
259
260 switch (evt->what)
261 {
262 case mouseDown:
263 /* See if the click happened in a special part of the screen. */
264 part = FindWindow (evt->where, &win);
265 switch (part)
266 {
267 case inMenuBar:
268 adjust_menus ();
269 do_menu_command (MenuSelect (evt->where));
270 break;
271 case inSysWindow:
272 SystemClick (evt, win);
273 break;
274 case inContent:
275 if (win != FrontWindow ())
276 {
277 /* Bring the clicked-on window to the front. */
278 SelectWindow (win);
279 /* Fix the menu to match the new front window. */
280 adjust_menus ();
281 /* We always want to discard the event now, since clicks in a
282 windows are often irreversible actions. */
283 } else
284 /* Mouse clicks in the front window do something useful. */
285 do_mouse_down (win, evt);
286 break;
287 case inDrag:
288 /* Standard drag behavior, no tricks necessary. */
289 DragWindow (win, evt->where, &dragrect);
290 break;
291 case inGrow:
292 grow_window (win, evt->where);
293 break;
294 case inZoomIn:
295 case inZoomOut:
296 zoom_window (win, evt->where, part);
297 break;
298 case inGoAway:
299 close_window (win);
300 break;
301 }
302 break;
303 case keyDown:
304 case autoKey:
305 key = evt->message & charCodeMask;
306 /* Check for menukey equivalents. */
307 if (evt->modifiers & cmdKey)
308 {
309 if (evt->what == keyDown)
310 {
311 adjust_menus ();
312 do_menu_command (MenuKey (key));
313 }
314 }
315 else
316 {
317 if (evt->what == keyDown)
318 {
319 /* Random keypress, interpret it. */
320 do_keyboard_command (key);
321 }
322 }
323 break;
324 case activateEvt:
325 activate_window ((WindowPtr) evt->message, evt->modifiers & activeFlag);
326 break;
327 case updateEvt:
328 update_window ((WindowPtr) evt->message);
329 break;
330 case diskEvt:
331 /* Call DIBadMount in response to a diskEvt, so that the user can format
332 a floppy. (from DTS Sample) */
333 if (HiWord (evt->message) != noErr)
334 {
335 SetPt (&pnt, 50, 50);
336 err = DIBadMount (pnt, evt->message);
337 }
338 break;
339 case app4Evt:
340 /* Grab only a single byte. */
341 switch ((evt->message >> 24) & 0xFF)
342 {
343 case 0xfa:
344 break;
345 case 1:
346 inbackground = !(evt->message & 1);
347 activate_window (FrontWindow (), !inbackground);
348 break;
349 }
350 break;
351 case kHighLevelEvent:
352 AEProcessAppleEvent (evt);
353 break;
354 case nullEvent:
355 rslt = 1;
356 break;
357 default:
358 break;
359 }
360 return rslt;
361 }
362
363 grow_window (win, where)
364 WindowPtr win;
365 Point where;
366 {
367 long winsize;
368 int h, v;
369 GrafPtr oldport;
370
371 winsize = GrowWindow (win, where, &sizerect);
372 if (winsize != 0)
373 {
374 GetPort (&oldport);
375 SetPort (win);
376 EraseRect (&win->portRect);
377 h = LoWord (winsize);
378 v = HiWord (winsize);
379 SizeWindow (win, h, v, 1);
380 if (win == console_window)
381 {
382 MoveControl(console_v_scrollbar, h - sbarwid, 0);
383 SizeControl(console_v_scrollbar, sbarwid + 1, v - sbarwid + 1);
384 }
385 InvalRect (&win->portRect);
386 SetPort (oldport);
387 }
388 }
389
390 zoom_window (win, where, part)
391 WindowPtr win;
392 Point where;
393 short part;
394 {
395 }
396
397 close_window (win)
398 WindowPtr win;
399 {
400 }
401
402 do_mouse_down (win, event)
403 WindowPtr win;
404 EventRecord *event;
405 {
406 short part;
407 Point mouse;
408 ControlHandle control;
409
410 if (1 /*is_app_window(win)*/)
411 {
412 SetPort (win);
413 mouse = event->where;
414 GlobalToLocal (&mouse);
415 part = FindControl(mouse, win, &control);
416 if (control == console_v_scrollbar)
417 {
418 SysBeep(20);
419 }
420 else
421 {
422 TEClick (mouse, 0, console_text);
423 }
424 }
425 }
426
427 activate_window (win, activate)
428 WindowPtr win;
429 int activate;
430 {
431 if (win == nil) return;
432 /* It's convenient to make the activated window also be the
433 current GrafPort. */
434 if (activate)
435 SetPort(win);
436 /* Activate the console window's scrollbar. */
437 if (win == console_window)
438 HiliteControl (console_v_scrollbar, (activate ? 0 : 255));
439 }
440
441 update_window (win)
442 WindowPtr win;
443 {
444 int controls = 1, growbox = 0;
445 GrafPtr oldport;
446
447 /* Set the updating window to be the current grafport. */
448 GetPort (&oldport);
449 SetPort (win);
450 /* recalc_depths(); */
451 BeginUpdate (win);
452 if (win == console_window)
453 {
454 draw_console ();
455 controls = 1;
456 growbox = 1;
457 }
458 if (controls)
459 UpdateControls (win, win->visRgn);
460 if (growbox)
461 DrawGrowIcon (win);
462 EndUpdate (win);
463 SetPort (oldport);
464 }
465
466 adjust_menus ()
467 {
468 }
469
470 do_menu_command (which)
471 long which;
472 {
473 short menuid, menuitem;
474 short itemHit;
475 Str255 daname;
476 short daRefNum;
477 Boolean handledbyda;
478 WindowPtr win;
479 short ditem;
480 int i;
481
482 menuid = HiWord (which);
483 menuitem = LoWord (which);
484 switch (menuid)
485 {
486 case mApple:
487 switch (menuitem)
488 {
489 case miAbout:
490 /* Alert(aAbout, nil); */
491 break;
492 default:
493 GetItem (GetMHandle (mApple), menuitem, daname);
494 daRefNum = OpenDeskAcc (daname);
495 }
496 break;
497 case mFile:
498 switch (menuitem)
499 {
500 case miFileQuit:
501 ExitToShell ();
502 break;
503 }
504 break;
505 case mEdit:
506 /* handledbyda = SystemEdit(menuitem-1); */
507 switch (menuitem)
508 {
509 case miEditCut:
510 break;
511 case miEditCopy:
512 break;
513 case miEditPaste:
514 break;
515 case miEditClear:
516 break;
517 }
518 break;
519 }
520 HiliteMenu (0);
521 }
522
523 char commandbuf[1000];
524
525 do_keyboard_command (key)
526 char key;
527 {
528 int startpos, endpos, i;
529 char buf[10], *text_str, *command;
530 CharsHandle text;
531
532 if (key == '\015' || key == '\003')
533 {
534 /* (should) Interpret the line as a command. */
535 text = TEGetText (console_text);
536 HLock ((Handle) text);
537 startpos = (*console_text)->selStart;
538 endpos = (*console_text)->selEnd;
539 if (startpos != endpos)
540 {
541 strncpy (commandbuf + 1, *text + startpos, endpos - startpos);
542 commandbuf[1 + endpos - startpos] = 0;
543 command = commandbuf + 1;
544 }
545 else
546 {
547 for (i = startpos; i > 0; --i)
548 {
549 strncpy (buf, *text + i, 5);
550 buf[5] = 0;
551 if (strncmp (buf, "(gdb)") == 0)
552 break;
553 }
554 if (i > 0)
555 {
556 strncpy (commandbuf + 1, *text + i + 5, startpos - i);
557 commandbuf[1 + startpos - i] = '\0';
558 }
559 else
560 {
561 SysBeep (20);
562 commandbuf[1] = '\0';
563 }
564 command = commandbuf + 1;
565 }
566 HUnlock ((Handle) text);
567 commandbuf[0] = strlen(command);
568 DebugStr(commandbuf);
569
570 /* Insert a newline and redraw before doing the command. */
571 buf[0] = '\015';
572 TEInsert (buf, 1, console_text);
573 TESetSelect (100000, 100000, console_text);
574 draw_console ();
575
576 execute_command (commandbuf, 0);
577 bpstat_do_actions (&stop_bpstat);
578 }
579 else if (0 /* editing chars... */)
580 {
581 }
582 else
583 {
584 /* A self-inserting character. */
585 buf[0] = key;
586 TEInsert (buf, 1, console_text);
587 TESetSelect (100000, 100000, console_text);
588 draw_console ();
589 }
590 }
591
592 draw_console ()
593 {
594 GrafPtr oldport;
595
596 GetPort (&oldport);
597 SetPort (console_window);
598 TEUpdate (&(console_window->portRect), console_text);
599 SetPort (oldport);
600 /* adjust_help_scrollbar(); */
601 }
602
603 /* Cause an update of a window's entire contents. */
604
605 force_update (win)
606 WindowPtr win;
607 {
608 GrafPtr oldport;
609
610 if (win == nil) return;
611 GetPort (&oldport);
612 SetPort (win);
613 EraseRect (&win->portRect);
614 InvalRect (&win->portRect);
615 SetPort (oldport);
616 }
617
618 adjust_console_scrollbars ()
619 {
620 int lines, newmax, value;
621
622 lines = (*console_text)->nLines;
623 newmax = lines - (((*console_text)->viewRect.bottom - (*console_text)->viewRect.top)
624 / (*console_text)->lineHeight);
625 if (newmax < 0) newmax = 0;
626 SetCtlMax(console_v_scrollbar, newmax);
627 value = ((*console_text)->viewRect.top - (*console_text)->destRect.top)
628 / (*console_text)->lineHeight;
629 SetCtlValue(console_v_scrollbar, value);
630 }
This page took 0.04179 seconds and 5 git commands to generate.