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