⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tui-layout.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* TUI layout window management.   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software   Foundation, Inc.   Contributed by Hewlett-Packard Company.   This file is part of GDB.   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place - Suite 330,   Boston, MA 02111-1307, USA.  */#include "defs.h"#include "command.h"#include "symtab.h"#include "frame.h"#include "source.h"#include <ctype.h>#include "tui/tui.h"#include "tui/tui-data.h"#include "tui/tui-windata.h"#include "tui/tui-wingeneral.h"#include "tui/tui-stack.h"#include "tui/tui-regs.h"#include "tui/tui-win.h"#include "tui/tui-winsource.h"#include "tui/tui-disasm.h"#include "gdb_string.h"#include "gdb_curses.h"/********************************* Static Local Decls********************************/static void show_layout (enum tui_layout_type);static void init_gen_win_info (struct tui_gen_win_info *, enum tui_win_type, int, int, int, int);static void init_and_make_win (void **, enum tui_win_type, int, int, int, int, int);static void show_source_or_disasm_and_command (enum tui_layout_type);static void make_source_or_disasm_window (struct tui_win_info * *, enum tui_win_type, int, int);static void make_command_window (struct tui_win_info * *, int, int);static void make_source_window (struct tui_win_info * *, int, int);static void make_disasm_window (struct tui_win_info * *, int, int);static void make_data_window (struct tui_win_info * *, int, int);static void show_source_command (void);static void show_disasm_command (void);static void show_source_disasm_command (void);static void show_data (enum tui_layout_type);static enum tui_layout_type next_layout (void);static enum tui_layout_type prev_layout (void);static void tui_layout_command (char *, int);static void tui_toggle_layout_command (char *, int);static void tui_toggle_split_layout_command (char *, int);static CORE_ADDR extract_display_start_addr (void);static void tui_handle_xdb_layout (struct tui_layout_def *);/***************************************** DEFINITIONS***************************************/#define LAYOUT_USAGE     "Usage: layout prev | next | <layout_name> \n"/* Show the screen layout defined.  */static voidshow_layout (enum tui_layout_type layout){  enum tui_layout_type cur_layout = tui_current_layout ();  if (layout != cur_layout)    {      /*         ** Since the new layout may cause changes in window size, we         ** should free the content and reallocate on next display of         ** source/asm       */      tui_free_all_source_wins_content ();      tui_clear_source_windows ();      if (layout == SRC_DATA_COMMAND || layout == DISASSEM_DATA_COMMAND)	{	  show_data (layout);	  tui_refresh_all (tui_win_list);	}      else	{	  /* First make the current layout be invisible */	  tui_make_all_invisible ();	  tui_make_invisible (tui_locator_win_info_ptr ());	  switch (layout)	    {	      /* Now show the new layout */	    case SRC_COMMAND:	      show_source_command ();	      tui_add_to_source_windows (TUI_SRC_WIN);	      break;	    case DISASSEM_COMMAND:	      show_disasm_command ();	      tui_add_to_source_windows (TUI_DISASM_WIN);	      break;	    case SRC_DISASSEM_COMMAND:	      show_source_disasm_command ();	      tui_add_to_source_windows (TUI_SRC_WIN);	      tui_add_to_source_windows (TUI_DISASM_WIN);	      break;	    default:	      break;	    }	}    }}/* Function to set the layout to SRC_COMMAND, DISASSEM_COMMAND,   SRC_DISASSEM_COMMAND, SRC_DATA_COMMAND, or DISASSEM_DATA_COMMAND.   If the layout is SRC_DATA_COMMAND, DISASSEM_DATA_COMMAND, or   UNDEFINED_LAYOUT, then the data window is populated according to   regs_display_type.  */enum tui_statustui_set_layout (enum tui_layout_type layout_type,		enum tui_register_display_type regs_display_type){  enum tui_status status = TUI_SUCCESS;  if (layout_type != UNDEFINED_LAYOUT || regs_display_type != TUI_UNDEFINED_REGS)    {      enum tui_layout_type cur_layout = tui_current_layout (), new_layout = UNDEFINED_LAYOUT;      int regs_populate = FALSE;      CORE_ADDR addr = extract_display_start_addr ();      struct tui_win_info * new_win_with_focus = (struct tui_win_info *) NULL;      struct tui_win_info * win_with_focus = tui_win_with_focus ();      struct tui_layout_def * layout_def = tui_layout_def ();      if (layout_type == UNDEFINED_LAYOUT &&	  regs_display_type != TUI_UNDEFINED_REGS)	{	  if (cur_layout == SRC_DISASSEM_COMMAND)	    new_layout = DISASSEM_DATA_COMMAND;	  else if (cur_layout == SRC_COMMAND || cur_layout == SRC_DATA_COMMAND)	    new_layout = SRC_DATA_COMMAND;	  else if (cur_layout == DISASSEM_COMMAND ||		   cur_layout == DISASSEM_DATA_COMMAND)	    new_layout = DISASSEM_DATA_COMMAND;	}      else	new_layout = layout_type;      regs_populate = (new_layout == SRC_DATA_COMMAND ||		      new_layout == DISASSEM_DATA_COMMAND ||		      regs_display_type != TUI_UNDEFINED_REGS);      if (new_layout != cur_layout || regs_display_type != TUI_UNDEFINED_REGS)	{	  if (new_layout != cur_layout)	    {	      show_layout (new_layout);	      /*	         ** Now determine where focus should be	       */	      if (win_with_focus != TUI_CMD_WIN)		{		  switch (new_layout)		    {		    case SRC_COMMAND:		      tui_set_win_focus_to (TUI_SRC_WIN);		      layout_def->display_mode = SRC_WIN;		      layout_def->split = FALSE;		      break;		    case DISASSEM_COMMAND:		      /* the previous layout was not showing		         ** code. this can happen if there is no		         ** source available:		         ** 1. if the source file is in another dir OR		         ** 2. if target was compiled without -g		         ** We still want to show the assembly though!		       */		      addr = tui_get_begin_asm_address ();		      tui_set_win_focus_to (TUI_DISASM_WIN);		      layout_def->display_mode = DISASSEM_WIN;		      layout_def->split = FALSE;		      break;		    case SRC_DISASSEM_COMMAND:		      /* the previous layout was not showing		         ** code. this can happen if there is no		         ** source available:		         ** 1. if the source file is in another dir OR		         ** 2. if target was compiled without -g		         ** We still want to show the assembly though!		       */		      addr = tui_get_begin_asm_address ();		      if (win_with_focus == TUI_SRC_WIN)			tui_set_win_focus_to (TUI_SRC_WIN);		      else			tui_set_win_focus_to (TUI_DISASM_WIN);		      layout_def->split = TRUE;		      break;		    case SRC_DATA_COMMAND:		      if (win_with_focus != TUI_DATA_WIN)			tui_set_win_focus_to (TUI_SRC_WIN);		      else			tui_set_win_focus_to (TUI_DATA_WIN);		      layout_def->display_mode = SRC_WIN;		      layout_def->split = FALSE;		      break;		    case DISASSEM_DATA_COMMAND:		      /* the previous layout was not showing		         ** code. this can happen if there is no		         ** source available:		         ** 1. if the source file is in another dir OR		         ** 2. if target was compiled without -g		         ** We still want to show the assembly though!		       */		      addr = tui_get_begin_asm_address ();		      if (win_with_focus != TUI_DATA_WIN)			tui_set_win_focus_to (TUI_DISASM_WIN);		      else			tui_set_win_focus_to (TUI_DATA_WIN);		      layout_def->display_mode = DISASSEM_WIN;		      layout_def->split = FALSE;		      break;		    default:		      break;		    }		}	      if (new_win_with_focus != (struct tui_win_info *) NULL)		tui_set_win_focus_to (new_win_with_focus);	      /*	         ** Now update the window content	       */	      if (!regs_populate &&		  (new_layout == SRC_DATA_COMMAND ||		   new_layout == DISASSEM_DATA_COMMAND))		tui_display_all_data ();	      tui_update_source_windows_with_addr (addr);	    }	  if (regs_populate)	    {              tui_show_registers (TUI_DATA_WIN->detail.data_display_info.current_group);	    }	}    }  else    status = TUI_FAILURE;  return status;}/* Add the specified window to the layout in a logical way.  This   means setting up the most logical layout given the window to be   added.  */voidtui_add_win_to_layout (enum tui_win_type type){  enum tui_layout_type cur_layout = tui_current_layout ();  switch (type)    {    case SRC_WIN:      if (cur_layout != SRC_COMMAND &&	  cur_layout != SRC_DISASSEM_COMMAND &&	  cur_layout != SRC_DATA_COMMAND)	{	  tui_clear_source_windows_detail ();	  if (cur_layout == DISASSEM_DATA_COMMAND)	    show_layout (SRC_DATA_COMMAND);	  else	    show_layout (SRC_COMMAND);	}      break;    case DISASSEM_WIN:      if (cur_layout != DISASSEM_COMMAND &&	  cur_layout != SRC_DISASSEM_COMMAND &&	  cur_layout != DISASSEM_DATA_COMMAND)	{	  tui_clear_source_windows_detail ();	  if (cur_layout == SRC_DATA_COMMAND)	    show_layout (DISASSEM_DATA_COMMAND);	  else	    show_layout (DISASSEM_COMMAND);	}      break;    case DATA_WIN:      if (cur_layout != SRC_DATA_COMMAND &&	  cur_layout != DISASSEM_DATA_COMMAND)	{	  if (cur_layout == DISASSEM_COMMAND)	    show_layout (DISASSEM_DATA_COMMAND);	  else	    show_layout (SRC_DATA_COMMAND);	}      break;    default:      break;    }}/* Answer the height of a window.  If it hasn't been created yet,   answer what the height of a window would be based upon its type and   the layout.  */inttui_default_win_height (enum tui_win_type type, enum tui_layout_type layout){  int h;  if (tui_win_list[type] != (struct tui_win_info *) NULL)    h = tui_win_list[type]->generic.height;  else    {      switch (layout)	{	case SRC_COMMAND:	case DISASSEM_COMMAND:	  if (TUI_CMD_WIN == NULL)	    h = tui_term_height () / 2;	  else	    h = tui_term_height () - TUI_CMD_WIN->generic.height;	  break;	case SRC_DISASSEM_COMMAND:	case SRC_DATA_COMMAND:	case DISASSEM_DATA_COMMAND:	  if (TUI_CMD_WIN == NULL)	    h = tui_term_height () / 3;	  else	    h = (tui_term_height () - TUI_CMD_WIN->generic.height) / 2;	  break;	default:	  h = 0;	  break;	}    }  return h;}/* Answer the height of a window.  If it hasn't been created yet,   answer what the height of a window would be based upon its type and   the layout.  */inttui_default_win_viewport_height (enum tui_win_type type,				 enum tui_layout_type layout){  int h;  h = tui_default_win_height (type, layout);  if (tui_win_list[type] == TUI_CMD_WIN)    h -= 1;  else    h -= 2;  return h;}/* Function to initialize gdb commands, for tui window layout   manipulation.  */void_initialize_tui_layout (void){  add_com ("layout", class_tui, tui_layout_command,           "Change the layout of windows.\n\Usage: layout prev | next | <layout_name> \n\Layout names are:\n\   src   : Displays source and command windows.\n\   asm   : Displays disassembly and command windows.\n\   split : Displays source, disassembly and command windows.\n\   regs  : Displays register window. If existing layout\n\           is source/command or assembly/command, the \n\           register window is displayed. If the\n\           source/assembly/command (split) is displayed, \n\           the register window is displayed with \n\           the window that has current logical focus.\n");  if (xdb_commands)    {      add_com ("td", class_tui, tui_toggle_layout_command,               "Toggle between Source/Command and Disassembly/Command layouts.\n");      add_com ("ts", class_tui, tui_toggle_split_layout_command,               "Toggle between Source/Command or Disassembly/Command and \n\Source/Disassembly/Command layouts.\n");    }}/*************************** STATIC LOCAL FUNCTIONS**************************//* Function to set the layout to SRC, ASM, SPLIT, NEXT, PREV, DATA,   REGS, $REGS, $GREGS, $FREGS, $SREGS.  */enum tui_statustui_set_layout_for_display_command (const char *layout_name){  enum tui_status status = TUI_SUCCESS;  if (layout_name != (char *) NULL)    {      int i;      char *buf_ptr;      enum tui_layout_type new_layout = UNDEFINED_LAYOUT;      enum tui_register_display_type dpy_type = TUI_UNDEFINED_REGS;      enum tui_layout_type cur_layout = tui_current_layout ();      buf_ptr = (char *) xstrdup (layout_name);      for (i = 0; (i < strlen (layout_name)); i++)	buf_ptr[i] = toupper (buf_ptr[i]);      /* First check for ambiguous input */      if (strlen (buf_ptr) <= 1 && (*buf_ptr == 'S' || *buf_ptr == '$'))	{	  warning ("Ambiguous command input.\n");	  status = TUI_FAILURE;	}      else	{	  if (subset_compare (buf_ptr, "SRC"))	    new_layout = SRC_COMMAND;	  else if (subset_compare (buf_ptr, "ASM"))	    new_layout = DISASSEM_COMMAND;	  else if (subset_compare (buf_ptr, "SPLIT"))	    new_layout = SRC_DISASSEM_COMMAND;	  else if (subset_compare (buf_ptr, "REGS") ||		   subset_compare (buf_ptr, TUI_GENERAL_SPECIAL_REGS_NAME) ||		   subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME) ||		   subset_compare (buf_ptr, TUI_FLOAT_REGS_NAME) ||		   subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME))	    {	      if (cur_layout == SRC_COMMAND || cur_layout == SRC_DATA_COMMAND)		new_layout = SRC_DATA_COMMAND;	      else		new_layout = DISASSEM_DATA_COMMAND;/* could ifdef out the following code. when compile with -z, there are null    pointer references that cause a core dump if 'layout regs' is the first    layout command issued by the user. HP has asked us to hook up this code    - edie epstein */	      if (subset_compare (buf_ptr, TUI_FLOAT_REGS_NAME))		{		  if (TUI_DATA_WIN->detail.data_display_info.regs_display_type !=		      TUI_SFLOAT_REGS &&		      TUI_DATA_WIN->detail.data_display_info.regs_display_type !=		      TUI_DFLOAT_REGS)		    dpy_type = TUI_SFLOAT_REGS;		  else		    dpy_type =		      TUI_DATA_WIN->detail.data_display_info.regs_display_type;		}	      else if (subset_compare (buf_ptr,				      TUI_GENERAL_SPECIAL_REGS_NAME))		dpy_type = TUI_GENERAL_AND_SPECIAL_REGS;	      else if (subset_compare (buf_ptr, TUI_GENERAL_REGS_NAME))		dpy_type = TUI_GENERAL_REGS;	      else if (subset_compare (buf_ptr, TUI_SPECIAL_REGS_NAME))		dpy_type = TUI_SPECIAL_REGS;	      else if (TUI_DATA_WIN)		{		  if (TUI_DATA_WIN->detail.data_display_info.regs_display_type !=		      TUI_UNDEFINED_REGS)		    dpy_type =		      TUI_DATA_WIN->detail.data_display_info.regs_display_type;		  else		    dpy_type = TUI_GENERAL_REGS;		}/* end of potential ifdef  *//* if ifdefed out code above, then assume that the user wishes to display the    general purpose registers  *//*              dpy_type = TUI_GENERAL_REGS;  */	    }	  else if (subset_compare (buf_ptr, "NEXT"))	    new_layout = next_layout ();	  else if (subset_compare (buf_ptr, "PREV"))	    new_layout = prev_layout ();	  else	    status = TUI_FAILURE;	  xfree (buf_ptr);	  tui_set_layout (new_layout, dpy_type);	}    }  else    status = TUI_FAILURE;  return status;}static CORE_ADDRextract_display_start_addr (void){  enum tui_layout_type cur_layout = tui_current_layout ();  CORE_ADDR addr;  CORE_ADDR pc;  struct symtab_and_line cursal = get_current_source_symtab_and_line ();  switch (cur_layout)    {    case SRC_COMMAND:    case SRC_DATA_COMMAND:      find_line_pc (cursal.symtab,		    TUI_SRC_WIN->detail.source_info.start_line_or_addr.line_no,		    &pc);      addr = pc;      break;    case DISASSEM_COMMAND:    case SRC_DISASSEM_COMMAND:    case DISASSEM_DATA_COMMAND:      addr = TUI_DISASM_WIN->detail.source_info.start_line_or_addr.addr;      break;    default:      addr = 0;      break;    }  return addr;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -