]>
Commit | Line | Data |
---|---|---|
939baabe SS |
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 | ||
a6b26c44 SS |
23 | #include "readline.h" |
24 | #include "history.h" | |
25 | ||
939baabe SS |
26 | #include <Values.h> |
27 | #include <Types.h> | |
28 | #include <Resources.h> | |
29 | #include <QuickDraw.h> | |
30 | #include <Fonts.h> | |
31 | #include <Events.h> | |
32 | #include <Windows.h> | |
33 | #include <Menus.h> | |
34 | #include <TextEdit.h> | |
35 | #include <Dialogs.h> | |
36 | #include <Desk.h> | |
37 | #include <ToolUtils.h> | |
38 | #include <Memory.h> | |
39 | #include <SegLoad.h> | |
40 | #include <Files.h> | |
41 | #include <Folders.h> | |
42 | #include <OSUtils.h> | |
43 | #include <OSEvents.h> | |
44 | #include <DiskInit.h> | |
45 | #include <Packages.h> | |
46 | #include <Traps.h> | |
47 | #include <Lists.h> | |
48 | #include <GestaltEqu.h> | |
49 | #include <PPCToolbox.h> | |
50 | #include <AppleEvents.h> | |
51 | #include <StandardFile.h> | |
52 | #include <Sound.h> | |
53 | ||
54 | #ifdef MPW | |
55 | #define QD(whatever) (qd.##whatever) | |
56 | #define QDPat(whatever) (&(qd.##whatever)) | |
57 | #endif | |
58 | ||
59 | #ifdef THINK_C | |
60 | #define QD(whatever) (whatever) | |
61 | #endif | |
62 | ||
63 | #define p2c(pstr,cbuf) \ | |
64 | strncpy(cbuf, ((char *) (pstr) + 1), pstr[0]); \ | |
65 | cbuf[pstr[0]] = '\0'; | |
66 | ||
67 | #define pascalify(STR) \ | |
68 | sprintf(tmpbuf, " %s", STR); \ | |
69 | tmpbuf[0] = strlen(STR); | |
70 | ||
71 | #include "gdbcmd.h" | |
72 | #include "call-cmds.h" | |
73 | #include "symtab.h" | |
74 | #include "inferior.h" | |
75 | #include "signals.h" | |
76 | #include "target.h" | |
77 | #include "breakpoint.h" | |
78 | #include "gdbtypes.h" | |
79 | #include "expression.h" | |
80 | #include "language.h" | |
939baabe SS |
81 | |
82 | #include "mac-defs.h" | |
83 | ||
a6b26c44 SS |
84 | int mac_app; |
85 | ||
939baabe SS |
86 | int useWNE; |
87 | ||
88 | int hasColorQD; | |
89 | ||
90 | int inbackground; | |
91 | ||
92 | Rect dragrect = { -32000, -32000, 32000, 32000 }; | |
93 | Rect sizerect; | |
94 | ||
95 | int sbarwid = 15; | |
96 | ||
97 | /* Globals for the console window. */ | |
98 | ||
99 | WindowPtr console_window; | |
100 | ||
101 | ControlHandle console_v_scrollbar; | |
102 | ||
103 | Rect console_v_scroll_rect; | |
104 | ||
105 | TEHandle console_text; | |
106 | ||
107 | Rect console_text_rect; | |
108 | ||
a6b26c44 SS |
109 | /* This will go away eventually. */ |
110 | gdb_has_a_terminal () { return 1; } | |
111 | ||
112 | ||
939baabe SS |
113 | mac_init () |
114 | { | |
115 | SysEnvRec se; | |
116 | int eventloopdone = 0; | |
117 | Boolean gotevent; | |
118 | Point mouse; | |
119 | EventRecord event; | |
120 | WindowPtr win; | |
121 | RgnHandle cursorRgn; | |
122 | int i; | |
123 | Handle menubar; | |
124 | MenuHandle menu; | |
125 | ||
126 | /* Do the standard Mac environment setup. */ | |
127 | InitGraf (&QD (thePort)); | |
128 | InitFonts (); | |
129 | FlushEvents (everyEvent, 0); | |
130 | InitWindows (); | |
131 | InitMenus (); | |
132 | TEInit (); | |
133 | InitDialogs (NULL); | |
134 | InitCursor (); | |
135 | ||
136 | /* Color Quickdraw is different from Classic QD. */ | |
137 | SysEnvirons(2, &se); | |
138 | hasColorQD = se.hasColorQD; | |
139 | ||
140 | sizerect.top = 50; | |
141 | sizerect.left = 50; | |
142 | sizerect.bottom = 1000; | |
143 | sizerect.right = 1000; | |
144 | #if 0 | |
145 | sizerect.bottom = screenBits.bounds.bottom - screenBits.bounds.top; | |
146 | sizerect.right = screenBits.bounds.right - screenBits.bounds.left; | |
147 | #endif | |
148 | ||
149 | /* Set up the menus. */ | |
150 | menubar = GetNewMBar (mbMain); | |
151 | SetMenuBar (menubar); | |
152 | /* Add the DAs etc as usual. */ | |
153 | menu = GetMHandle (mApple); | |
154 | if (menu != nil) { | |
155 | AddResMenu (menu, 'DRVR'); | |
156 | } | |
157 | DrawMenuBar (); | |
158 | ||
159 | /* Create the main window we're going to play in. */ | |
160 | if (hasColorQD) | |
161 | console_window = GetNewCWindow (wConsole, NULL, (WindowPtr) -1L); | |
162 | else | |
163 | console_window = GetNewWindow (wConsole, NULL, (WindowPtr) -1L); | |
164 | ||
a6b26c44 | 165 | if (0) DebugStr("\pnear beginning"); |
939baabe SS |
166 | SetPort (console_window); |
167 | console_text_rect = console_window->portRect; | |
168 | console_text_rect.bottom -= sbarwid - 1; | |
169 | console_text_rect.right -= sbarwid - 1; | |
170 | console_text = TENew (&console_text_rect, &console_text_rect); | |
171 | TESetSelect (0, 32767, console_text); | |
172 | TEDelete (console_text); | |
173 | TEInsert ("(gdb)", strlen("(gdb)"), console_text); | |
174 | ||
175 | console_v_scroll_rect = console_window->portRect; | |
176 | console_v_scroll_rect.bottom -= sbarwid - 1; | |
177 | console_v_scroll_rect.left = console_v_scroll_rect.right - sbarwid; | |
178 | console_v_scrollbar = | |
179 | NewControl (console_window, &console_v_scroll_rect, | |
180 | "\p", 1, 0, 0, 0, scrollBarProc, 0L); | |
181 | ||
182 | ShowWindow (console_window); | |
183 | SelectWindow (console_window); | |
184 | /* force_update (console_window); */ | |
185 | ||
186 | return 1; | |
187 | } | |
188 | ||
189 | mac_command_loop() | |
190 | { | |
191 | SysEnvRec se; | |
192 | int eventloopdone = 0; | |
193 | Boolean gotevent; | |
194 | Point mouse; | |
195 | EventRecord event; | |
196 | WindowPtr win; | |
197 | RgnHandle cursorRgn; | |
198 | int i; | |
199 | Handle menubar; | |
200 | MenuHandle menu; | |
201 | ||
202 | /* Figure out if the WaitNextEvent Trap is available. */ | |
203 | useWNE = | |
204 | (NGetTrapAddress (0x60, ToolTrap) != NGetTrapAddress (0x9f, ToolTrap)); | |
205 | /* Pass WNE an empty region the 1st time thru. */ | |
206 | cursorRgn = NewRgn (); | |
207 | /* Go into the main event-handling loop. */ | |
208 | while (!eventloopdone) | |
209 | { | |
210 | /* Use WaitNextEvent if it is available, otherwise GetNextEvent. */ | |
211 | if (useWNE) | |
212 | { | |
213 | get_global_mouse (&mouse); | |
214 | adjust_cursor (mouse, cursorRgn); | |
215 | gotevent = WaitNextEvent (everyEvent, &event, 0L, cursorRgn); | |
216 | } | |
217 | else | |
218 | { | |
219 | SystemTask (); | |
220 | gotevent = GetNextEvent (everyEvent, &event); | |
221 | } | |
222 | /* First decide if the event is for a dialog or is just any old event. */ | |
223 | if (FrontWindow () != nil && IsDialogEvent (&event)) | |
224 | { | |
225 | short itemhit; | |
226 | DialogPtr dialog; | |
227 | ||
228 | /* Handle all the modeless dialogs here. */ | |
229 | if (DialogSelect (&event, &dialog, &itemhit)) | |
230 | { | |
231 | } | |
232 | } | |
233 | else if (gotevent) | |
234 | { | |
235 | /* Make sure we have the right cursor before handling the event. */ | |
236 | adjust_cursor (event.where, cursorRgn); | |
237 | do_event (&event); | |
238 | } | |
239 | } | |
240 | } | |
241 | ||
242 | get_global_mouse (mouse) | |
243 | Point *mouse; | |
244 | { | |
245 | EventRecord evt; | |
246 | ||
247 | OSEventAvail (0, &evt); | |
248 | *mouse = evt.where; | |
249 | } | |
250 | ||
251 | adjust_cursor (mouse, region) | |
252 | Point mouse; | |
253 | RgnHandle region; | |
254 | { | |
255 | } | |
256 | ||
257 | /* Decipher an event, maybe do something with it. */ | |
258 | ||
259 | do_event (evt) | |
260 | EventRecord *evt; | |
261 | { | |
262 | short part, err, rslt = 0; | |
263 | WindowPtr win; | |
264 | Boolean hit; | |
265 | char key; | |
266 | Point pnt; | |
267 | ||
268 | switch (evt->what) | |
269 | { | |
270 | case mouseDown: | |
271 | /* See if the click happened in a special part of the screen. */ | |
272 | part = FindWindow (evt->where, &win); | |
273 | switch (part) | |
274 | { | |
275 | case inMenuBar: | |
276 | adjust_menus (); | |
277 | do_menu_command (MenuSelect (evt->where)); | |
278 | break; | |
279 | case inSysWindow: | |
280 | SystemClick (evt, win); | |
281 | break; | |
282 | case inContent: | |
283 | if (win != FrontWindow ()) | |
284 | { | |
285 | /* Bring the clicked-on window to the front. */ | |
286 | SelectWindow (win); | |
287 | /* Fix the menu to match the new front window. */ | |
288 | adjust_menus (); | |
289 | /* We always want to discard the event now, since clicks in a | |
290 | windows are often irreversible actions. */ | |
291 | } else | |
292 | /* Mouse clicks in the front window do something useful. */ | |
293 | do_mouse_down (win, evt); | |
294 | break; | |
295 | case inDrag: | |
296 | /* Standard drag behavior, no tricks necessary. */ | |
297 | DragWindow (win, evt->where, &dragrect); | |
298 | break; | |
299 | case inGrow: | |
300 | grow_window (win, evt->where); | |
301 | break; | |
302 | case inZoomIn: | |
303 | case inZoomOut: | |
304 | zoom_window (win, evt->where, part); | |
305 | break; | |
306 | case inGoAway: | |
307 | close_window (win); | |
308 | break; | |
309 | } | |
310 | break; | |
311 | case keyDown: | |
312 | case autoKey: | |
313 | key = evt->message & charCodeMask; | |
314 | /* Check for menukey equivalents. */ | |
315 | if (evt->modifiers & cmdKey) | |
316 | { | |
317 | if (evt->what == keyDown) | |
318 | { | |
319 | adjust_menus (); | |
320 | do_menu_command (MenuKey (key)); | |
321 | } | |
322 | } | |
323 | else | |
324 | { | |
325 | if (evt->what == keyDown) | |
326 | { | |
327 | /* Random keypress, interpret it. */ | |
328 | do_keyboard_command (key); | |
329 | } | |
330 | } | |
331 | break; | |
332 | case activateEvt: | |
333 | activate_window ((WindowPtr) evt->message, evt->modifiers & activeFlag); | |
334 | break; | |
335 | case updateEvt: | |
336 | update_window ((WindowPtr) evt->message); | |
337 | break; | |
338 | case diskEvt: | |
339 | /* Call DIBadMount in response to a diskEvt, so that the user can format | |
340 | a floppy. (from DTS Sample) */ | |
341 | if (HiWord (evt->message) != noErr) | |
342 | { | |
343 | SetPt (&pnt, 50, 50); | |
344 | err = DIBadMount (pnt, evt->message); | |
345 | } | |
346 | break; | |
347 | case app4Evt: | |
348 | /* Grab only a single byte. */ | |
349 | switch ((evt->message >> 24) & 0xFF) | |
350 | { | |
351 | case 0xfa: | |
352 | break; | |
353 | case 1: | |
354 | inbackground = !(evt->message & 1); | |
355 | activate_window (FrontWindow (), !inbackground); | |
356 | break; | |
357 | } | |
358 | break; | |
359 | case kHighLevelEvent: | |
360 | AEProcessAppleEvent (evt); | |
361 | break; | |
362 | case nullEvent: | |
363 | rslt = 1; | |
364 | break; | |
365 | default: | |
366 | break; | |
367 | } | |
368 | return rslt; | |
369 | } | |
370 | ||
371 | grow_window (win, where) | |
372 | WindowPtr win; | |
373 | Point where; | |
374 | { | |
375 | long winsize; | |
376 | int h, v; | |
377 | GrafPtr oldport; | |
378 | ||
379 | winsize = GrowWindow (win, where, &sizerect); | |
380 | if (winsize != 0) | |
381 | { | |
382 | GetPort (&oldport); | |
383 | SetPort (win); | |
384 | EraseRect (&win->portRect); | |
385 | h = LoWord (winsize); | |
386 | v = HiWord (winsize); | |
387 | SizeWindow (win, h, v, 1); | |
388 | if (win == console_window) | |
389 | { | |
390 | MoveControl(console_v_scrollbar, h - sbarwid, 0); | |
391 | SizeControl(console_v_scrollbar, sbarwid + 1, v - sbarwid + 1); | |
392 | } | |
393 | InvalRect (&win->portRect); | |
394 | SetPort (oldport); | |
395 | } | |
396 | } | |
397 | ||
398 | zoom_window (win, where, part) | |
399 | WindowPtr win; | |
400 | Point where; | |
401 | short part; | |
402 | { | |
403 | } | |
404 | ||
405 | close_window (win) | |
406 | WindowPtr win; | |
407 | { | |
408 | } | |
409 | ||
410 | do_mouse_down (win, event) | |
411 | WindowPtr win; | |
412 | EventRecord *event; | |
413 | { | |
414 | short part; | |
415 | Point mouse; | |
416 | ControlHandle control; | |
417 | ||
418 | if (1 /*is_app_window(win)*/) | |
419 | { | |
420 | SetPort (win); | |
421 | mouse = event->where; | |
422 | GlobalToLocal (&mouse); | |
423 | part = FindControl(mouse, win, &control); | |
424 | if (control == console_v_scrollbar) | |
425 | { | |
426 | SysBeep(20); | |
427 | } | |
428 | else | |
429 | { | |
430 | TEClick (mouse, 0, console_text); | |
431 | } | |
432 | } | |
433 | } | |
434 | ||
435 | activate_window (win, activate) | |
436 | WindowPtr win; | |
437 | int activate; | |
438 | { | |
439 | if (win == nil) return; | |
440 | /* It's convenient to make the activated window also be the | |
441 | current GrafPort. */ | |
442 | if (activate) | |
443 | SetPort(win); | |
444 | /* Activate the console window's scrollbar. */ | |
445 | if (win == console_window) | |
446 | HiliteControl (console_v_scrollbar, (activate ? 0 : 255)); | |
447 | } | |
448 | ||
449 | update_window (win) | |
450 | WindowPtr win; | |
451 | { | |
452 | int controls = 1, growbox = 0; | |
453 | GrafPtr oldport; | |
454 | ||
455 | /* Set the updating window to be the current grafport. */ | |
456 | GetPort (&oldport); | |
457 | SetPort (win); | |
458 | /* recalc_depths(); */ | |
459 | BeginUpdate (win); | |
460 | if (win == console_window) | |
461 | { | |
462 | draw_console (); | |
463 | controls = 1; | |
464 | growbox = 1; | |
465 | } | |
466 | if (controls) | |
467 | UpdateControls (win, win->visRgn); | |
468 | if (growbox) | |
469 | DrawGrowIcon (win); | |
470 | EndUpdate (win); | |
471 | SetPort (oldport); | |
472 | } | |
473 | ||
474 | adjust_menus () | |
475 | { | |
476 | } | |
477 | ||
478 | do_menu_command (which) | |
479 | long which; | |
480 | { | |
481 | short menuid, menuitem; | |
482 | short itemHit; | |
483 | Str255 daname; | |
484 | short daRefNum; | |
485 | Boolean handledbyda; | |
486 | WindowPtr win; | |
487 | short ditem; | |
488 | int i; | |
489 | ||
490 | menuid = HiWord (which); | |
491 | menuitem = LoWord (which); | |
492 | switch (menuid) | |
493 | { | |
494 | case mApple: | |
495 | switch (menuitem) | |
496 | { | |
497 | case miAbout: | |
498 | /* Alert(aAbout, nil); */ | |
499 | break; | |
500 | default: | |
501 | GetItem (GetMHandle (mApple), menuitem, daname); | |
502 | daRefNum = OpenDeskAcc (daname); | |
503 | } | |
504 | break; | |
505 | case mFile: | |
506 | switch (menuitem) | |
507 | { | |
508 | case miFileQuit: | |
509 | ExitToShell (); | |
510 | break; | |
511 | } | |
512 | break; | |
513 | case mEdit: | |
514 | /* handledbyda = SystemEdit(menuitem-1); */ | |
515 | switch (menuitem) | |
516 | { | |
517 | case miEditCut: | |
518 | break; | |
519 | case miEditCopy: | |
520 | break; | |
521 | case miEditPaste: | |
522 | break; | |
523 | case miEditClear: | |
524 | break; | |
525 | } | |
526 | break; | |
527 | } | |
528 | HiliteMenu (0); | |
529 | } | |
530 | ||
531 | char commandbuf[1000]; | |
532 | ||
533 | do_keyboard_command (key) | |
534 | char key; | |
535 | { | |
536 | int startpos, endpos, i; | |
a6b26c44 | 537 | char *last_newline; |
939baabe SS |
538 | char buf[10], *text_str, *command; |
539 | CharsHandle text; | |
540 | ||
541 | if (key == '\015' || key == '\003') | |
542 | { | |
543 | /* (should) Interpret the line as a command. */ | |
544 | text = TEGetText (console_text); | |
545 | HLock ((Handle) text); | |
546 | startpos = (*console_text)->selStart; | |
547 | endpos = (*console_text)->selEnd; | |
548 | if (startpos != endpos) | |
549 | { | |
550 | strncpy (commandbuf + 1, *text + startpos, endpos - startpos); | |
551 | commandbuf[1 + endpos - startpos] = 0; | |
552 | command = commandbuf + 1; | |
553 | } | |
554 | else | |
555 | { | |
a6b26c44 SS |
556 | DebugStr("\plooking for command"); |
557 | last_newline = strrchr(*text+startpos, '\n'); | |
558 | if (last_newline) | |
939baabe | 559 | { |
a6b26c44 SS |
560 | strncpy (commandbuf + 1, |
561 | last_newline, | |
562 | last_newline - (*text+startpos)); | |
563 | commandbuf[1 + last_newline - (*text+startpos)] = 0; | |
564 | command = commandbuf + 1; | |
939baabe SS |
565 | } |
566 | else | |
567 | { | |
a6b26c44 | 568 | command = "help"; |
939baabe | 569 | } |
939baabe SS |
570 | } |
571 | HUnlock ((Handle) text); | |
572 | commandbuf[0] = strlen(command); | |
573 | DebugStr(commandbuf); | |
574 | ||
575 | /* Insert a newline and redraw before doing the command. */ | |
576 | buf[0] = '\015'; | |
577 | TEInsert (buf, 1, console_text); | |
578 | TESetSelect (100000, 100000, console_text); | |
579 | draw_console (); | |
580 | ||
581 | execute_command (commandbuf, 0); | |
582 | bpstat_do_actions (&stop_bpstat); | |
583 | } | |
584 | else if (0 /* editing chars... */) | |
585 | { | |
586 | } | |
587 | else | |
588 | { | |
589 | /* A self-inserting character. */ | |
590 | buf[0] = key; | |
591 | TEInsert (buf, 1, console_text); | |
592 | TESetSelect (100000, 100000, console_text); | |
593 | draw_console (); | |
594 | } | |
595 | } | |
596 | ||
597 | draw_console () | |
598 | { | |
599 | GrafPtr oldport; | |
600 | ||
601 | GetPort (&oldport); | |
602 | SetPort (console_window); | |
603 | TEUpdate (&(console_window->portRect), console_text); | |
604 | SetPort (oldport); | |
605 | /* adjust_help_scrollbar(); */ | |
606 | } | |
607 | ||
608 | /* Cause an update of a window's entire contents. */ | |
609 | ||
610 | force_update (win) | |
611 | WindowPtr win; | |
612 | { | |
613 | GrafPtr oldport; | |
614 | ||
615 | if (win == nil) return; | |
616 | GetPort (&oldport); | |
617 | SetPort (win); | |
618 | EraseRect (&win->portRect); | |
619 | InvalRect (&win->portRect); | |
620 | SetPort (oldport); | |
621 | } | |
622 | ||
623 | adjust_console_scrollbars () | |
624 | { | |
625 | int lines, newmax, value; | |
626 | ||
627 | lines = (*console_text)->nLines; | |
628 | newmax = lines - (((*console_text)->viewRect.bottom - (*console_text)->viewRect.top) | |
629 | / (*console_text)->lineHeight); | |
630 | if (newmax < 0) newmax = 0; | |
a6b26c44 | 631 | SetCtlMax (console_v_scrollbar, newmax); |
939baabe SS |
632 | value = ((*console_text)->viewRect.top - (*console_text)->destRect.top) |
633 | / (*console_text)->lineHeight; | |
a6b26c44 | 634 | SetCtlValue (console_v_scrollbar, value); |
939baabe | 635 | } |
a6b26c44 SS |
636 | |
637 | /* Readline substitute. */ | |
638 | ||
639 | char * | |
640 | readline (char *prrompt) | |
641 | { | |
642 | return gdb_readline (prrompt); | |
643 | } | |
644 | ||
645 | char *rl_completer_word_break_characters; | |
646 | ||
647 | char *rl_completer_quote_characters; | |
648 | ||
649 | int (*rl_completion_entry_function) (); | |
650 | ||
651 | int rl_point; | |
652 | ||
653 | char *rl_line_buffer; | |
654 | ||
655 | char *rl_readline_name; | |
656 | ||
657 | /* History substitute. */ | |
658 | ||
659 | void | |
660 | add_history (char *buf) | |
661 | { | |
662 | } | |
663 | ||
664 | void | |
665 | stifle_history (int n) | |
666 | { | |
667 | } | |
668 | ||
669 | int | |
670 | unstifle_history () | |
671 | { | |
672 | } | |
673 | ||
674 | int | |
675 | read_history (char *name) | |
676 | { | |
677 | } | |
678 | ||
679 | int | |
680 | write_history (char *name) | |
681 | { | |
682 | } | |
683 | ||
684 | int | |
685 | history_expand (char *x, char **y) | |
686 | { | |
687 | } | |
688 | ||
689 | extern HIST_ENTRY * | |
690 | history_get (int xxx) | |
691 | { | |
692 | return NULL; | |
693 | } | |
694 | ||
695 | int history_base; | |
696 | ||
697 | char * | |
698 | filename_completion_function (char *text, char *name) | |
699 | { | |
700 | return "?"; | |
701 | } | |
702 | ||
703 | char * | |
704 | tilde_expand (char *str) | |
705 | { | |
706 | return strsave (str); | |
707 | } | |
708 | ||
709 | /* Modified versions of standard I/O. */ | |
710 | ||
711 | #include <stdarg.h> | |
712 | ||
713 | #undef fprintf | |
714 | ||
715 | int | |
716 | hacked_fprintf (FILE *fp, const char *fmt, ...) | |
717 | { | |
718 | int ret; | |
719 | va_list ap; | |
720 | ||
721 | va_start (ap, fmt); | |
722 | if (mac_app && (fp == stdout || fp == stderr)) | |
723 | { | |
724 | char buf[1000]; | |
725 | ||
726 | ret = vsprintf(buf, fmt, ap); | |
727 | TEInsert (buf, strlen(buf), console_text); | |
728 | TESetSelect (100000, 100000, console_text); | |
729 | draw_console (); | |
730 | } | |
731 | else | |
732 | ret = vfprintf (fp, fmt, ap); | |
733 | va_end (ap); | |
734 | return ret; | |
735 | } | |
736 | ||
737 | #undef printf | |
738 | ||
739 | int | |
740 | hacked_printf (const char *fmt, ...) | |
741 | { | |
742 | int ret; | |
743 | va_list ap; | |
744 | ||
745 | va_start (ap, fmt); | |
746 | if (mac_app) | |
747 | { | |
748 | ret = hacked_vfprintf(stdout, fmt, ap); | |
749 | } | |
750 | else | |
751 | ret = vfprintf (stdout, fmt, ap); | |
752 | va_end (ap); | |
753 | return ret; | |
754 | } | |
755 | ||
756 | #undef vfprintf | |
757 | ||
758 | int | |
759 | hacked_vfprintf (FILE *fp, const char *format, va_list args) | |
760 | { | |
761 | if (mac_app && (fp == stdout || fp == stderr)) | |
762 | { | |
763 | char buf[1000]; | |
764 | int ret; | |
765 | ||
766 | ret = vsprintf(buf, format, args); | |
767 | TEInsert (buf, strlen(buf), console_text); | |
768 | TESetSelect (100000, 100000, console_text); | |
769 | draw_console (); | |
770 | return ret; | |
771 | } | |
772 | else | |
773 | return vfprintf (fp, format, args); | |
774 | } | |
775 | ||
776 | #undef fputs | |
777 | ||
778 | hacked_fputs (const char *s, FILE *fp) | |
779 | { | |
780 | if (mac_app && (fp == stdout || fp == stderr)) | |
781 | { | |
782 | TEInsert (s, strlen(s), console_text); | |
783 | TESetSelect (100000, 100000, console_text); | |
784 | draw_console (); | |
785 | return 0; | |
786 | } | |
787 | else | |
788 | return fputs (s, fp); | |
789 | } | |
790 | ||
791 | #undef fputc | |
792 | ||
793 | hacked_fputc (const char c, FILE *fp) | |
794 | { | |
795 | if (mac_app && (fp == stdout || fp == stderr)) | |
796 | { | |
797 | char buf[2]; | |
798 | ||
799 | buf[0] = c; | |
800 | TEInsert (buf, 1, console_text); | |
801 | TESetSelect (100000, 100000, console_text); | |
802 | draw_console (); | |
803 | return 0; | |
804 | } | |
805 | else | |
806 | return fputc (c, fp); | |
807 | } | |
808 | ||
809 | #undef putc | |
810 | ||
811 | hacked_putc (const char c, FILE *fp) | |
812 | { | |
813 | if (mac_app && (fp == stdout || fp == stderr)) | |
814 | { | |
815 | char buf[2]; | |
816 | ||
817 | buf[0] = c; | |
818 | TEInsert (buf, 1, console_text); | |
819 | TESetSelect (100000, 100000, console_text); | |
820 | draw_console (); | |
821 | } | |
822 | else | |
823 | return fputc (c, fp); | |
824 | } | |
825 | ||
826 | #undef fflush | |
827 | ||
828 | hacked_fflush (FILE *fp) | |
829 | { | |
830 | if (mac_app && (fp == stdout || fp == stderr)) | |
831 | return 0; | |
832 | return fflush (fp); | |
833 | } | |
834 |