Commit | Line | Data |
---|---|---|
f377b406 SC |
1 | /* General functions for the WDB TUI. |
2 | Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | |
3 | Contributed by Hewlett-Packard Company. | |
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., 59 Temple Place - Suite 330, | |
20 | Boston, MA 02111-1307, USA. */ | |
c906108c SS |
21 | |
22 | #include <stdio.h> | |
23 | #include <stdlib.h> | |
24 | #include <ctype.h> | |
25 | #include <malloc.h> | |
c906108c SS |
26 | #ifdef HAVE_TERM_H |
27 | #include <term.h> | |
28 | #endif | |
29 | #include <signal.h> | |
30 | #include <fcntl.h> | |
31 | #include <termio.h> | |
32 | #include <setjmp.h> | |
33 | #include "defs.h" | |
34 | #include "gdbcmd.h" | |
35 | #include "tui.h" | |
36 | #include "tuiData.h" | |
37 | #include "tuiLayout.h" | |
38 | #include "tuiIO.h" | |
39 | #include "tuiRegs.h" | |
40 | #include "tuiWin.h" | |
41 | ||
42 | /* The Solaris header files seem to provide no declaration for this at | |
43 | all when __STDC__ is defined. This shouldn't conflict with | |
44 | anything. */ | |
45 | extern char *tgoto (); | |
46 | ||
47 | /*********************** | |
48 | ** Local Definitions | |
49 | ************************/ | |
50 | #define FILEDES 2 | |
51 | /* Solaris <sys/termios.h> defines CTRL. */ | |
52 | #ifndef CTRL | |
53 | #define CTRL(x) (x & ~0140) | |
54 | #endif | |
55 | #define CHK(val, dft) (val<=0 ? dft : val) | |
56 | ||
57 | #define TOGGLE_USAGE "Usage:toggle breakpoints" | |
58 | #define TUI_TOGGLE_USAGE "Usage:\ttoggle $fregs\n\ttoggle breakpoints" | |
59 | ||
60 | /***************************** | |
61 | ** Local static forward decls | |
62 | ******************************/ | |
a14ed312 KB |
63 | static void _tuiReset (void); |
64 | static void _toggle_command (char *, int); | |
65 | static void _tui_vToggle_command (va_list); | |
c906108c SS |
66 | |
67 | ||
68 | ||
69 | /*********************** | |
70 | ** Public Functions | |
71 | ************************/ | |
72 | ||
73 | /* | |
c5aa993b JM |
74 | ** tuiInit(). |
75 | */ | |
c906108c | 76 | void |
c906108c | 77 | tuiInit (char *argv0) |
c906108c SS |
78 | { |
79 | extern void init_page_info (); | |
a14ed312 | 80 | extern void initialize_tui_files (void); |
c906108c SS |
81 | |
82 | initialize_tui_files (); | |
83 | initializeStaticData (); | |
84 | initscr (); | |
85 | refresh (); | |
86 | setTermHeightTo (LINES); | |
87 | setTermWidthTo (COLS); | |
88 | tuiInitWindows (); | |
89 | wrefresh (cmdWin->generic.handle); | |
90 | init_page_info (); | |
91 | /* Don't hook debugger output if doing command-window | |
92 | * the XDB way. However, one thing we do want to do in | |
93 | * XDB style is set up the scrolling region to be | |
94 | * the bottom of the screen (tuiTermUnsetup()). | |
c5aa993b | 95 | */ |
c906108c | 96 | fputs_unfiltered_hook = NULL; |
c906108c | 97 | rl_initialize (); /* need readline initialization to |
c5aa993b JM |
98 | * create termcap sequences |
99 | */ | |
c906108c SS |
100 | tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch); |
101 | ||
102 | return; | |
103 | } /* tuiInit */ | |
104 | ||
105 | ||
106 | /* | |
c5aa993b JM |
107 | ** tuiInitWindows(). |
108 | */ | |
c906108c | 109 | void |
c906108c | 110 | tuiInitWindows (void) |
c906108c SS |
111 | { |
112 | TuiWinType type; | |
113 | ||
114 | tuiSetLocatorContent (0); | |
115 | showLayout (SRC_COMMAND); | |
116 | keypad (cmdWin->generic.handle, TRUE); | |
117 | echo (); | |
118 | crmode (); | |
119 | nl (); | |
120 | tuiSetWinFocusTo (srcWin); | |
121 | ||
122 | return; | |
123 | } /* tuiInitWindows */ | |
124 | ||
125 | ||
126 | /* | |
c5aa993b JM |
127 | ** tuiCleanUp(). |
128 | ** Kill signal handler and cleanup termination method | |
129 | */ | |
c906108c | 130 | void |
c906108c | 131 | tuiResetScreen (void) |
c906108c SS |
132 | { |
133 | TuiWinType type = SRC_WIN; | |
134 | ||
135 | keypad (cmdWin->generic.handle, FALSE); | |
136 | for (; type < MAX_MAJOR_WINDOWS; type++) | |
137 | { | |
138 | if (m_winPtrNotNull (winList[type]) && | |
139 | winList[type]->generic.type != UNDEFINED_WIN && | |
140 | !winList[type]->generic.isVisible) | |
141 | tuiDelWindow (winList[type]); | |
142 | } | |
143 | endwin (); | |
144 | initscr (); | |
145 | refresh (); | |
146 | echo (); | |
147 | crmode (); | |
148 | nl (); | |
149 | ||
150 | return; | |
151 | } /* tuiResetScreen */ | |
152 | ||
153 | ||
154 | /* | |
c5aa993b JM |
155 | ** tuiCleanUp(). |
156 | ** Kill signal handler and cleanup termination method | |
157 | */ | |
c906108c | 158 | void |
c906108c | 159 | tuiCleanUp (void) |
c906108c SS |
160 | { |
161 | char *buffer; | |
162 | extern char *term_cursor_move; | |
163 | ||
164 | signal (SIGINT, SIG_IGN); | |
165 | tuiTermSetup (0); /* Restore scrolling region to whole screen */ | |
166 | keypad (cmdWin->generic.handle, FALSE); | |
167 | freeAllWindows (); | |
168 | endwin (); | |
169 | buffer = tgoto (term_cursor_move, 0, termHeight ()); | |
170 | tputs (buffer, 1, putchar); | |
171 | _tuiReset (); | |
172 | ||
173 | return; | |
174 | } /* tuiCleanUp */ | |
175 | ||
176 | ||
177 | /* | |
c5aa993b JM |
178 | ** tuiError(). |
179 | */ | |
c906108c | 180 | void |
eca6576c | 181 | tuiError (char *string, int exitGdb) |
c906108c SS |
182 | { |
183 | puts_unfiltered (string); | |
184 | if (exitGdb) | |
185 | { | |
186 | tuiCleanUp (); | |
187 | exit (-1); | |
188 | } | |
189 | ||
190 | return; | |
191 | } /* tuiError */ | |
192 | ||
193 | ||
194 | /* | |
c5aa993b JM |
195 | ** tui_vError() |
196 | ** tuiError with args in a va_list. | |
197 | */ | |
c906108c | 198 | void |
eca6576c | 199 | tui_vError (va_list args) |
c906108c SS |
200 | { |
201 | char *string; | |
202 | int exitGdb; | |
203 | ||
204 | string = va_arg (args, char *); | |
205 | exitGdb = va_arg (args, int); | |
206 | ||
207 | tuiError (string, exitGdb); | |
208 | ||
209 | return; | |
210 | } /* tui_vError */ | |
211 | ||
212 | ||
213 | /* | |
c5aa993b JM |
214 | ** tuiFree() |
215 | ** Wrapper on top of free() to ensure that input address is greater than 0x0 | |
216 | */ | |
c906108c | 217 | void |
eca6576c | 218 | tuiFree (char *ptr) |
c906108c SS |
219 | { |
220 | if (ptr != (char *) NULL) | |
221 | { | |
b8c9b27d | 222 | xfree (ptr); |
c906108c SS |
223 | } |
224 | ||
225 | return; | |
226 | } /* tuiFree */ | |
227 | ||
228 | ||
229 | /* tuiGetLowDisassemblyAddress(). | |
c5aa993b JM |
230 | ** Determine what the low address will be to display in the TUI's |
231 | ** disassembly window. This may or may not be the same as the | |
232 | ** low address input. | |
233 | */ | |
c906108c | 234 | Opaque |
eca6576c | 235 | tuiGetLowDisassemblyAddress (Opaque low, Opaque pc) |
c906108c SS |
236 | { |
237 | int line; | |
238 | Opaque newLow; | |
239 | ||
240 | /* | |
c5aa993b JM |
241 | ** Determine where to start the disassembly so that the pc is about in the |
242 | ** middle of the viewport. | |
243 | */ | |
c906108c SS |
244 | for (line = 0, newLow = pc; |
245 | (newLow > low && | |
246 | line < (tuiDefaultWinViewportHeight (DISASSEM_WIN, | |
247 | DISASSEM_COMMAND) / 2));) | |
248 | { | |
249 | bfd_byte buffer[4]; | |
250 | ||
251 | newLow -= sizeof (bfd_getb32 (buffer)); | |
252 | line++; | |
253 | } | |
254 | ||
255 | return newLow; | |
256 | } /* tuiGetLowDisassemblyAddress */ | |
257 | ||
258 | ||
259 | /* tui_vGetLowDisassemblyAddress(). | |
c5aa993b JM |
260 | ** Determine what the low address will be to display in the TUI's |
261 | ** disassembly window with args in a va_list. | |
262 | */ | |
c906108c | 263 | Opaque |
eca6576c | 264 | tui_vGetLowDisassemblyAddress (va_list args) |
c906108c SS |
265 | { |
266 | int line; | |
267 | Opaque newLow; | |
268 | Opaque low; | |
269 | Opaque pc; | |
270 | ||
271 | low = va_arg (args, Opaque); | |
272 | pc = va_arg (args, Opaque); | |
273 | ||
274 | return (tuiGetLowDisassemblyAddress (low, pc)); | |
275 | ||
276 | } /* tui_vGetLowDisassemblyAddress */ | |
277 | ||
278 | ||
c906108c | 279 | void |
eca6576c | 280 | tui_vSelectSourceSymtab (va_list args) |
c906108c SS |
281 | { |
282 | struct symtab *s = va_arg (args, struct symtab *); | |
283 | ||
284 | select_source_symtab (s); | |
285 | return; | |
286 | } /* tui_vSelectSourceSymtab */ | |
287 | ||
288 | ||
289 | /* | |
c5aa993b JM |
290 | ** _initialize_tui(). |
291 | ** Function to initialize gdb commands, for tui window manipulation. | |
292 | */ | |
c906108c | 293 | void |
fba45db2 | 294 | _initialize_tui (void) |
c906108c SS |
295 | { |
296 | #if 0 | |
297 | if (tui_version) | |
298 | { | |
299 | add_com ("toggle", class_tui, _toggle_command, | |
300 | "Toggle Terminal UI Features\n\ | |
301 | Usage: Toggle $fregs\n\ | |
302 | \tToggles between single and double precision floating point registers.\n"); | |
303 | } | |
304 | #endif | |
305 | char *helpStr; | |
306 | ||
307 | if (tui_version) | |
308 | helpStr = "Toggle Specified Features\n\ | |
309 | Usage:\ttoggle $fregs\n\ttoggle breakpoints"; | |
310 | else | |
311 | helpStr = "Toggle Specified Features\nUsage:toggle breakpoints"; | |
312 | add_abbrev_prefix_cmd ("toggle", | |
313 | class_tui, | |
314 | _toggle_command, | |
315 | helpStr, | |
316 | &togglelist, | |
317 | "toggle ", | |
318 | 1, | |
319 | &cmdlist); | |
c5aa993b | 320 | } /* _initialize_tui */ |
c906108c SS |
321 | |
322 | ||
c906108c | 323 | void |
eca6576c | 324 | strcat_to_buf (char *buf, int buflen, char *itemToAdd) |
c906108c SS |
325 | { |
326 | if (itemToAdd != (char *) NULL && buf != (char *) NULL) | |
327 | { | |
328 | if ((strlen (buf) + strlen (itemToAdd)) <= buflen) | |
329 | strcat (buf, itemToAdd); | |
330 | else | |
331 | strncat (buf, itemToAdd, (buflen - strlen (buf))); | |
332 | } | |
333 | ||
334 | return; | |
335 | } /* strcat_to_buf */ | |
336 | ||
337 | /* VARARGS */ | |
338 | void | |
eca6576c | 339 | strcat_to_buf_with_fmt (char *buf, int bufLen, char *format, ...) |
c906108c SS |
340 | { |
341 | char *linebuffer; | |
342 | struct cleanup *old_cleanups; | |
343 | va_list args; | |
c906108c | 344 | va_start (args, format); |
c906108c | 345 | vasprintf (&linebuffer, format, args); |
b8c9b27d | 346 | old_cleanups = make_cleanup (xfree, linebuffer); |
c906108c SS |
347 | strcat_to_buf (buf, bufLen, linebuffer); |
348 | do_cleanups (old_cleanups); | |
349 | va_end (args); | |
350 | } | |
351 | ||
352 | ||
353 | ||
354 | ||
355 | ||
356 | /*********************** | |
357 | ** Static Functions | |
358 | ************************/ | |
359 | ||
360 | ||
c906108c SS |
361 | |
362 | static void | |
eca6576c | 363 | _toggle_command (char *arg, int fromTTY) |
c906108c SS |
364 | { |
365 | printf_filtered ("Specify feature to toggle.\n%s\n", | |
366 | (tui_version) ? TUI_TOGGLE_USAGE : TOGGLE_USAGE); | |
367 | /* | |
c5aa993b JM |
368 | tuiDo((TuiOpaqueFuncPtr)_Toggle_command, arg, fromTTY); |
369 | */ | |
c906108c SS |
370 | } |
371 | ||
372 | /* | |
c5aa993b JM |
373 | ** _tui_vToggle_command(). |
374 | */ | |
c906108c | 375 | static void |
eca6576c | 376 | _tui_vToggle_command (va_list args) |
c906108c SS |
377 | { |
378 | char *arg; | |
379 | int fromTTY; | |
380 | ||
381 | arg = va_arg (args, char *); | |
382 | ||
383 | if (arg == (char *) NULL) | |
384 | printf_filtered (TOGGLE_USAGE); | |
385 | else | |
386 | { | |
387 | char *ptr = (char *) tuiStrDup (arg); | |
388 | int i; | |
389 | ||
390 | for (i = 0; (ptr[i]); i++) | |
391 | ptr[i] = toupper (arg[i]); | |
392 | ||
0963fc96 | 393 | if (subset_compare (ptr, TUI_FLOAT_REGS_NAME)) |
c906108c | 394 | tuiToggleFloatRegs (); |
0963fc96 | 395 | /* else if (subset_compare(ptr, "ANOTHER TOGGLE OPTION")) |
c5aa993b JM |
396 | ... |
397 | */ | |
c906108c SS |
398 | else |
399 | printf_filtered (TOGGLE_USAGE); | |
400 | tuiFree (ptr); | |
401 | } | |
402 | ||
403 | return; | |
404 | } /* _tuiToggle_command */ | |
405 | ||
406 | ||
407 | static void | |
c906108c | 408 | _tuiReset (void) |
c906108c SS |
409 | { |
410 | struct termio mode; | |
411 | ||
412 | /* | |
c5aa993b JM |
413 | ** reset the teletype mode bits to a sensible state. |
414 | ** Copied tset.c | |
415 | */ | |
c906108c SS |
416 | #if ! defined (USG) && defined (TIOCGETC) |
417 | struct tchars tbuf; | |
418 | #endif /* !USG && TIOCGETC */ | |
419 | #ifdef UCB_NTTY | |
420 | struct ltchars ltc; | |
421 | ||
422 | if (ldisc == NTTYDISC) | |
423 | { | |
424 | ioctl (FILEDES, TIOCGLTC, <c); | |
425 | ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z')); | |
426 | ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y')); | |
427 | ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R')); | |
428 | ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O')); | |
429 | ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W')); | |
430 | ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V')); | |
431 | ioctl (FILEDES, TIOCSLTC, <c); | |
432 | } | |
433 | #endif /* UCB_NTTY */ | |
434 | #ifndef USG | |
435 | #ifdef TIOCGETC | |
436 | ioctl (FILEDES, TIOCGETC, &tbuf); | |
437 | tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?')); | |
438 | tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\')); | |
439 | tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q')); | |
440 | tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S')); | |
441 | tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D')); | |
442 | /* brkc is left alone */ | |
443 | ioctl (FILEDES, TIOCSETC, &tbuf); | |
444 | #endif /* TIOCGETC */ | |
445 | mode.sg_flags &= ~(RAW | |
446 | #ifdef CBREAK | |
447 | | CBREAK | |
448 | #endif /* CBREAK */ | |
449 | | VTDELAY | ALLDELAY); | |
450 | mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP; | |
c5aa993b | 451 | #else /*USG */ |
c906108c SS |
452 | ioctl (FILEDES, TCGETA, &mode); |
453 | mode.c_cc[VINTR] = CHK (mode.c_cc[VINTR], CTRL ('?')); | |
454 | mode.c_cc[VQUIT] = CHK (mode.c_cc[VQUIT], CTRL ('\\')); | |
455 | mode.c_cc[VEOF] = CHK (mode.c_cc[VEOF], CTRL ('D')); | |
456 | ||
457 | mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF); | |
458 | mode.c_iflag |= (BRKINT | ISTRIP | ICRNL | IXON); | |
459 | mode.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL | | |
460 | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY); | |
461 | mode.c_oflag |= (OPOST | ONLCR); | |
462 | mode.c_cflag &= ~(CSIZE | PARODD | CLOCAL); | |
463 | #ifndef hp9000s800 | |
464 | mode.c_cflag |= (CS8 | CREAD); | |
c5aa993b | 465 | #else /*hp9000s800 */ |
c906108c SS |
466 | mode.c_cflag |= (CS8 | CSTOPB | CREAD); |
467 | #endif /* hp9000s800 */ | |
468 | mode.c_lflag &= ~(XCASE | ECHONL | NOFLSH); | |
469 | mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOK); | |
470 | ioctl (FILEDES, TCSETAW, &mode); | |
471 | #endif /* USG */ | |
472 | ||
473 | return; | |
474 | } /* _tuiReset */ |