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) |
c906108c | 230 | { |
7bd0be3a AB |
231 | struct reggroup *group = |
232 | TUI_DATA_WIN->detail.data_display_info.current_group; | |
233 | tui_show_registers (group); | |
c906108c SS |
234 | } |
235 | } | |
236 | } | |
237 | else | |
238 | status = TUI_FAILURE; | |
239 | ||
240 | return status; | |
bc712bbf | 241 | } |
c906108c | 242 | |
080ce8c0 AC |
243 | /* Add the specified window to the layout in a logical way. This |
244 | means setting up the most logical layout given the window to be | |
245 | added. */ | |
c906108c | 246 | void |
080ce8c0 | 247 | tui_add_win_to_layout (enum tui_win_type type) |
c906108c | 248 | { |
6ba8e26f | 249 | enum tui_layout_type cur_layout = tui_current_layout (); |
c906108c SS |
250 | |
251 | switch (type) | |
252 | { | |
253 | case SRC_WIN: | |
e5908723 MS |
254 | if (cur_layout != SRC_COMMAND |
255 | && cur_layout != SRC_DISASSEM_COMMAND | |
256 | && cur_layout != SRC_DATA_COMMAND) | |
c906108c | 257 | { |
dd1abb8c | 258 | tui_clear_source_windows_detail (); |
6ba8e26f AC |
259 | if (cur_layout == DISASSEM_DATA_COMMAND) |
260 | show_layout (SRC_DATA_COMMAND); | |
c906108c | 261 | else |
6ba8e26f | 262 | show_layout (SRC_COMMAND); |
c906108c SS |
263 | } |
264 | break; | |
265 | case DISASSEM_WIN: | |
e5908723 MS |
266 | if (cur_layout != DISASSEM_COMMAND |
267 | && cur_layout != SRC_DISASSEM_COMMAND | |
268 | && cur_layout != DISASSEM_DATA_COMMAND) | |
c906108c | 269 | { |
dd1abb8c | 270 | tui_clear_source_windows_detail (); |
6ba8e26f AC |
271 | if (cur_layout == SRC_DATA_COMMAND) |
272 | show_layout (DISASSEM_DATA_COMMAND); | |
c906108c | 273 | else |
6ba8e26f | 274 | show_layout (DISASSEM_COMMAND); |
c906108c SS |
275 | } |
276 | break; | |
277 | case DATA_WIN: | |
e5908723 MS |
278 | if (cur_layout != SRC_DATA_COMMAND |
279 | && cur_layout != DISASSEM_DATA_COMMAND) | |
c906108c | 280 | { |
6ba8e26f AC |
281 | if (cur_layout == DISASSEM_COMMAND) |
282 | show_layout (DISASSEM_DATA_COMMAND); | |
c906108c | 283 | else |
6ba8e26f | 284 | show_layout (SRC_DATA_COMMAND); |
c906108c SS |
285 | } |
286 | break; | |
287 | default: | |
288 | break; | |
289 | } | |
6ba8e26f | 290 | } |
c906108c SS |
291 | |
292 | ||
6ba8e26f AC |
293 | /* Answer the height of a window. If it hasn't been created yet, |
294 | answer what the height of a window would be based upon its type and | |
295 | the layout. */ | |
c906108c | 296 | int |
08ef48c5 MS |
297 | tui_default_win_height (enum tui_win_type type, |
298 | enum tui_layout_type layout) | |
c906108c SS |
299 | { |
300 | int h; | |
301 | ||
cafb3438 | 302 | if (tui_win_list[type] != NULL) |
6d012f14 | 303 | h = tui_win_list[type]->generic.height; |
c906108c SS |
304 | else |
305 | { | |
306 | switch (layout) | |
307 | { | |
308 | case SRC_COMMAND: | |
309 | case DISASSEM_COMMAND: | |
6d012f14 | 310 | if (TUI_CMD_WIN == NULL) |
dd1abb8c | 311 | h = tui_term_height () / 2; |
c906108c | 312 | else |
6d012f14 | 313 | h = tui_term_height () - TUI_CMD_WIN->generic.height; |
c906108c SS |
314 | break; |
315 | case SRC_DISASSEM_COMMAND: | |
316 | case SRC_DATA_COMMAND: | |
317 | case DISASSEM_DATA_COMMAND: | |
6d012f14 | 318 | if (TUI_CMD_WIN == NULL) |
dd1abb8c | 319 | h = tui_term_height () / 3; |
c906108c | 320 | else |
6d012f14 | 321 | h = (tui_term_height () - TUI_CMD_WIN->generic.height) / 2; |
c906108c SS |
322 | break; |
323 | default: | |
324 | h = 0; | |
325 | break; | |
326 | } | |
327 | } | |
328 | ||
329 | return h; | |
6ba8e26f | 330 | } |
c906108c SS |
331 | |
332 | ||
080ce8c0 AC |
333 | /* Answer the height of a window. If it hasn't been created yet, |
334 | answer what the height of a window would be based upon its type and | |
335 | the layout. */ | |
c906108c | 336 | int |
080ce8c0 AC |
337 | tui_default_win_viewport_height (enum tui_win_type type, |
338 | enum tui_layout_type layout) | |
c906108c SS |
339 | { |
340 | int h; | |
341 | ||
6ba8e26f | 342 | h = tui_default_win_height (type, layout); |
c906108c | 343 | |
6d012f14 | 344 | if (tui_win_list[type] == TUI_CMD_WIN) |
c906108c SS |
345 | h -= 1; |
346 | else | |
347 | h -= 2; | |
348 | ||
349 | return h; | |
6ba8e26f | 350 | } |
c906108c | 351 | |
a0145030 AB |
352 | /* Complete possible layout names. TEXT is the complete text entered so |
353 | far, WORD is the word currently being completed. */ | |
354 | ||
eb3ff9a5 | 355 | static void |
a0145030 | 356 | layout_completer (struct cmd_list_element *ignore, |
eb3ff9a5 | 357 | completion_tracker &tracker, |
a0145030 AB |
358 | const char *text, const char *word) |
359 | { | |
360 | static const char *layout_names [] = | |
361 | { "src", "asm", "split", "regs", "next", "prev", NULL }; | |
362 | ||
eb3ff9a5 | 363 | complete_on_enum (tracker, layout_names, text, word); |
a0145030 AB |
364 | } |
365 | ||
6ba8e26f AC |
366 | /* Function to initialize gdb commands, for tui window layout |
367 | manipulation. */ | |
2c0b251b | 368 | |
c906108c | 369 | void |
6ba8e26f | 370 | _initialize_tui_layout (void) |
c906108c | 371 | { |
a0145030 AB |
372 | struct cmd_list_element *cmd; |
373 | ||
374 | cmd = add_com ("layout", class_tui, tui_layout_command, _("\ | |
1bedd215 | 375 | Change the layout of windows.\n\ |
bf212be1 | 376 | Usage: layout prev | next | LAYOUT-NAME\n\ |
c906108c SS |
377 | Layout names are:\n\ |
378 | src : Displays source and command windows.\n\ | |
379 | asm : Displays disassembly and command windows.\n\ | |
380 | split : Displays source, disassembly and command windows.\n\ | |
381 | regs : Displays register window. If existing layout\n\ | |
382 | is source/command or assembly/command, the \n\ | |
383 | register window is displayed. If the\n\ | |
384 | source/assembly/command (split) is displayed, \n\ | |
385 | the register window is displayed with \n\ | |
89549d7f | 386 | the window that has current logical focus.")); |
a0145030 | 387 | set_cmd_completer (cmd, layout_completer); |
41783295 | 388 | } |
c906108c SS |
389 | |
390 | ||
391 | /************************* | |
392 | ** STATIC LOCAL FUNCTIONS | |
393 | **************************/ | |
394 | ||
395 | ||
7bd0be3a AB |
396 | /* Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA, or |
397 | REGS. */ | |
22940a24 | 398 | enum tui_status |
7bd0be3a | 399 | tui_set_layout_by_name (const char *layout_name) |
c906108c | 400 | { |
22940a24 | 401 | enum tui_status status = TUI_SUCCESS; |
c906108c | 402 | |
63a33118 | 403 | if (layout_name != NULL) |
c906108c | 404 | { |
d02c80cd | 405 | int i; |
6ba8e26f | 406 | enum tui_layout_type new_layout = UNDEFINED_LAYOUT; |
6ba8e26f | 407 | enum tui_layout_type cur_layout = tui_current_layout (); |
c906108c | 408 | |
f71c8822 TT |
409 | std::string copy = layout_name; |
410 | for (i = 0; i < copy.size (); i++) | |
411 | copy[i] = toupper (copy[i]); | |
412 | const char *buf_ptr = copy.c_str (); | |
c906108c | 413 | |
1cc6d956 | 414 | /* First check for ambiguous input. */ |
7bd0be3a | 415 | if (strlen (buf_ptr) <= 1 && *buf_ptr == 'S') |
c906108c | 416 | { |
8a3fe4f8 | 417 | warning (_("Ambiguous command input.")); |
c906108c SS |
418 | status = TUI_FAILURE; |
419 | } | |
420 | else | |
421 | { | |
6ba8e26f AC |
422 | if (subset_compare (buf_ptr, "SRC")) |
423 | new_layout = SRC_COMMAND; | |
424 | else if (subset_compare (buf_ptr, "ASM")) | |
425 | new_layout = DISASSEM_COMMAND; | |
426 | else if (subset_compare (buf_ptr, "SPLIT")) | |
427 | new_layout = SRC_DISASSEM_COMMAND; | |
7bd0be3a | 428 | else if (subset_compare (buf_ptr, "REGS")) |
c906108c | 429 | { |
7bd0be3a | 430 | if (cur_layout == SRC_COMMAND |
e5908723 | 431 | || cur_layout == SRC_DATA_COMMAND) |
6ba8e26f | 432 | new_layout = SRC_DATA_COMMAND; |
c906108c | 433 | else |
6ba8e26f | 434 | new_layout = DISASSEM_DATA_COMMAND; |
c906108c | 435 | } |
6ba8e26f AC |
436 | else if (subset_compare (buf_ptr, "NEXT")) |
437 | new_layout = next_layout (); | |
438 | else if (subset_compare (buf_ptr, "PREV")) | |
439 | new_layout = prev_layout (); | |
c906108c SS |
440 | else |
441 | status = TUI_FAILURE; | |
c906108c | 442 | |
880d1e40 AB |
443 | if (status == TUI_SUCCESS) |
444 | { | |
445 | /* Make sure the curses mode is enabled. */ | |
446 | tui_enable (); | |
447 | tui_set_layout (new_layout); | |
448 | } | |
c906108c SS |
449 | } |
450 | } | |
451 | else | |
452 | status = TUI_FAILURE; | |
453 | ||
454 | return status; | |
e8b915dc | 455 | } |
c906108c SS |
456 | |
457 | ||
13274fc3 UW |
458 | static void |
459 | extract_display_start_addr (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p) | |
c906108c | 460 | { |
6ba8e26f | 461 | enum tui_layout_type cur_layout = tui_current_layout (); |
957b8b5a | 462 | struct gdbarch *gdbarch = get_current_arch (); |
c774cec6 | 463 | CORE_ADDR addr; |
84b1e7c7 | 464 | CORE_ADDR pc; |
52575520 | 465 | struct symtab_and_line cursal = get_current_source_symtab_and_line (); |
c906108c | 466 | |
6ba8e26f | 467 | switch (cur_layout) |
c906108c SS |
468 | { |
469 | case SRC_COMMAND: | |
470 | case SRC_DATA_COMMAND: | |
e6e41501 | 471 | gdbarch = TUI_SRC_WIN->gdbarch; |
52575520 | 472 | find_line_pc (cursal.symtab, |
e6e41501 | 473 | TUI_SRC_WIN->start_line_or_addr.u.line_no, |
84b1e7c7 | 474 | &pc); |
c774cec6 | 475 | addr = pc; |
c906108c SS |
476 | break; |
477 | case DISASSEM_COMMAND: | |
478 | case SRC_DISASSEM_COMMAND: | |
479 | case DISASSEM_DATA_COMMAND: | |
e6e41501 TT |
480 | gdbarch = TUI_DISASM_WIN->gdbarch; |
481 | addr = TUI_DISASM_WIN->start_line_or_addr.u.addr; | |
c906108c SS |
482 | break; |
483 | default: | |
c774cec6 | 484 | addr = 0; |
c906108c SS |
485 | break; |
486 | } | |
487 | ||
13274fc3 UW |
488 | *gdbarch_p = gdbarch; |
489 | *addr_p = addr; | |
6ba8e26f | 490 | } |
c906108c SS |
491 | |
492 | ||
c906108c | 493 | static void |
0b39b52e | 494 | tui_layout_command (const char *arg, int from_tty) |
c906108c | 495 | { |
19eb139b | 496 | /* Switch to the selected layout. */ |
7bd0be3a | 497 | if (tui_set_layout_by_name (arg) != TUI_SUCCESS) |
8a3fe4f8 | 498 | warning (_("Invalid layout specified.\n%s"), LAYOUT_USAGE); |
e8b915dc | 499 | } |
c906108c | 500 | |
6ba8e26f | 501 | /* Answer the previous layout to cycle to. */ |
2a8854a7 | 502 | static enum tui_layout_type |
6ba8e26f | 503 | next_layout (void) |
c906108c | 504 | { |
570dc176 | 505 | int new_layout; |
c906108c | 506 | |
6ba8e26f AC |
507 | new_layout = tui_current_layout (); |
508 | if (new_layout == UNDEFINED_LAYOUT) | |
509 | new_layout = SRC_COMMAND; | |
c906108c SS |
510 | else |
511 | { | |
6ba8e26f AC |
512 | new_layout++; |
513 | if (new_layout == UNDEFINED_LAYOUT) | |
514 | new_layout = SRC_COMMAND; | |
c906108c SS |
515 | } |
516 | ||
570dc176 | 517 | return (enum tui_layout_type) new_layout; |
6ba8e26f | 518 | } |
c906108c SS |
519 | |
520 | ||
6ba8e26f | 521 | /* Answer the next layout to cycle to. */ |
2a8854a7 | 522 | static enum tui_layout_type |
6ba8e26f | 523 | prev_layout (void) |
c906108c | 524 | { |
570dc176 | 525 | int new_layout; |
c906108c | 526 | |
6ba8e26f AC |
527 | new_layout = tui_current_layout (); |
528 | if (new_layout == SRC_COMMAND) | |
529 | new_layout = DISASSEM_DATA_COMMAND; | |
c906108c SS |
530 | else |
531 | { | |
6ba8e26f AC |
532 | new_layout--; |
533 | if (new_layout == UNDEFINED_LAYOUT) | |
534 | new_layout = DISASSEM_DATA_COMMAND; | |
c906108c SS |
535 | } |
536 | ||
570dc176 | 537 | return (enum tui_layout_type) new_layout; |
6ba8e26f | 538 | } |
c906108c SS |
539 | |
540 | ||
541 | ||
82432e10 TT |
542 | static struct tui_win_info * |
543 | make_command_window (int height, int origin_y) | |
c906108c | 544 | { |
82432e10 TT |
545 | struct tui_win_info *result |
546 | = (struct tui_win_info *) init_and_make_win (NULL, | |
19ba03f4 SM |
547 | CMD_WIN, |
548 | height, | |
549 | tui_term_width (), | |
550 | 0, | |
551 | origin_y, | |
552 | DONT_BOX_WINDOW); | |
82432e10 TT |
553 | result->can_highlight = FALSE; |
554 | return result; | |
6ba8e26f | 555 | } |
c906108c SS |
556 | |
557 | ||
ef5eab5a | 558 | /* make_source_window(). |
c5aa993b | 559 | */ |
0ed69eda TT |
560 | static struct tui_win_info * |
561 | make_source_window (int height, int origin_y) | |
c906108c | 562 | { |
0ed69eda | 563 | return make_source_or_disasm_window (SRC_WIN, height, origin_y); |
6ba8e26f | 564 | } /* make_source_window */ |
c906108c SS |
565 | |
566 | ||
ef5eab5a | 567 | /* make_disasm_window(). |
c5aa993b | 568 | */ |
0ed69eda TT |
569 | static struct tui_win_info * |
570 | make_disasm_window (int height, int origin_y) | |
c906108c | 571 | { |
0ed69eda | 572 | return make_source_or_disasm_window (DISASSEM_WIN, height, origin_y); |
6ba8e26f | 573 | } /* make_disasm_window */ |
c906108c SS |
574 | |
575 | ||
c906108c | 576 | static void |
08ef48c5 MS |
577 | make_data_window (struct tui_win_info **win_info_ptr, |
578 | int height, int origin_y) | |
c906108c | 579 | { |
19ba03f4 SM |
580 | *win_info_ptr |
581 | = (struct tui_win_info *) init_and_make_win (*win_info_ptr, | |
582 | DATA_WIN, | |
583 | height, | |
584 | tui_term_width (), | |
585 | 0, | |
586 | origin_y, | |
587 | BOX_WINDOW); | |
6ba8e26f | 588 | } |
c906108c SS |
589 | |
590 | ||
591 | ||
6ba8e26f | 592 | /* Show the Source/Command layout. */ |
c906108c | 593 | static void |
6ba8e26f | 594 | show_source_command (void) |
c906108c | 595 | { |
6ba8e26f AC |
596 | show_source_or_disasm_and_command (SRC_COMMAND); |
597 | } | |
c906108c SS |
598 | |
599 | ||
6ba8e26f | 600 | /* Show the Dissassem/Command layout. */ |
c906108c | 601 | static void |
6ba8e26f | 602 | show_disasm_command (void) |
c906108c | 603 | { |
6ba8e26f AC |
604 | show_source_or_disasm_and_command (DISASSEM_COMMAND); |
605 | } | |
c906108c SS |
606 | |
607 | ||
6ba8e26f | 608 | /* Show the Source/Disassem/Command layout. */ |
c906108c | 609 | static void |
6ba8e26f | 610 | show_source_disasm_command (void) |
c906108c | 611 | { |
dd1abb8c | 612 | if (tui_current_layout () != SRC_DISASSEM_COMMAND) |
c906108c | 613 | { |
6ba8e26f | 614 | int cmd_height, src_height, asm_height; |
c906108c | 615 | |
6d012f14 | 616 | if (TUI_CMD_WIN != NULL) |
6ba8e26f | 617 | cmd_height = TUI_CMD_WIN->generic.height; |
c906108c | 618 | else |
6ba8e26f | 619 | cmd_height = tui_term_height () / 3; |
c906108c | 620 | |
6ba8e26f AC |
621 | src_height = (tui_term_height () - cmd_height) / 2; |
622 | asm_height = tui_term_height () - (src_height + cmd_height); | |
c906108c | 623 | |
6d012f14 | 624 | if (TUI_SRC_WIN == NULL) |
e6e41501 | 625 | tui_win_list[SRC_WIN] = make_source_window (src_height, 0); |
c906108c SS |
626 | else |
627 | { | |
6ba8e26f | 628 | init_gen_win_info (&TUI_SRC_WIN->generic, |
08ef48c5 MS |
629 | TUI_SRC_WIN->generic.type, |
630 | src_height, | |
631 | TUI_SRC_WIN->generic.width, | |
e6e41501 | 632 | TUI_SRC_WIN->execution_info->width, |
08ef48c5 | 633 | 0); |
6d012f14 | 634 | TUI_SRC_WIN->can_highlight = TRUE; |
e6e41501 | 635 | init_gen_win_info (TUI_SRC_WIN->execution_info, |
08ef48c5 MS |
636 | EXEC_INFO_WIN, |
637 | src_height, | |
638 | 3, | |
639 | 0, | |
640 | 0); | |
6d012f14 | 641 | tui_make_visible (&TUI_SRC_WIN->generic); |
e6e41501 TT |
642 | tui_make_visible (TUI_SRC_WIN->execution_info); |
643 | TUI_SRC_WIN->m_has_locator = false; | |
c906108c | 644 | } |
c906108c | 645 | |
82432e10 TT |
646 | struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); |
647 | ||
648 | tui_show_source_content (TUI_SRC_WIN); | |
649 | if (TUI_DISASM_WIN == NULL) | |
650 | { | |
e6e41501 TT |
651 | tui_win_list[DISASSEM_WIN] |
652 | = make_disasm_window (asm_height, src_height - 1); | |
82432e10 TT |
653 | locator |
654 | = ((struct tui_gen_win_info *) | |
655 | init_and_make_win (locator, | |
656 | LOCATOR_WIN, | |
657 | 2 /* 1 */ , | |
658 | tui_term_width (), | |
659 | 0, | |
660 | (src_height + asm_height) - 1, | |
661 | DONT_BOX_WINDOW)); | |
662 | } | |
663 | else | |
664 | { | |
665 | init_gen_win_info (locator, | |
666 | LOCATOR_WIN, | |
667 | 2 /* 1 */ , | |
668 | tui_term_width (), | |
669 | 0, | |
670 | (src_height + asm_height) - 1); | |
e6e41501 | 671 | TUI_DISASM_WIN->m_has_locator = true; |
82432e10 TT |
672 | init_gen_win_info (&TUI_DISASM_WIN->generic, |
673 | TUI_DISASM_WIN->generic.type, | |
674 | asm_height, | |
675 | TUI_DISASM_WIN->generic.width, | |
e6e41501 | 676 | TUI_DISASM_WIN->execution_info->width, |
82432e10 | 677 | src_height - 1); |
e6e41501 | 678 | init_gen_win_info (TUI_DISASM_WIN->execution_info, |
82432e10 TT |
679 | EXEC_INFO_WIN, |
680 | asm_height, | |
681 | 3, | |
682 | 0, | |
683 | src_height - 1); | |
684 | TUI_DISASM_WIN->can_highlight = TRUE; | |
685 | tui_make_visible (&TUI_DISASM_WIN->generic); | |
e6e41501 | 686 | tui_make_visible (TUI_DISASM_WIN->execution_info); |
82432e10 | 687 | } |
e6e41501 TT |
688 | TUI_SRC_WIN->m_has_locator = false; |
689 | TUI_DISASM_WIN->m_has_locator = true; | |
82432e10 TT |
690 | tui_make_visible (locator); |
691 | tui_show_locator_content (); | |
692 | tui_show_source_content (TUI_DISASM_WIN); | |
693 | ||
694 | if (TUI_CMD_WIN == NULL) | |
695 | TUI_CMD_WIN = make_command_window (cmd_height, | |
696 | tui_term_height () - cmd_height); | |
697 | else | |
698 | { | |
699 | init_gen_win_info (&TUI_CMD_WIN->generic, | |
700 | TUI_CMD_WIN->generic.type, | |
701 | TUI_CMD_WIN->generic.height, | |
702 | TUI_CMD_WIN->generic.width, | |
703 | 0, | |
704 | TUI_CMD_WIN->generic.origin.y); | |
705 | TUI_CMD_WIN->can_highlight = FALSE; | |
706 | tui_make_visible (&TUI_CMD_WIN->generic); | |
c906108c | 707 | } |
82432e10 | 708 | tui_refresh_win (&TUI_CMD_WIN->generic); |
dd1abb8c | 709 | tui_set_current_layout_to (SRC_DISASSEM_COMMAND); |
c906108c | 710 | } |
6ba8e26f | 711 | } |
c906108c SS |
712 | |
713 | ||
6ba8e26f AC |
714 | /* Show the Source/Data/Command or the Dissassembly/Data/Command |
715 | layout. */ | |
c906108c | 716 | static void |
6ba8e26f | 717 | show_data (enum tui_layout_type new_layout) |
c906108c | 718 | { |
6ba8e26f AC |
719 | int total_height = (tui_term_height () - TUI_CMD_WIN->generic.height); |
720 | int src_height, data_height; | |
721 | enum tui_win_type win_type; | |
5b6fe301 | 722 | struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); |
c906108c SS |
723 | |
724 | ||
6ba8e26f AC |
725 | data_height = total_height / 2; |
726 | src_height = total_height - data_height; | |
ec7d9e56 AC |
727 | tui_make_all_invisible (); |
728 | tui_make_invisible (locator); | |
6ba8e26f | 729 | make_data_window (&TUI_DATA_WIN, data_height, 0); |
6d012f14 | 730 | TUI_DATA_WIN->can_highlight = TRUE; |
6ba8e26f AC |
731 | if (new_layout == SRC_DATA_COMMAND) |
732 | win_type = SRC_WIN; | |
c906108c | 733 | else |
6ba8e26f | 734 | win_type = DISASSEM_WIN; |
e6e41501 TT |
735 | |
736 | tui_source_window_base *base; | |
6ba8e26f | 737 | if (tui_win_list[win_type] == NULL) |
c906108c | 738 | { |
6ba8e26f | 739 | if (win_type == SRC_WIN) |
0ed69eda TT |
740 | tui_win_list[win_type] |
741 | = make_source_window (src_height, data_height - 1); | |
c906108c | 742 | else |
0ed69eda TT |
743 | tui_win_list[win_type] |
744 | = make_disasm_window (src_height, data_height - 1); | |
19ba03f4 SM |
745 | locator |
746 | = ((struct tui_gen_win_info *) | |
747 | init_and_make_win (locator, | |
748 | LOCATOR_WIN, | |
749 | 2 /* 1 */ , | |
750 | tui_term_width (), | |
751 | 0, | |
752 | total_height - 1, | |
753 | DONT_BOX_WINDOW)); | |
e6e41501 | 754 | base = (tui_source_window_base *) tui_win_list[win_type]; |
c906108c SS |
755 | } |
756 | else | |
757 | { | |
e6e41501 | 758 | base = (tui_source_window_base *) tui_win_list[win_type]; |
6ba8e26f | 759 | init_gen_win_info (&tui_win_list[win_type]->generic, |
08ef48c5 MS |
760 | tui_win_list[win_type]->generic.type, |
761 | src_height, | |
762 | tui_win_list[win_type]->generic.width, | |
e6e41501 | 763 | base->execution_info->width, |
08ef48c5 | 764 | data_height - 1); |
e6e41501 | 765 | init_gen_win_info (base->execution_info, |
08ef48c5 MS |
766 | EXEC_INFO_WIN, |
767 | src_height, | |
768 | 3, | |
769 | 0, | |
770 | data_height - 1); | |
6ba8e26f | 771 | tui_make_visible (&tui_win_list[win_type]->generic); |
e6e41501 | 772 | tui_make_visible (base->execution_info); |
6ba8e26f | 773 | init_gen_win_info (locator, |
08ef48c5 MS |
774 | LOCATOR_WIN, |
775 | 2 /* 1 */ , | |
776 | tui_term_width (), | |
777 | 0, | |
778 | total_height - 1); | |
c906108c | 779 | } |
e6e41501 | 780 | base->m_has_locator = true; |
ec7d9e56 | 781 | tui_make_visible (locator); |
47d3492a | 782 | tui_show_locator_content (); |
6ba8e26f AC |
783 | tui_add_to_source_windows (tui_win_list[win_type]); |
784 | tui_set_current_layout_to (new_layout); | |
785 | } | |
c906108c | 786 | |
ef5eab5a | 787 | /* init_gen_win_info(). |
c5aa993b | 788 | */ |
c906108c | 789 | static void |
08ef48c5 MS |
790 | init_gen_win_info (struct tui_gen_win_info *win_info, |
791 | enum tui_win_type type, | |
792 | int height, int width, | |
793 | int origin_x, int origin_y) | |
c906108c SS |
794 | { |
795 | int h = height; | |
796 | ||
6ba8e26f AC |
797 | win_info->type = type; |
798 | win_info->width = width; | |
799 | win_info->height = h; | |
c906108c SS |
800 | if (h > 1) |
801 | { | |
6ba8e26f AC |
802 | win_info->viewport_height = h - 1; |
803 | if (win_info->type != CMD_WIN) | |
804 | win_info->viewport_height--; | |
c906108c SS |
805 | } |
806 | else | |
6ba8e26f AC |
807 | win_info->viewport_height = 1; |
808 | win_info->origin.x = origin_x; | |
809 | win_info->origin.y = origin_y; | |
c906108c SS |
810 | |
811 | return; | |
6ba8e26f | 812 | } /* init_gen_win_info */ |
c906108c | 813 | |
ef5eab5a | 814 | /* init_and_make_win(). |
c5aa993b | 815 | */ |
d5d6fca5 | 816 | static void * |
08ef48c5 MS |
817 | init_and_make_win (void *opaque_win_info, |
818 | enum tui_win_type win_type, | |
819 | int height, int width, | |
820 | int origin_x, int origin_y, | |
d5d6fca5 | 821 | int box_it) |
c906108c | 822 | { |
5b6fe301 | 823 | struct tui_gen_win_info *generic; |
c906108c | 824 | |
6ba8e26f | 825 | if (opaque_win_info == NULL) |
c906108c | 826 | { |
6ba8e26f AC |
827 | if (tui_win_is_auxillary (win_type)) |
828 | opaque_win_info = (void *) tui_alloc_generic_win_info (); | |
c906108c | 829 | else |
6ba8e26f | 830 | opaque_win_info = (void *) tui_alloc_win_info (win_type); |
c906108c | 831 | } |
6ba8e26f AC |
832 | if (tui_win_is_auxillary (win_type)) |
833 | generic = (struct tui_gen_win_info *) opaque_win_info; | |
c906108c | 834 | else |
6ba8e26f | 835 | generic = &((struct tui_win_info *) opaque_win_info)->generic; |
c906108c | 836 | |
ec328aa5 TT |
837 | init_gen_win_info (generic, win_type, height, width, origin_x, origin_y); |
838 | if (!tui_win_is_auxillary (win_type)) | |
c906108c | 839 | { |
ec328aa5 TT |
840 | if (generic->type == CMD_WIN) |
841 | ((struct tui_win_info *) opaque_win_info)->can_highlight = FALSE; | |
842 | else | |
843 | ((struct tui_win_info *) opaque_win_info)->can_highlight = TRUE; | |
c906108c | 844 | } |
ec328aa5 TT |
845 | tui_make_window (generic, box_it); |
846 | ||
d5d6fca5 | 847 | return opaque_win_info; |
bc712bbf | 848 | } |
c906108c SS |
849 | |
850 | ||
0ed69eda TT |
851 | static struct tui_win_info * |
852 | make_source_or_disasm_window (enum tui_win_type type, | |
08ef48c5 | 853 | int height, int origin_y) |
c906108c | 854 | { |
e65b5245 | 855 | struct tui_gen_win_info *execution_info = NULL; |
c906108c | 856 | |
ef5eab5a | 857 | /* Create the exeuction info window. */ |
c906108c | 858 | if (type == SRC_WIN) |
6d012f14 | 859 | execution_info = tui_source_exec_info_win_ptr (); |
c906108c | 860 | else |
6d012f14 | 861 | execution_info = tui_disassem_exec_info_win_ptr (); |
19ba03f4 SM |
862 | execution_info |
863 | = ((struct tui_gen_win_info *) | |
864 | init_and_make_win (execution_info, | |
865 | EXEC_INFO_WIN, | |
866 | height, | |
867 | 3, | |
868 | 0, | |
869 | origin_y, | |
870 | DONT_BOX_WINDOW)); | |
ef5eab5a MS |
871 | |
872 | /* Now create the source window. */ | |
e6e41501 TT |
873 | struct tui_source_window_base *result |
874 | = ((struct tui_source_window_base *) | |
0ed69eda | 875 | init_and_make_win (NULL, |
19ba03f4 SM |
876 | type, |
877 | height, | |
878 | tui_term_width () - execution_info->width, | |
879 | execution_info->width, | |
880 | origin_y, | |
881 | BOX_WINDOW)); | |
e6e41501 | 882 | result->execution_info = execution_info; |
0ed69eda | 883 | return result; |
6ba8e26f | 884 | } |
c906108c SS |
885 | |
886 | ||
1cc6d956 | 887 | /* Show the Source/Command or the Disassem layout. */ |
c906108c | 888 | static void |
6ba8e26f | 889 | show_source_or_disasm_and_command (enum tui_layout_type layout_type) |
c906108c | 890 | { |
6ba8e26f | 891 | if (tui_current_layout () != layout_type) |
c906108c | 892 | { |
5b6fe301 | 893 | struct tui_win_info **win_info_ptr; |
6ba8e26f | 894 | int src_height, cmd_height; |
5b6fe301 | 895 | struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); |
c906108c | 896 | |
6d012f14 | 897 | if (TUI_CMD_WIN != NULL) |
6ba8e26f | 898 | cmd_height = TUI_CMD_WIN->generic.height; |
c906108c | 899 | else |
6ba8e26f AC |
900 | cmd_height = tui_term_height () / 3; |
901 | src_height = tui_term_height () - cmd_height; | |
c906108c | 902 | |
6ba8e26f | 903 | if (layout_type == SRC_COMMAND) |
e6e41501 | 904 | win_info_ptr = &tui_win_list[SRC_WIN]; |
c906108c | 905 | else |
e6e41501 | 906 | win_info_ptr = &tui_win_list[DISASSEM_WIN]; |
c906108c | 907 | |
e6e41501 | 908 | tui_source_window_base *base; |
6ba8e26f | 909 | if ((*win_info_ptr) == NULL) |
c906108c | 910 | { |
6ba8e26f | 911 | if (layout_type == SRC_COMMAND) |
0ed69eda | 912 | *win_info_ptr = make_source_window (src_height - 1, 0); |
c906108c | 913 | else |
0ed69eda | 914 | *win_info_ptr = make_disasm_window (src_height - 1, 0); |
19ba03f4 SM |
915 | locator |
916 | = ((struct tui_gen_win_info *) | |
917 | init_and_make_win (locator, | |
918 | LOCATOR_WIN, | |
919 | 2 /* 1 */ , | |
920 | tui_term_width (), | |
921 | 0, | |
922 | src_height - 1, | |
923 | DONT_BOX_WINDOW)); | |
e6e41501 | 924 | base = (tui_source_window_base *) *win_info_ptr; |
c906108c SS |
925 | } |
926 | else | |
927 | { | |
e6e41501 | 928 | base = (tui_source_window_base *) *win_info_ptr; |
6ba8e26f | 929 | init_gen_win_info (locator, |
08ef48c5 MS |
930 | LOCATOR_WIN, |
931 | 2 /* 1 */ , | |
932 | tui_term_width (), | |
933 | 0, | |
934 | src_height - 1); | |
e6e41501 | 935 | base->m_has_locator = true; |
08ef48c5 MS |
936 | init_gen_win_info (&(*win_info_ptr)->generic, |
937 | (*win_info_ptr)->generic.type, | |
938 | src_height - 1, | |
939 | (*win_info_ptr)->generic.width, | |
e6e41501 | 940 | base->execution_info->width, |
08ef48c5 | 941 | 0); |
e6e41501 | 942 | init_gen_win_info (base->execution_info, |
08ef48c5 MS |
943 | EXEC_INFO_WIN, |
944 | src_height - 1, | |
945 | 3, | |
946 | 0, | |
947 | 0); | |
e6e41501 | 948 | base->can_highlight = TRUE; |
6ba8e26f | 949 | tui_make_visible (&(*win_info_ptr)->generic); |
e6e41501 | 950 | tui_make_visible (base->execution_info); |
c906108c | 951 | } |
6ba8e26f | 952 | if ((*win_info_ptr) != NULL) |
c906108c | 953 | { |
e6e41501 | 954 | base->m_has_locator = true; |
ec7d9e56 | 955 | tui_make_visible (locator); |
47d3492a | 956 | tui_show_locator_content (); |
6ba8e26f | 957 | tui_show_source_content (*win_info_ptr); |
c906108c | 958 | |
6d012f14 | 959 | if (TUI_CMD_WIN == NULL) |
c906108c | 960 | { |
82432e10 | 961 | TUI_CMD_WIN = make_command_window (cmd_height, src_height); |
6d012f14 | 962 | tui_refresh_win (&TUI_CMD_WIN->generic); |
c906108c SS |
963 | } |
964 | else | |
965 | { | |
6ba8e26f | 966 | init_gen_win_info (&TUI_CMD_WIN->generic, |
08ef48c5 MS |
967 | TUI_CMD_WIN->generic.type, |
968 | TUI_CMD_WIN->generic.height, | |
969 | TUI_CMD_WIN->generic.width, | |
970 | TUI_CMD_WIN->generic.origin.x, | |
971 | TUI_CMD_WIN->generic.origin.y); | |
6d012f14 AC |
972 | TUI_CMD_WIN->can_highlight = FALSE; |
973 | tui_make_visible (&TUI_CMD_WIN->generic); | |
c906108c SS |
974 | } |
975 | } | |
6ba8e26f | 976 | tui_set_current_layout_to (layout_type); |
c906108c | 977 | } |
6ba8e26f | 978 | } |