1 /* TUI data manipulation routines.
2 
3    Copyright (C) 1998-2024 Free Software Foundation, Inc.
4 
5    Contributed by Hewlett-Packard Company.
6 
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
11    the Free Software Foundation; either version 3 of the License, or
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
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21 
22 #ifndef TUI_TUI_DATA_H
23 #define TUI_TUI_DATA_H
24 
25 #include "tui/tui.h"
26 #include "gdb_curses.h"
27 #include "observable.h"
28 #include "gdbsupport/gdb-checked-static-cast.h"
29 
30 /* A deleter that calls delwin.  */
31 struct curses_deleter
32 {
operatorcurses_deleter33   void operator() (WINDOW *win) const
34   {
35     delwin (win);
36   }
37 };
38 
39 #define MIN_WIN_HEIGHT          3
40 
41 /* Generic window information.  */
42 struct tui_win_info
43 {
44 protected:
45 
46   tui_win_info () = default;
47   DISABLE_COPY_AND_ASSIGN (tui_win_info);
48 
49   /* This is called after the window is resized, and should update the
50      window's contents.  */
51   virtual void rerender ();
52 
53   virtual void make_window ();
54 
55 public:
56   tui_win_info (tui_win_info &&) = default;
57   virtual ~tui_win_info () = default;
58 
59   /* Call to refresh this window.  */
60   virtual void refresh_window ();
61 
62   /* Make this window visible or invisible.  */
63   virtual void make_visible (bool visible);
64 
65   /* Return the name of this type of window.  */
66   virtual const char *name () const = 0;
67 
68   /* Compute the maximum height of this window.  */
69   virtual int max_height () const;
70 
71   /* Compute the minimum height of this window.  */
min_heighttui_win_info72   virtual int min_height () const
73   {
74     return MIN_WIN_HEIGHT;
75   }
76 
77   /* Compute the maximum width of this window.  */
78   int max_width () const;
79 
80   /* Compute the minimum width of this window.  */
min_widthtui_win_info81   int min_width () const
82   {
83     return 3;
84   }
85 
86   /* Return true if this window can be boxed.  */
can_boxtui_win_info87   virtual bool can_box () const
88   {
89     return true;
90   }
91 
92   /* Return the width of the box.  */
box_widthtui_win_info93   int box_width () const
94   {
95     return can_box () ? 1 : 0;
96   }
97 
98   /* Return the size of the box.  */
box_sizetui_win_info99   int box_size () const
100   {
101     return 2 * box_width ();
102   }
103 
104   /* Resize this window.  The parameters are used to set the window's
105      size and position.  */
106   virtual void resize (int height, int width,
107                            int origin_x, int origin_y);
108 
109   /* Return true if this window is visible.  */
is_visibletui_win_info110   bool is_visible () const
111   {
112     return handle != nullptr && tui_active;
113   }
114 
115   /* Return true if this window can accept the focus.  */
can_focustui_win_info116   virtual bool can_focus () const
117   {
118     return true;
119   }
120 
121   /* Disable output until the next call to doupdate.  */
no_refreshtui_win_info122   void no_refresh ()
123   {
124     if (handle != nullptr)
125       wnoutrefresh (handle.get ());
126   }
127 
128   /* Called after the tab width has been changed.  */
update_tab_widthtui_win_info129   virtual void update_tab_width ()
130   {
131   }
132 
133   /* Set whether this window is highlighted.  */
set_highlighttui_win_info134   void set_highlight (bool highlight)
135   {
136     is_highlighted = highlight;
137   }
138 
139   /* Methods to scroll the contents of this window.  Note that they
140      are named with "_scroll" coming at the end because the more
141      obvious "scroll_forward" is defined as a macro in term.h.  */
142   void forward_scroll (int num_to_scroll);
143   void backward_scroll (int num_to_scroll);
144   void left_scroll (int num_to_scroll);
145   void right_scroll (int num_to_scroll);
146 
147   /* Return true if this window can be scrolled, false otherwise.  */
can_scrolltui_win_info148   virtual bool can_scroll () const
149   {
150     return true;
151   }
152 
153   /* Called for each mouse click inside this window.  Coordinates MOUSE_X
154      and MOUSE_Y are 0-based relative to the window, and MOUSE_BUTTON can
155      be 1 (left), 2 (middle), or 3 (right).  */
clicktui_win_info156   virtual void click (int mouse_x, int mouse_y, int mouse_button)
157   {
158   }
159 
160   void check_and_display_highlight_if_needed ();
161 
162   /* A helper function to change the title and then redraw the
163      surrounding box, if needed.  */
164   void set_title (std::string &&new_title);
165 
166   /* Return a reference to the current window title.  */
titletui_win_info167   const std::string &title () const
168   { return m_title; }
169 
170   /* Clear the window, maybe draw the boarder, and then display string
171      STR centered in the window, abbreviated if necessary.  */
172   void center_string (const char *str);
173 
174   /* Display string STR in the window at the current cursor position,
175      abbreviated if necessary.  */
176   void display_string (const char *str) const;
177 
178   /* Window handle.  */
179   std::unique_ptr<WINDOW, curses_deleter> handle;
180   /* Window width.  */
181   int width = 0;
182   /* Window height.  */
183   int height = 0;
184   /* Origin of window.  */
185   int x = 0;
186   int y = 0;
187 
188   /* Is this window highlighted?  */
189   bool is_highlighted = false;
190 
191 protected:
192 
193   /* Scroll the contents vertically.  This is only called via
194      forward_scroll and backward_scroll.  */
195   virtual void do_scroll_vertical (int num_to_scroll) = 0;
196 
197   /* Scroll the contents horizontally.  This is only called via
198      left_scroll and right_scroll.  */
199   virtual void do_scroll_horizontal (int num_to_scroll) = 0;
200 
201 private:
202   /* Window title to display.  */
203   std::string m_title;
204 };
205 
206 /* A TUI window that doesn't scroll.  */
207 
208 struct tui_noscroll_window : public virtual tui_win_info
209 {
210 public:
can_scrolltui_noscroll_window211   virtual bool can_scroll () const final override
212   {
213     return false;
214   }
215 
216 protected:
do_scroll_verticaltui_noscroll_window217   virtual void do_scroll_vertical (int num_to_scroll) final override
218   {
219   }
220 
221   /* Scroll the contents horizontally.  This is only called via
222      left_scroll and right_scroll.  */
do_scroll_horizontaltui_noscroll_window223   virtual void do_scroll_horizontal (int num_to_scroll) final override
224   {
225   }
226 };
227 
228 /* A TUI window that cannot have focus.  */
229 
230 struct tui_nofocus_window : public virtual tui_win_info
231 {
232 public:
can_focustui_nofocus_window233   virtual bool can_focus () const final override
234   {
235     return false;
236   }
237 };
238 
239 /* A TUI window that occupies a single line.  */
240 
241 struct tui_oneline_window : public virtual tui_win_info
242 {
max_heighttui_oneline_window243   int max_height () const final override
244   {
245     return 1;
246   }
247 
min_heighttui_oneline_window248   int min_height () const final override
249   {
250     return 1;
251   }
252 };
253 
254 /* A TUI window that has no border.  */
255 
256 struct tui_nobox_window : public virtual tui_win_info
257 {
can_boxtui_nobox_window258   bool can_box () const final override
259   {
260     return false;
261   }
262 };
263 
264 /* A TUI window that is not refreshed.  */
265 
266 struct tui_norefresh_window : public virtual tui_win_info
267 {
refresh_windowtui_norefresh_window268   virtual void refresh_window () final override
269   {
270   }
271 };
272 
273 /* A TUI window that is always visible.  */
274 
275 struct tui_always_visible_window : public virtual tui_win_info
276 {
make_visibletui_always_visible_window277   virtual void make_visible (bool visible) final override
278   {
279   }
280 };
281 
282 /* Constant definitions.  */
283 #define SRC_NAME                "src"
284 #define CMD_NAME                "cmd"
285 #define DATA_NAME               "regs"
286 #define DISASSEM_NAME           "asm"
287 #define STATUS_NAME           "status"
288 
289 /* Global Data.  */
290 extern struct tui_win_info *tui_win_list[MAX_MAJOR_WINDOWS];
291 
292 #define TUI_SRC_WIN \
293   (gdb::checked_static_cast<tui_source_window *> (tui_win_list[SRC_WIN]))
294 #define TUI_DISASM_WIN \
295   (gdb::checked_static_cast<tui_disasm_window *> (tui_win_list[DISASSEM_WIN]))
296 #define TUI_DATA_WIN \
297   (gdb::checked_static_cast<tui_data_window *> (tui_win_list[DATA_WIN]))
298 #define TUI_CMD_WIN \
299   (dynamic_cast<tui_cmd_window *> (tui_win_list[CMD_WIN]))
300 #define TUI_STATUS_WIN \
301   (dynamic_cast<tui_status_window *> (tui_win_list[STATUS_WIN]))
302 
303 /* All the windows that are currently instantiated, in layout
304    order.  */
305 extern std::vector<tui_win_info *> tui_windows;
306 
307 /* Return a range adapter for iterating over TUI windows.  */
308 static inline std::vector<tui_win_info *> &
all_tui_windows()309 all_tui_windows ()
310 {
311   return tui_windows;
312 }
313 
314 /* Data Manipulation Functions.  */
315 extern int tui_term_height (void);
316 extern void tui_set_term_height_to (int);
317 extern int tui_term_width (void);
318 extern void tui_set_term_width_to (int);
319 extern struct tui_win_info *tui_win_with_focus (void);
320 extern bool tui_win_resized ();
321 extern void tui_set_win_resized_to (bool);
322 
323 extern struct tui_win_info *tui_next_win (struct tui_win_info *);
324 extern struct tui_win_info *tui_prev_win (struct tui_win_info *);
325 
326 extern unsigned int tui_tab_width;
327 
328 #endif /* TUI_TUI_DATA_H */
329