Commit | Line | Data |
---|---|---|
f377b406 | 1 | /* TUI layout window management. |
f33c6cbf | 2 | |
42a4f53d | 3 | Copyright (C) 1998-2019 Free Software Foundation, Inc. |
f33c6cbf | 4 | |
f377b406 | 5 | Contributed by Hewlett-Packard Company. |
c906108c | 6 | |
f377b406 SC |
7 | This file is part of GDB. |
8 | ||
9 | This program is free software; you can redistribute it and/or modify | |
10 | it under the terms of the GNU General Public License as published by | |
a9762ec7 | 11 | the Free Software Foundation; either version 3 of the License, or |
f377b406 SC |
12 | (at your option) any later version. |
13 | ||
14 | This program is distributed in the hope that it will be useful, | |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | GNU General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU General Public License | |
a9762ec7 | 20 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
c906108c SS |
21 | |
22 | #include "defs.h" | |
957b8b5a | 23 | #include "arch-utils.h" |
c906108c SS |
24 | #include "command.h" |
25 | #include "symtab.h" | |
26 | #include "frame.h" | |
52575520 | 27 | #include "source.h" |
84b1e7c7 | 28 | #include <ctype.h> |
c906108c | 29 | |
d7b2e967 AC |
30 | #include "tui/tui.h" |
31 | #include "tui/tui-data.h" | |
32 | #include "tui/tui-windata.h" | |
33 | #include "tui/tui-wingeneral.h" | |
34 | #include "tui/tui-stack.h" | |
35 | #include "tui/tui-regs.h" | |
36 | #include "tui/tui-win.h" | |
37 | #include "tui/tui-winsource.h" | |
38 | #include "tui/tui-disasm.h" | |
2c0b251b | 39 | #include "tui/tui-layout.h" |
6a83354a | 40 | #include "gdb_curses.h" |
96ec9981 | 41 | |
c906108c SS |
42 | /******************************* |
43 | ** Static Local Decls | |
44 | ********************************/ | |
6ba8e26f | 45 | static void show_layout (enum tui_layout_type); |
08ef48c5 MS |
46 | static void init_gen_win_info (struct tui_gen_win_info *, |
47 | enum tui_win_type, | |
48 | int, int, int, int); | |
49 | static void *init_and_make_win (void *, enum tui_win_type, | |
50 | int, int, int, int, int); | |
6ba8e26f | 51 | static void show_source_or_disasm_and_command (enum tui_layout_type); |
0ed69eda TT |
52 | static struct tui_win_info *make_source_or_disasm_window (enum tui_win_type, |
53 | int, int); | |
82432e10 | 54 | static struct tui_win_info *make_command_window (int, int); |
0ed69eda TT |
55 | static struct tui_win_info *make_source_window (int, int); |
56 | static struct tui_win_info *make_disasm_window (int, int); | |
5b6fe301 | 57 | static void make_data_window (struct tui_win_info **, int, int); |
6ba8e26f AC |
58 | static void show_source_command (void); |
59 | static void show_disasm_command (void); | |
60 | static void show_source_disasm_command (void); | |
61 | static void show_data (enum tui_layout_type); | |
62 | static enum tui_layout_type next_layout (void); | |
63 | static enum tui_layout_type prev_layout (void); | |
0b39b52e | 64 | static void tui_layout_command (const char *, int); |
13274fc3 | 65 | static void extract_display_start_addr (struct gdbarch **, CORE_ADDR *); |
c906108c SS |
66 | |
67 | ||
68 | /*************************************** | |
69 | ** DEFINITIONS | |
70 | ***************************************/ | |
71 | ||
72 | #define LAYOUT_USAGE "Usage: layout prev | next | <layout_name> \n" | |
73 | ||
c7037be1 SC |
74 | /* Show the screen layout defined. */ |
75 | static void | |
6ba8e26f | 76 | show_layout (enum tui_layout_type layout) |
c906108c | 77 | { |
6ba8e26f | 78 | enum tui_layout_type cur_layout = tui_current_layout (); |
c906108c | 79 | |
6ba8e26f | 80 | if (layout != cur_layout) |
c906108c | 81 | { |
ef5eab5a MS |
82 | /* Since the new layout may cause changes in window size, we |
83 | should free the content and reallocate on next display of | |
84 | source/asm. */ | |
dd1abb8c AC |
85 | tui_free_all_source_wins_content (); |
86 | tui_clear_source_windows (); | |
e5908723 MS |
87 | if (layout == SRC_DATA_COMMAND |
88 | || layout == DISASSEM_DATA_COMMAND) | |
c906108c | 89 | { |
6ba8e26f | 90 | show_data (layout); |
6d012f14 | 91 | tui_refresh_all (tui_win_list); |
c906108c SS |
92 | } |
93 | else | |
94 | { | |
1cc6d956 | 95 | /* First make the current layout be invisible. */ |
ec7d9e56 | 96 | tui_make_all_invisible (); |
dd1abb8c | 97 | tui_make_invisible (tui_locator_win_info_ptr ()); |
c906108c SS |
98 | |
99 | switch (layout) | |
100 | { | |
1cc6d956 | 101 | /* Now show the new layout. */ |
c906108c | 102 | case SRC_COMMAND: |
6ba8e26f | 103 | show_source_command (); |
6d012f14 | 104 | tui_add_to_source_windows (TUI_SRC_WIN); |
c906108c SS |
105 | break; |
106 | case DISASSEM_COMMAND: | |
6ba8e26f | 107 | show_disasm_command (); |
6d012f14 | 108 | tui_add_to_source_windows (TUI_DISASM_WIN); |
c906108c SS |
109 | break; |
110 | case SRC_DISASSEM_COMMAND: | |
6ba8e26f | 111 | show_source_disasm_command (); |
6d012f14 AC |
112 | tui_add_to_source_windows (TUI_SRC_WIN); |
113 | tui_add_to_source_windows (TUI_DISASM_WIN); | |
c906108c SS |
114 | break; |
115 | default: | |
116 | break; | |
117 | } | |
118 | } | |
119 | } | |
bc712bbf | 120 | } |
c906108c SS |
121 | |
122 | ||
080ce8c0 | 123 | /* Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND, |
7bd0be3a | 124 | SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND. */ |
080ce8c0 | 125 | enum tui_status |
7bd0be3a | 126 | tui_set_layout (enum tui_layout_type layout_type) |
c906108c | 127 | { |
22940a24 | 128 | enum tui_status status = TUI_SUCCESS; |
c906108c | 129 | |
7bd0be3a | 130 | if (layout_type != UNDEFINED_LAYOUT) |
c906108c | 131 | { |
e5908723 MS |
132 | enum tui_layout_type cur_layout = tui_current_layout (), |
133 | new_layout = UNDEFINED_LAYOUT; | |
6ba8e26f | 134 | int regs_populate = FALSE; |
13274fc3 UW |
135 | struct gdbarch *gdbarch; |
136 | CORE_ADDR addr; | |
5b6fe301 MS |
137 | struct tui_win_info *win_with_focus = tui_win_with_focus (); |
138 | struct tui_layout_def *layout_def = tui_layout_def (); | |
c906108c | 139 | |
13274fc3 | 140 | extract_display_start_addr (&gdbarch, &addr); |
c906108c | 141 | |
7bd0be3a | 142 | new_layout = layout_type; |
c906108c | 143 | |
7bd0be3a AB |
144 | regs_populate = (new_layout == SRC_DATA_COMMAND |
145 | || new_layout == DISASSEM_DATA_COMMAND); | |
146 | if (new_layout != cur_layout) | |
c906108c | 147 | { |
7bd0be3a | 148 | show_layout (new_layout); |
ef5eab5a | 149 | |
7bd0be3a AB |
150 | /* Now determine where focus should be. */ |
151 | if (win_with_focus != TUI_CMD_WIN) | |
152 | { | |
153 | switch (new_layout) | |
c906108c | 154 | { |
7bd0be3a AB |
155 | case SRC_COMMAND: |
156 | tui_set_win_focus_to (TUI_SRC_WIN); | |
157 | layout_def->display_mode = SRC_WIN; | |
158 | layout_def->split = FALSE; | |
159 | break; | |
160 | case DISASSEM_COMMAND: | |
161 | /* The previous layout was not showing code. | |
162 | This can happen if there is no source | |
163 | available: | |
164 | ||
165 | 1. if the source file is in another dir OR | |
166 | 2. if target was compiled without -g | |
167 | We still want to show the assembly though! */ | |
168 | ||
169 | tui_get_begin_asm_address (&gdbarch, &addr); | |
170 | tui_set_win_focus_to (TUI_DISASM_WIN); | |
171 | layout_def->display_mode = DISASSEM_WIN; | |
172 | layout_def->split = FALSE; | |
173 | break; | |
174 | case SRC_DISASSEM_COMMAND: | |
175 | /* The previous layout was not showing code. | |
176 | This can happen if there is no source | |
177 | available: | |
178 | ||
179 | 1. if the source file is in another dir OR | |
180 | 2. if target was compiled without -g | |
181 | We still want to show the assembly though! */ | |
182 | ||
183 | tui_get_begin_asm_address (&gdbarch, &addr); | |
184 | if (win_with_focus == TUI_SRC_WIN) | |
185 | tui_set_win_focus_to (TUI_SRC_WIN); | |
186 | else | |
187 | tui_set_win_focus_to (TUI_DISASM_WIN); | |
188 | layout_def->split = TRUE; | |
189 | break; | |
190 | case SRC_DATA_COMMAND: | |
191 | if (win_with_focus != TUI_DATA_WIN) | |
192 | tui_set_win_focus_to (TUI_SRC_WIN); | |
193 | else | |
194 | tui_set_win_focus_to (TUI_DATA_WIN); | |
195 | layout_def->display_mode = SRC_WIN; | |
196 | layout_def->split = FALSE; | |
197 | break; | |
198 | case DISASSEM_DATA_COMMAND: | |
199 | /* The previous layout was not showing code. | |
200 | This can happen if there is no source | |
201 | available: | |
202 | ||
203 | 1. if the source file is in another dir OR | |
204 | 2. if target was compiled without -g | |
205 | We still want to show the assembly though! */ | |
206 | ||
207 | tui_get_begin_asm_address (&gdbarch, &addr); | |
208 | if (win_with_focus != TUI_DATA_WIN) | |
209 | tui_set_win_focus_to (TUI_DISASM_WIN); | |
210 | else | |
211 | tui_set_win_focus_to (TUI_DATA_WIN); | |
212 | layout_def->display_mode = DISASSEM_WIN; | |
213 | layout_def->split = FALSE; | |
214 | break; | |
215 | default: | |
216 | break; | |
c906108c | 217 | } |
c906108c | 218 | } |
7bd0be3a AB |
219 | /* |
220 | * Now update the window content. | |
221 | */ | |
222 | if (!regs_populate | |
223 | && (new_layout == SRC_DATA_COMMAND | |
224 | || new_layout == DISASSEM_DATA_COMMAND)) | |
225 | tui_display_all_data (); | |
226 | ||
227 | tui_update_source_windows_with_addr (gdbarch, addr); | |
228 | ||
6ba8e26f | 229 | if (regs_populate) |
238eb706 | 230 | tui_show_registers (TUI_DATA_WIN->current_group); |
c906108c SS |
231 | } |
232 | } | |
233 | else | |
234 | status = TUI_FAILURE; | |
235 | ||
236 | return status; | |
bc712bbf | 237 | } |
c906108c | 238 | |
080ce8c0 AC |
239 | /* Add the specified window to the layout in a logical way. This |
240 | means setting up the most logical layout given the window to be | |
241 | added. */ | |
c906108c | 242 | void |
080ce8c0 | 243 | tui_add_win_to_layout (enum tui_win_type type) |
c906108c | 244 | { |
6ba8e26f | 245 | enum tui_layout_type cur_layout = tui_current_layout (); |
c906108c SS |
246 | |
247 | switch (type) | |
248 | { | |
249 | case SRC_WIN: | |
e5908723 MS |
250 | if (cur_layout != SRC_COMMAND |
251 | && cur_layout != SRC_DISASSEM_COMMAND | |
252 | && cur_layout != SRC_DATA_COMMAND) | |
c906108c | 253 | { |
dd1abb8c | 254 | tui_clear_source_windows_detail (); |
6ba8e26f AC |
255 | if (cur_layout == DISASSEM_DATA_COMMAND) |
256 | show_layout (SRC_DATA_COMMAND); | |
c906108c | 257 | else |
6ba8e26f | 258 | show_layout (SRC_COMMAND); |
c906108c SS |
259 | } |
260 | break; | |
261 | case DISASSEM_WIN: | |
e5908723 MS |
262 | if (cur_layout != DISASSEM_COMMAND |
263 | && cur_layout != SRC_DISASSEM_COMMAND | |
264 | && cur_layout != DISASSEM_DATA_COMMAND) | |
c906108c | 265 | { |
dd1abb8c | 266 | tui_clear_source_windows_detail (); |
6ba8e26f AC |
267 | if (cur_layout == SRC_DATA_COMMAND) |
268 | show_layout (DISASSEM_DATA_COMMAND); | |
c906108c | 269 | else |
6ba8e26f | 270 | show_layout (DISASSEM_COMMAND); |
c906108c SS |
271 | } |
272 | break; | |
273 | case DATA_WIN: | |
e5908723 MS |
274 | if (cur_layout != SRC_DATA_COMMAND |
275 | && cur_layout != DISASSEM_DATA_COMMAND) | |
c906108c | 276 | { |
6ba8e26f AC |
277 | if (cur_layout == DISASSEM_COMMAND) |
278 | show_layout (DISASSEM_DATA_COMMAND); | |
c906108c | 279 | else |
6ba8e26f | 280 | show_layout (SRC_DATA_COMMAND); |
c906108c SS |
281 | } |
282 | break; | |
283 | default: | |
284 | break; | |
285 | } | |
6ba8e26f | 286 | } |
c906108c SS |
287 | |
288 | ||
6ba8e26f AC |
289 | /* Answer the height of a window. If it hasn't been created yet, |
290 | answer what the height of a window would be based upon its type and | |
291 | the layout. */ | |
c906108c | 292 | int |
08ef48c5 MS |
293 | tui_default_win_height (enum tui_win_type type, |
294 | enum tui_layout_type layout) | |
c906108c SS |
295 | { |
296 | int h; | |
297 | ||
cafb3438 | 298 | if (tui_win_list[type] != NULL) |
cb2ce893 | 299 | h = tui_win_list[type]->height; |
c906108c SS |
300 | else |
301 | { | |
302 | switch (layout) | |
303 | { | |
304 | case SRC_COMMAND: | |
305 | case DISASSEM_COMMAND: | |
6d012f14 | 306 | if (TUI_CMD_WIN == NULL) |
dd1abb8c | 307 | h = tui_term_height () / 2; |
c906108c | 308 | else |
cb2ce893 | 309 | h = tui_term_height () - TUI_CMD_WIN->height; |
c906108c SS |
310 | break; |
311 | case SRC_DISASSEM_COMMAND: | |
312 | case SRC_DATA_COMMAND: | |
313 | case DISASSEM_DATA_COMMAND: | |
6d012f14 | 314 | if (TUI_CMD_WIN == NULL) |
dd1abb8c | 315 | h = tui_term_height () / 3; |
c906108c | 316 | else |
cb2ce893 | 317 | h = (tui_term_height () - TUI_CMD_WIN->height) / 2; |
c906108c SS |
318 | break; |
319 | default: | |
320 | h = 0; | |
321 | break; | |
322 | } | |
323 | } | |
324 | ||
325 | return h; | |
6ba8e26f | 326 | } |
c906108c SS |
327 | |
328 | ||
080ce8c0 AC |
329 | /* Answer the height of a window. If it hasn't been created yet, |
330 | answer what the height of a window would be based upon its type and | |
331 | the layout. */ | |
c906108c | 332 | int |
080ce8c0 AC |
333 | tui_default_win_viewport_height (enum tui_win_type type, |
334 | enum tui_layout_type layout) | |
c906108c SS |
335 | { |
336 | int h; | |
337 | ||
6ba8e26f | 338 | h = tui_default_win_height (type, layout); |
c906108c | 339 | |
6d012f14 | 340 | if (tui_win_list[type] == TUI_CMD_WIN) |
c906108c SS |
341 | h -= 1; |
342 | else | |
343 | h -= 2; | |
344 | ||
345 | return h; | |
6ba8e26f | 346 | } |
c906108c | 347 | |
a0145030 AB |
348 | /* Complete possible layout names. TEXT is the complete text entered so |
349 | far, WORD is the word currently being completed. */ | |
350 | ||
eb3ff9a5 | 351 | static void |
a0145030 | 352 | layout_completer (struct cmd_list_element *ignore, |
eb3ff9a5 | 353 | completion_tracker &tracker, |
a0145030 AB |
354 | const char *text, const char *word) |
355 | { | |
356 | static const char *layout_names [] = | |
357 | { "src", "asm", "split", "regs", "next", "prev", NULL }; | |
358 | ||
eb3ff9a5 | 359 | complete_on_enum (tracker, layout_names, text, word); |
a0145030 AB |
360 | } |
361 | ||
6ba8e26f AC |
362 | /* Function to initialize gdb commands, for tui window layout |
363 | manipulation. */ | |
2c0b251b | 364 | |
c906108c | 365 | void |
6ba8e26f | 366 | _initialize_tui_layout (void) |
c906108c | 367 | { |
a0145030 AB |
368 | struct cmd_list_element *cmd; |
369 | ||
370 | cmd = add_com ("layout", class_tui, tui_layout_command, _("\ | |
1bedd215 | 371 | Change the layout of windows.\n\ |
bf212be1 | 372 | Usage: layout prev | next | LAYOUT-NAME\n\ |
c906108c SS |
373 | Layout names are:\n\ |
374 | src : Displays source and command windows.\n\ | |
375 | asm : Displays disassembly and command windows.\n\ | |
376 | split : Displays source, disassembly and command windows.\n\ | |
377 | regs : Displays register window. If existing layout\n\ | |
378 | is source/command or assembly/command, the \n\ | |
379 | register window is displayed. If the\n\ | |
380 | source/assembly/command (split) is displayed, \n\ | |
381 | the register window is displayed with \n\ | |
89549d7f | 382 | the window that has current logical focus.")); |
a0145030 | 383 | set_cmd_completer (cmd, layout_completer); |
41783295 | 384 | } |
c906108c SS |
385 | |
386 | ||
387 | /************************* | |
388 | ** STATIC LOCAL FUNCTIONS | |
389 | **************************/ | |
390 | ||
391 | ||
7bd0be3a AB |
392 | /* Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, or |
393 | REGS. */ | |
22940a24 | 394 | enum tui_status |
7bd0be3a | 395 | tui_set_layout_by_name (const char *layout_name) |
c906108c | 396 | { |
22940a24 | 397 | enum tui_status status = TUI_SUCCESS; |
c906108c | 398 | |
63a33118 | 399 | if (layout_name != NULL) |
c906108c | 400 | { |
d02c80cd | 401 | int i; |
6ba8e26f | 402 | enum tui_layout_type new_layout = UNDEFINED_LAYOUT; |
6ba8e26f | 403 | enum tui_layout_type cur_layout = tui_current_layout (); |
c906108c | 404 | |
f71c8822 TT |
405 | std::string copy = layout_name; |
406 | for (i = 0; i < copy.size (); i++) | |
407 | copy[i] = toupper (copy[i]); | |
408 | const char *buf_ptr = copy.c_str (); | |
c906108c | 409 | |
1cc6d956 | 410 | /* First check for ambiguous input. */ |
7bd0be3a | 411 | if (strlen (buf_ptr) <= 1 && *buf_ptr == 'S') |
c906108c | 412 | { |
8a3fe4f8 | 413 | warning (_("Ambiguous command input.")); |
c906108c SS |
414 | status = TUI_FAILURE; |
415 | } | |
416 | else | |
417 | { | |
6ba8e26f AC |
418 | if (subset_compare (buf_ptr, "SRC")) |
419 | new_layout = SRC_COMMAND; | |
420 | else if (subset_compare (buf_ptr, "ASM")) | |
421 | new_layout = DISASSEM_COMMAND; | |
422 | else if (subset_compare (buf_ptr, "SPLIT")) | |
423 | new_layout = SRC_DISASSEM_COMMAND; | |
7bd0be3a | 424 | else if (subset_compare (buf_ptr, "REGS")) |
c906108c | 425 | { |
7bd0be3a | 426 | if (cur_layout == SRC_COMMAND |
e5908723 | 427 | || cur_layout == SRC_DATA_COMMAND) |
6ba8e26f | 428 | new_layout = SRC_DATA_COMMAND; |
c906108c | 429 | else |
6ba8e26f | 430 | new_layout = DISASSEM_DATA_COMMAND; |
c906108c | 431 | } |
6ba8e26f AC |
432 | else if (subset_compare (buf_ptr, "NEXT")) |
433 | new_layout = next_layout (); | |
434 | else if (subset_compare (buf_ptr, "PREV")) | |
435 | new_layout = prev_layout (); | |
c906108c SS |
436 | else |
437 | status = TUI_FAILURE; | |
c906108c | 438 | |
880d1e40 AB |
439 | if (status == TUI_SUCCESS) |
440 | { | |
441 | /* Make sure the curses mode is enabled. */ | |
442 | tui_enable (); | |
443 | tui_set_layout (new_layout); | |
444 | } | |
c906108c SS |
445 | } |
446 | } | |
447 | else | |
448 | status = TUI_FAILURE; | |
449 | ||
450 | return status; | |
e8b915dc | 451 | } |
c906108c SS |
452 | |
453 | ||
13274fc3 UW |
454 | static void |
455 | extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p) | |
c906108c | 456 | { |
6ba8e26f | 457 | enum tui_layout_type cur_layout = tui_current_layout (); |
957b8b5a | 458 | struct gdbarch *gdbarch = get_current_arch (); |
c774cec6 | 459 | CORE_ADDR addr; |
84b1e7c7 | 460 | CORE_ADDR pc; |
52575520 | 461 | struct symtab_and_line cursal = get_current_source_symtab_and_line (); |
c906108c | 462 | |
6ba8e26f | 463 | switch (cur_layout) |
c906108c SS |
464 | { |
465 | case SRC_COMMAND: | |
466 | case SRC_DATA_COMMAND: | |
e6e41501 | 467 | gdbarch = TUI_SRC_WIN->gdbarch; |
52575520 | 468 | find_line_pc (cursal.symtab, |
e6e41501 | 469 | TUI_SRC_WIN->start_line_or_addr.u.line_no, |
84b1e7c7 | 470 | &pc); |
c774cec6 | 471 | addr = pc; |
c906108c SS |
472 | break; |
473 | case DISASSEM_COMMAND: | |
474 | case SRC_DISASSEM_COMMAND: | |
475 | case DISASSEM_DATA_COMMAND: | |
e6e41501 TT |
476 | gdbarch = TUI_DISASM_WIN->gdbarch; |
477 | addr = TUI_DISASM_WIN->start_line_or_addr.u.addr; | |
c906108c SS |
478 | break; |
479 | default: | |
c774cec6 | 480 | addr = 0; |
c906108c SS |
481 | break; |
482 | } | |
483 | ||
13274fc3 UW |
484 | *gdbarch_p = gdbarch; |
485 | *addr_p = addr; | |
6ba8e26f | 486 | } |
c906108c SS |
487 | |
488 | ||
c906108c | 489 | static void |
0b39b52e | 490 | tui_layout_command (const char *arg, int from_tty) |
c906108c | 491 | { |
19eb139b | 492 | /* Switch to the selected layout. */ |
7bd0be3a | 493 | if (tui_set_layout_by_name (arg) != TUI_SUCCESS) |
8a3fe4f8 | 494 | warning (_("Invalid layout specified.\n%s"), LAYOUT_USAGE); |
e8b915dc | 495 | } |
c906108c | 496 | |
6ba8e26f | 497 | /* Answer the previous layout to cycle to. */ |
2a8854a7 | 498 | static enum tui_layout_type |
6ba8e26f | 499 | next_layout (void) |
c906108c | 500 | { |
570dc176 | 501 | int new_layout; |
c906108c | 502 | |
6ba8e26f AC |
503 | new_layout = tui_current_layout (); |
504 | if (new_layout == UNDEFINED_LAYOUT) | |
505 | new_layout = SRC_COMMAND; | |
c906108c SS |
506 | else |
507 | { | |
6ba8e26f AC |
508 | new_layout++; |
509 | if (new_layout == UNDEFINED_LAYOUT) | |
510 | new_layout = SRC_COMMAND; | |
c906108c SS |
511 | } |
512 | ||
570dc176 | 513 | return (enum tui_layout_type) new_layout; |
6ba8e26f | 514 | } |
c906108c SS |
515 | |
516 | ||
6ba8e26f | 517 | /* Answer the next layout to cycle to. */ |
2a8854a7 | 518 | static enum tui_layout_type |
6ba8e26f | 519 | prev_layout (void) |
c906108c | 520 | { |
570dc176 | 521 | int new_layout; |
c906108c | 522 | |
6ba8e26f AC |
523 | new_layout = tui_current_layout (); |
524 | if (new_layout == SRC_COMMAND) | |
525 | new_layout = DISASSEM_DATA_COMMAND; | |
c906108c SS |
526 | else |
527 | { | |
6ba8e26f AC |
528 | new_layout--; |
529 | if (new_layout == UNDEFINED_LAYOUT) | |
530 | new_layout = DISASSEM_DATA_COMMAND; | |
c906108c SS |
531 | } |
532 | ||
570dc176 | 533 | return (enum tui_layout_type) new_layout; |
6ba8e26f | 534 | } |
c906108c SS |
535 | |
536 | ||
537 | ||
82432e10 TT |
538 | static struct tui_win_info * |
539 | make_command_window (int height, int origin_y) | |
c906108c | 540 | { |
82432e10 TT |
541 | struct tui_win_info *result |
542 | = (struct tui_win_info *) init_and_make_win (NULL, | |
19ba03f4 SM |
543 | CMD_WIN, |
544 | height, | |
545 | tui_term_width (), | |
546 | 0, | |
547 | origin_y, | |
548 | DONT_BOX_WINDOW); | |
214a5cbe | 549 | result->can_highlight = false; |
82432e10 | 550 | return result; |
6ba8e26f | 551 | } |
c906108c SS |
552 | |
553 | ||
ef5eab5a | 554 | /* make_source_window(). |
c5aa993b | 555 | */ |
0ed69eda TT |
556 | static struct tui_win_info * |
557 | make_source_window (int height, int origin_y) | |
c906108c | 558 | { |
0ed69eda | 559 | return make_source_or_disasm_window (SRC_WIN, height, origin_y); |
6ba8e26f | 560 | } /* make_source_window */ |
c906108c SS |
561 | |
562 | ||
ef5eab5a | 563 | /* make_disasm_window(). |
c5aa993b | 564 | */ |
0ed69eda TT |
565 | static struct tui_win_info * |
566 | make_disasm_window (int height, int origin_y) | |
c906108c | 567 | { |
0ed69eda | 568 | return make_source_or_disasm_window (DISASSEM_WIN, height, origin_y); |
6ba8e26f | 569 | } /* make_disasm_window */ |
c906108c SS |
570 | |
571 | ||
c906108c | 572 | static void |
08ef48c5 MS |
573 | make_data_window (struct tui_win_info **win_info_ptr, |
574 | int height, int origin_y) | |
c906108c | 575 | { |
19ba03f4 SM |
576 | *win_info_ptr |
577 | = (struct tui_win_info *) init_and_make_win (*win_info_ptr, | |
578 | DATA_WIN, | |
579 | height, | |
580 | tui_term_width (), | |
581 | 0, | |
582 | origin_y, | |
583 | BOX_WINDOW); | |
6ba8e26f | 584 | } |
c906108c SS |
585 | |
586 | ||
587 | ||
6ba8e26f | 588 | /* Show the Source/Command layout. */ |
c906108c | 589 | static void |
6ba8e26f | 590 | show_source_command (void) |
c906108c | 591 | { |
6ba8e26f AC |
592 | show_source_or_disasm_and_command (SRC_COMMAND); |
593 | } | |
c906108c SS |
594 | |
595 | ||
6ba8e26f | 596 | /* Show the Dissassem/Command layout. */ |
c906108c | 597 | static void |
6ba8e26f | 598 | show_disasm_command (void) |
c906108c | 599 | { |
6ba8e26f AC |
600 | show_source_or_disasm_and_command (DISASSEM_COMMAND); |
601 | } | |
c906108c SS |
602 | |
603 | ||
6ba8e26f | 604 | /* Show the Source/Disassem/Command layout. */ |
c906108c | 605 | static void |
6ba8e26f | 606 | show_source_disasm_command (void) |
c906108c | 607 | { |
dd1abb8c | 608 | if (tui_current_layout () != SRC_DISASSEM_COMMAND) |
c906108c | 609 | { |
6ba8e26f | 610 | int cmd_height, src_height, asm_height; |
c906108c | 611 | |
6d012f14 | 612 | if (TUI_CMD_WIN != NULL) |
cb2ce893 | 613 | cmd_height = TUI_CMD_WIN->height; |
c906108c | 614 | else |
6ba8e26f | 615 | cmd_height = tui_term_height () / 3; |
c906108c | 616 | |
6ba8e26f AC |
617 | src_height = (tui_term_height () - cmd_height) / 2; |
618 | asm_height = tui_term_height () - (src_height + cmd_height); | |
c906108c | 619 | |
6d012f14 | 620 | if (TUI_SRC_WIN == NULL) |
e6e41501 | 621 | tui_win_list[SRC_WIN] = make_source_window (src_height, 0); |
c906108c SS |
622 | else |
623 | { | |
cb2ce893 TT |
624 | init_gen_win_info (TUI_SRC_WIN, |
625 | TUI_SRC_WIN->type, | |
08ef48c5 | 626 | src_height, |
cb2ce893 | 627 | TUI_SRC_WIN->width, |
e6e41501 | 628 | TUI_SRC_WIN->execution_info->width, |
08ef48c5 | 629 | 0); |
214a5cbe | 630 | TUI_SRC_WIN->can_highlight = true; |
e6e41501 | 631 | init_gen_win_info (TUI_SRC_WIN->execution_info, |
08ef48c5 MS |
632 | EXEC_INFO_WIN, |
633 | src_height, | |
634 | 3, | |
635 | 0, | |
636 | 0); | |
cb2ce893 | 637 | tui_make_visible (TUI_SRC_WIN); |
e6e41501 TT |
638 | tui_make_visible (TUI_SRC_WIN->execution_info); |
639 | TUI_SRC_WIN->m_has_locator = false; | |
c906108c | 640 | } |
c906108c | 641 | |
82432e10 TT |
642 | struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); |
643 | ||
644 | tui_show_source_content (TUI_SRC_WIN); | |
645 | if (TUI_DISASM_WIN == NULL) | |
646 | { | |
e6e41501 TT |
647 | tui_win_list[DISASSEM_WIN] |
648 | = make_disasm_window (asm_height, src_height - 1); | |
82432e10 TT |
649 | locator |
650 | = ((struct tui_gen_win_info *) | |
651 | init_and_make_win (locator, | |
652 | LOCATOR_WIN, | |
653 | 2 /* 1 */ , | |
654 | tui_term_width (), | |
655 | 0, | |
656 | (src_height + asm_height) - 1, | |
657 | DONT_BOX_WINDOW)); | |
658 | } | |
659 | else | |
660 | { | |
661 | init_gen_win_info (locator, | |
662 | LOCATOR_WIN, | |
663 | 2 /* 1 */ , | |
664 | tui_term_width (), | |
665 | 0, | |
666 | (src_height + asm_height) - 1); | |
e6e41501 | 667 | TUI_DISASM_WIN->m_has_locator = true; |
cb2ce893 TT |
668 | init_gen_win_info (TUI_DISASM_WIN, |
669 | TUI_DISASM_WIN->type, | |
82432e10 | 670 | asm_height, |
cb2ce893 | 671 | TUI_DISASM_WIN->width, |
e6e41501 | 672 | TUI_DISASM_WIN->execution_info->width, |
82432e10 | 673 | src_height - 1); |
e6e41501 | 674 | init_gen_win_info (TUI_DISASM_WIN->execution_info, |
82432e10 TT |
675 | EXEC_INFO_WIN, |
676 | asm_height, | |
677 | 3, | |
678 | 0, | |
679 | src_height - 1); | |
214a5cbe | 680 | TUI_DISASM_WIN->can_highlight = true; |
cb2ce893 | 681 | tui_make_visible (TUI_DISASM_WIN); |
e6e41501 | 682 | tui_make_visible (TUI_DISASM_WIN->execution_info); |
82432e10 | 683 | } |
e6e41501 TT |
684 | TUI_SRC_WIN->m_has_locator = false; |
685 | TUI_DISASM_WIN->m_has_locator = true; | |
82432e10 TT |
686 | tui_make_visible (locator); |
687 | tui_show_locator_content (); | |
688 | tui_show_source_content (TUI_DISASM_WIN); | |
689 | ||
690 | if (TUI_CMD_WIN == NULL) | |
81491aa0 TT |
691 | tui_win_list[CMD_WIN] |
692 | = make_command_window (cmd_height, tui_term_height () - cmd_height); | |
82432e10 TT |
693 | else |
694 | { | |
cb2ce893 TT |
695 | init_gen_win_info (TUI_CMD_WIN, |
696 | TUI_CMD_WIN->type, | |
697 | TUI_CMD_WIN->height, | |
698 | TUI_CMD_WIN->width, | |
82432e10 | 699 | 0, |
cb2ce893 | 700 | TUI_CMD_WIN->origin.y); |
214a5cbe | 701 | TUI_CMD_WIN->can_highlight = false; |
cb2ce893 | 702 | tui_make_visible (TUI_CMD_WIN); |
c906108c | 703 | } |
cb2ce893 | 704 | tui_refresh_win (TUI_CMD_WIN); |
dd1abb8c | 705 | tui_set_current_layout_to (SRC_DISASSEM_COMMAND); |
c906108c | 706 | } |
6ba8e26f | 707 | } |
c906108c SS |
708 | |
709 | ||
6ba8e26f AC |
710 | /* Show the Source/Data/Command or the Dissassembly/Data/Command |
711 | layout. */ | |
c906108c | 712 | static void |
6ba8e26f | 713 | show_data (enum tui_layout_type new_layout) |
c906108c | 714 | { |
cb2ce893 | 715 | int total_height = (tui_term_height () - TUI_CMD_WIN->height); |
6ba8e26f AC |
716 | int src_height, data_height; |
717 | enum tui_win_type win_type; | |
5b6fe301 | 718 | struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); |
c906108c SS |
719 | |
720 | ||
6ba8e26f AC |
721 | data_height = total_height / 2; |
722 | src_height = total_height - data_height; | |
ec7d9e56 AC |
723 | tui_make_all_invisible (); |
724 | tui_make_invisible (locator); | |
238eb706 | 725 | make_data_window (&tui_win_list[DATA_WIN], data_height, 0); |
214a5cbe | 726 | TUI_DATA_WIN->can_highlight = true; |
6ba8e26f AC |
727 | if (new_layout == SRC_DATA_COMMAND) |
728 | win_type = SRC_WIN; | |
c906108c | 729 | else |
6ba8e26f | 730 | win_type = DISASSEM_WIN; |
e6e41501 TT |
731 | |
732 | tui_source_window_base *base; | |
6ba8e26f | 733 | if (tui_win_list[win_type] == NULL) |
c906108c | 734 | { |
6ba8e26f | 735 | if (win_type == SRC_WIN) |
0ed69eda TT |
736 | tui_win_list[win_type] |
737 | = make_source_window (src_height, data_height - 1); | |
c906108c | 738 | else |
0ed69eda TT |
739 | tui_win_list[win_type] |
740 | = make_disasm_window (src_height, data_height - 1); | |
19ba03f4 SM |
741 | locator |
742 | = ((struct tui_gen_win_info *) | |
743 | init_and_make_win (locator, | |
744 | LOCATOR_WIN, | |
745 | 2 /* 1 */ , | |
746 | tui_term_width (), | |
747 | 0, | |
748 | total_height - 1, | |
749 | DONT_BOX_WINDOW)); | |
e6e41501 | 750 | base = (tui_source_window_base *) tui_win_list[win_type]; |
c906108c SS |
751 | } |
752 | else | |
753 | { | |
e6e41501 | 754 | base = (tui_source_window_base *) tui_win_list[win_type]; |
cb2ce893 TT |
755 | init_gen_win_info (tui_win_list[win_type], |
756 | tui_win_list[win_type]->type, | |
08ef48c5 | 757 | src_height, |
cb2ce893 | 758 | tui_win_list[win_type]->width, |
e6e41501 | 759 | base->execution_info->width, |
08ef48c5 | 760 | data_height - 1); |
e6e41501 | 761 | init_gen_win_info (base->execution_info, |
08ef48c5 MS |
762 | EXEC_INFO_WIN, |
763 | src_height, | |
764 | 3, | |
765 | 0, | |
766 | data_height - 1); | |
cb2ce893 | 767 | tui_make_visible (tui_win_list[win_type]); |
e6e41501 | 768 | tui_make_visible (base->execution_info); |
6ba8e26f | 769 | init_gen_win_info (locator, |
08ef48c5 MS |
770 | LOCATOR_WIN, |
771 | 2 /* 1 */ , | |
772 | tui_term_width (), | |
773 | 0, | |
774 | total_height - 1); | |
c906108c | 775 | } |
e6e41501 | 776 | base->m_has_locator = true; |
ec7d9e56 | 777 | tui_make_visible (locator); |
47d3492a | 778 | tui_show_locator_content (); |
ad54d15b TT |
779 | tui_add_to_source_windows |
780 | ((tui_source_window_base *) tui_win_list[win_type]); | |
6ba8e26f AC |
781 | tui_set_current_layout_to (new_layout); |
782 | } | |
c906108c | 783 | |
ef5eab5a | 784 | /* init_gen_win_info(). |
c5aa993b | 785 | */ |
c906108c | 786 | static void |
08ef48c5 MS |
787 | init_gen_win_info (struct tui_gen_win_info *win_info, |
788 | enum tui_win_type type, | |
789 | int height, int width, | |
790 | int origin_x, int origin_y) | |
c906108c SS |
791 | { |
792 | int h = height; | |
793 | ||
6ba8e26f AC |
794 | win_info->type = type; |
795 | win_info->width = width; | |
796 | win_info->height = h; | |
c906108c SS |
797 | if (h > 1) |
798 | { | |
6ba8e26f AC |
799 | win_info->viewport_height = h - 1; |
800 | if (win_info->type != CMD_WIN) | |
801 | win_info->viewport_height--; | |
c906108c SS |
802 | } |
803 | else | |
6ba8e26f AC |
804 | win_info->viewport_height = 1; |
805 | win_info->origin.x = origin_x; | |
806 | win_info->origin.y = origin_y; | |
c906108c SS |
807 | |
808 | return; | |
6ba8e26f | 809 | } /* init_gen_win_info */ |
c906108c | 810 | |
ef5eab5a | 811 | /* init_and_make_win(). |
c5aa993b | 812 | */ |
d5d6fca5 | 813 | static void * |
08ef48c5 MS |
814 | init_and_make_win (void *opaque_win_info, |
815 | enum tui_win_type win_type, | |
816 | int height, int width, | |
817 | int origin_x, int origin_y, | |
d5d6fca5 | 818 | int box_it) |
c906108c | 819 | { |
5b6fe301 | 820 | struct tui_gen_win_info *generic; |
c906108c | 821 | |
6ba8e26f | 822 | if (opaque_win_info == NULL) |
c906108c | 823 | { |
6ba8e26f | 824 | if (tui_win_is_auxillary (win_type)) |
ab313b35 | 825 | opaque_win_info = (void *) new tui_gen_win_info (win_type); |
c906108c | 826 | else |
6ba8e26f | 827 | opaque_win_info = (void *) tui_alloc_win_info (win_type); |
c906108c | 828 | } |
6ba8e26f AC |
829 | if (tui_win_is_auxillary (win_type)) |
830 | generic = (struct tui_gen_win_info *) opaque_win_info; | |
c906108c | 831 | else |
cb2ce893 | 832 | generic = (struct tui_win_info *) opaque_win_info; |
c906108c | 833 | |
ec328aa5 TT |
834 | init_gen_win_info (generic, win_type, height, width, origin_x, origin_y); |
835 | if (!tui_win_is_auxillary (win_type)) | |
c906108c | 836 | { |
ec328aa5 | 837 | if (generic->type == CMD_WIN) |
214a5cbe | 838 | ((struct tui_win_info *) opaque_win_info)->can_highlight = false; |
ec328aa5 | 839 | else |
214a5cbe | 840 | ((struct tui_win_info *) opaque_win_info)->can_highlight = true; |
c906108c | 841 | } |
ec328aa5 TT |
842 | tui_make_window (generic, box_it); |
843 | ||
d5d6fca5 | 844 | return opaque_win_info; |
bc712bbf | 845 | } |
c906108c SS |
846 | |
847 | ||
0ed69eda TT |
848 | static struct tui_win_info * |
849 | make_source_or_disasm_window (enum tui_win_type type, | |
08ef48c5 | 850 | int height, int origin_y) |
c906108c | 851 | { |
e65b5245 | 852 | struct tui_gen_win_info *execution_info = NULL; |
c906108c | 853 | |
ef5eab5a | 854 | /* Create the exeuction info window. */ |
c906108c | 855 | if (type == SRC_WIN) |
6d012f14 | 856 | execution_info = tui_source_exec_info_win_ptr (); |
c906108c | 857 | else |
6d012f14 | 858 | execution_info = tui_disassem_exec_info_win_ptr (); |
19ba03f4 SM |
859 | execution_info |
860 | = ((struct tui_gen_win_info *) | |
861 | init_and_make_win (execution_info, | |
862 | EXEC_INFO_WIN, | |
863 | height, | |
864 | 3, | |
865 | 0, | |
866 | origin_y, | |
867 | DONT_BOX_WINDOW)); | |
ef5eab5a MS |
868 | |
869 | /* Now create the source window. */ | |
e6e41501 TT |
870 | struct tui_source_window_base *result |
871 | = ((struct tui_source_window_base *) | |
0ed69eda | 872 | init_and_make_win (NULL, |
19ba03f4 SM |
873 | type, |
874 | height, | |
875 | tui_term_width () - execution_info->width, | |
876 | execution_info->width, | |
877 | origin_y, | |
878 | BOX_WINDOW)); | |
e6e41501 | 879 | result->execution_info = execution_info; |
0ed69eda | 880 | return result; |
6ba8e26f | 881 | } |
c906108c SS |
882 | |
883 | ||
1cc6d956 | 884 | /* Show the Source/Command or the Disassem layout. */ |
c906108c | 885 | static void |
6ba8e26f | 886 | show_source_or_disasm_and_command (enum tui_layout_type layout_type) |
c906108c | 887 | { |
6ba8e26f | 888 | if (tui_current_layout () != layout_type) |
c906108c | 889 | { |
5b6fe301 | 890 | struct tui_win_info **win_info_ptr; |
6ba8e26f | 891 | int src_height, cmd_height; |
5b6fe301 | 892 | struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); |
c906108c | 893 | |
6d012f14 | 894 | if (TUI_CMD_WIN != NULL) |
cb2ce893 | 895 | cmd_height = TUI_CMD_WIN->height; |
c906108c | 896 | else |
6ba8e26f AC |
897 | cmd_height = tui_term_height () / 3; |
898 | src_height = tui_term_height () - cmd_height; | |
c906108c | 899 | |
6ba8e26f | 900 | if (layout_type == SRC_COMMAND) |
e6e41501 | 901 | win_info_ptr = &tui_win_list[SRC_WIN]; |
c906108c | 902 | else |
e6e41501 | 903 | win_info_ptr = &tui_win_list[DISASSEM_WIN]; |
c906108c | 904 | |
e6e41501 | 905 | tui_source_window_base *base; |
6ba8e26f | 906 | if ((*win_info_ptr) == NULL) |
c906108c | 907 | { |
6ba8e26f | 908 | if (layout_type == SRC_COMMAND) |
0ed69eda | 909 | *win_info_ptr = make_source_window (src_height - 1, 0); |
c906108c | 910 | else |
0ed69eda | 911 | *win_info_ptr = make_disasm_window (src_height - 1, 0); |
19ba03f4 SM |
912 | locator |
913 | = ((struct tui_gen_win_info *) | |
914 | init_and_make_win (locator, | |
915 | LOCATOR_WIN, | |
916 | 2 /* 1 */ , | |
917 | tui_term_width (), | |
918 | 0, | |
919 | src_height - 1, | |
920 | DONT_BOX_WINDOW)); | |
e6e41501 | 921 | base = (tui_source_window_base *) *win_info_ptr; |
c906108c SS |
922 | } |
923 | else | |
924 | { | |
e6e41501 | 925 | base = (tui_source_window_base *) *win_info_ptr; |
6ba8e26f | 926 | init_gen_win_info (locator, |
08ef48c5 MS |
927 | LOCATOR_WIN, |
928 | 2 /* 1 */ , | |
929 | tui_term_width (), | |
930 | 0, | |
931 | src_height - 1); | |
e6e41501 | 932 | base->m_has_locator = true; |
cb2ce893 TT |
933 | init_gen_win_info (*win_info_ptr, |
934 | (*win_info_ptr)->type, | |
08ef48c5 | 935 | src_height - 1, |
cb2ce893 | 936 | (*win_info_ptr)->width, |
e6e41501 | 937 | base->execution_info->width, |
08ef48c5 | 938 | 0); |
e6e41501 | 939 | init_gen_win_info (base->execution_info, |
08ef48c5 MS |
940 | EXEC_INFO_WIN, |
941 | src_height - 1, | |
942 | 3, | |
943 | 0, | |
944 | 0); | |
214a5cbe | 945 | base->can_highlight = true; |
cb2ce893 | 946 | tui_make_visible (*win_info_ptr); |
e6e41501 | 947 | tui_make_visible (base->execution_info); |
c906108c | 948 | } |
c906108c | 949 | |
6a0ee02c TT |
950 | base->m_has_locator = true; |
951 | tui_make_visible (locator); | |
952 | tui_show_locator_content (); | |
953 | tui_show_source_content (*win_info_ptr); | |
954 | ||
955 | if (TUI_CMD_WIN == NULL) | |
956 | { | |
957 | tui_win_list[CMD_WIN] = make_command_window (cmd_height, | |
958 | src_height); | |
cb2ce893 | 959 | tui_refresh_win (TUI_CMD_WIN); |
6a0ee02c TT |
960 | } |
961 | else | |
962 | { | |
cb2ce893 TT |
963 | init_gen_win_info (TUI_CMD_WIN, |
964 | TUI_CMD_WIN->type, | |
965 | TUI_CMD_WIN->height, | |
966 | TUI_CMD_WIN->width, | |
967 | TUI_CMD_WIN->origin.x, | |
968 | TUI_CMD_WIN->origin.y); | |
214a5cbe | 969 | TUI_CMD_WIN->can_highlight = false; |
cb2ce893 | 970 | tui_make_visible (TUI_CMD_WIN); |
c906108c | 971 | } |
6ba8e26f | 972 | tui_set_current_layout_to (layout_type); |
c906108c | 973 | } |
6ba8e26f | 974 | } |