* tui/tui-regs.c (tui_show_register_group): Remove GDBARCH parameter;
[external/binutils.git] / gdb / tui / tui-regs.c
1 /* TUI display registers in window.
2
3    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009
4    Free Software Foundation, Inc.
5
6    Contributed by Hewlett-Packard Company.
7
8    This file is part of GDB.
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
23 #include "defs.h"
24 #include "tui/tui.h"
25 #include "tui/tui-data.h"
26 #include "symtab.h"
27 #include "gdbtypes.h"
28 #include "gdbcmd.h"
29 #include "frame.h"
30 #include "regcache.h"
31 #include "inferior.h"
32 #include "target.h"
33 #include "gdb_string.h"
34 #include "tui/tui-layout.h"
35 #include "tui/tui-win.h"
36 #include "tui/tui-windata.h"
37 #include "tui/tui-wingeneral.h"
38 #include "tui/tui-file.h"
39 #include "tui/tui-regs.h"
40 #include "reggroups.h"
41 #include "valprint.h"
42
43 #include "gdb_curses.h"
44
45
46 /*****************************************
47 ** STATIC LOCAL FUNCTIONS FORWARD DECLS    **
48 ******************************************/
49 static void
50 tui_display_register (struct tui_data_element *data,
51                       struct tui_gen_win_info *win_info);
52
53 static enum tui_status tui_show_register_group (struct reggroup *group,
54                                                 struct frame_info *frame,
55                                                 int refresh_values_only);
56
57 static enum tui_status tui_get_register (struct frame_info *frame,
58                                          struct tui_data_element *data,
59                                          int regnum, int *changedp);
60
61 static void tui_register_format (struct frame_info *,
62                                  struct tui_data_element*, int);
63
64 static void tui_scroll_regs_forward_command (char *, int);
65 static void tui_scroll_regs_backward_command (char *, int);
66
67
68
69 /*****************************************
70 ** PUBLIC FUNCTIONS                     **
71 ******************************************/
72
73 /* Answer the number of the last line in the regs display.  If there
74    are no registers (-1) is returned.  */
75 int
76 tui_last_regs_line_no (void)
77 {
78   int num_lines = (-1);
79
80   if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
81     {
82       num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count /
83                   TUI_DATA_WIN->detail.data_display_info.regs_column_count);
84       if (TUI_DATA_WIN->detail.data_display_info.regs_content_count %
85           TUI_DATA_WIN->detail.data_display_info.regs_column_count)
86         num_lines++;
87     }
88   return num_lines;
89 }
90
91
92 /* Answer the line number that the register element at element_no is
93    on.  If element_no is greater than the number of register elements
94    there are, -1 is returned.  */
95 int
96 tui_line_from_reg_element_no (int element_no)
97 {
98   if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
99     {
100       int i, line = (-1);
101
102       i = 1;
103       while (line == (-1))
104         {
105           if (element_no <
106               (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i))
107             line = i - 1;
108           else
109             i++;
110         }
111
112       return line;
113     }
114   else
115     return (-1);
116 }
117
118
119 /* Answer the index of the first element in line_no.  If line_no is
120    past the register area (-1) is returned.  */
121 int
122 tui_first_reg_element_no_inline (int line_no)
123 {
124   if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count)
125       <= TUI_DATA_WIN->detail.data_display_info.regs_content_count)
126     return ((line_no + 1) *
127             TUI_DATA_WIN->detail.data_display_info.regs_column_count) -
128       TUI_DATA_WIN->detail.data_display_info.regs_column_count;
129   else
130     return (-1);
131 }
132
133
134 /* Answer the index of the last element in line_no.  If line_no is
135    past the register area (-1) is returned.  */
136 int
137 tui_last_reg_element_no_in_line (int line_no)
138 {
139   if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) <=
140       TUI_DATA_WIN->detail.data_display_info.regs_content_count)
141     return ((line_no + 1) *
142             TUI_DATA_WIN->detail.data_display_info.regs_column_count) - 1;
143   else
144     return (-1);
145 }
146
147 /* Show the registers of the given group in the data window
148    and refresh the window.  */
149 void
150 tui_show_registers (struct reggroup *group)
151 {
152   enum tui_status ret = TUI_FAILURE;
153   struct tui_data_info *display_info;
154
155   /* Make sure the curses mode is enabled.  */
156   tui_enable ();
157
158   /* Make sure the register window is visible.  If not, select an
159      appropriate layout.  */
160   if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible)
161     tui_set_layout_for_display_command (DATA_NAME);
162
163   display_info = &TUI_DATA_WIN->detail.data_display_info;
164   if (group == 0)
165     group = general_reggroup;
166
167   /* Say that registers should be displayed, even if there is a
168      problem.  */
169   display_info->display_regs = TRUE;
170
171   if (target_has_registers && target_has_stack && target_has_memory)
172     {
173       ret = tui_show_register_group (group, get_current_frame (),
174                                      group == display_info->current_group);
175     }
176   if (ret == TUI_FAILURE)
177     {
178       display_info->current_group = 0;
179       tui_erase_data_content (NO_REGS_STRING);
180     }
181   else
182     {
183       int i;
184
185       /* Clear all notation of changed values.  */
186       for (i = 0; i < display_info->regs_content_count; i++)
187         {
188           struct tui_gen_win_info *data_item_win;
189           struct tui_win_element *win;
190
191           data_item_win = &display_info->regs_content[i]
192             ->which_element.data_window;
193           win = (struct tui_win_element *) data_item_win->content[0];
194           win->which_element.data.highlight = FALSE;
195         }
196       display_info->current_group = group;
197       tui_display_all_data ();
198     }
199 }
200
201
202 /* Set the data window to display the registers of the register group
203    using the given frame.  Values are refreshed only when
204    refresh_values_only is TRUE.  */
205
206 static enum tui_status
207 tui_show_register_group (struct reggroup *group,
208                          struct frame_info *frame, 
209                          int refresh_values_only)
210 {
211   struct gdbarch *gdbarch = get_frame_arch (frame);
212   enum tui_status ret = TUI_FAILURE;
213   int nr_regs;
214   int allocated_here = FALSE;
215   int regnum, pos;
216   char title[80];
217   struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
218
219   /* Make a new title showing which group we display.  */
220   snprintf (title, sizeof (title) - 1, "Register group: %s",
221             reggroup_name (group));
222   xfree (TUI_DATA_WIN->generic.title);
223   TUI_DATA_WIN->generic.title = xstrdup (title);
224
225   /* See how many registers must be displayed.  */
226   nr_regs = 0;
227   for (regnum = 0;
228        regnum < gdbarch_num_regs (gdbarch)
229                 + gdbarch_num_pseudo_regs (gdbarch);
230        regnum++)
231     {
232       /* Must be in the group and have a name.  */
233       if (gdbarch_register_reggroup_p (gdbarch, regnum, group)
234           && gdbarch_register_name (gdbarch, regnum) != 0)
235         nr_regs++;
236     }
237
238   if (display_info->regs_content_count > 0 && !refresh_values_only)
239     {
240       tui_free_data_content (display_info->regs_content,
241                              display_info->regs_content_count);
242       display_info->regs_content_count = 0;
243     }
244
245   if (display_info->regs_content_count <= 0)
246     {
247       display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN);
248       allocated_here = TRUE;
249       refresh_values_only = FALSE;
250     }
251
252   if (display_info->regs_content != (tui_win_content) NULL)
253     {
254       if (!refresh_values_only || allocated_here)
255         {
256           TUI_DATA_WIN->generic.content = (void*) NULL;
257           TUI_DATA_WIN->generic.content_size = 0;
258           tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs);
259           display_info->regs_content
260             = (tui_win_content) TUI_DATA_WIN->generic.content;
261           display_info->regs_content_count = nr_regs;
262         }
263
264       /* Now set the register names and values.  */
265       pos = 0;
266       for (regnum = 0;
267            regnum < gdbarch_num_regs (gdbarch)
268                     + gdbarch_num_pseudo_regs (gdbarch);
269            regnum++)
270         {
271           struct tui_gen_win_info *data_item_win;
272           struct tui_data_element *data;
273           const char *name;
274
275           if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
276             continue;
277
278           name = gdbarch_register_name (gdbarch, regnum);
279           if (name == 0)
280             continue;
281
282           data_item_win =
283             &display_info->regs_content[pos]->which_element.data_window;
284           data =
285             &((struct tui_win_element *) data_item_win->content[0])->which_element.data;
286           if (data)
287             {
288               if (!refresh_values_only)
289                 {
290                   data->item_no = regnum;
291                   data->name = name;
292                   data->highlight = FALSE;
293                 }
294               if (data->value == (void*) NULL)
295                 data->value = (void*) xmalloc (MAX_REGISTER_SIZE);
296
297               tui_get_register (frame, data, regnum, 0);
298             }
299           pos++;
300         }
301
302       TUI_DATA_WIN->generic.content_size =
303         display_info->regs_content_count + display_info->data_content_count;
304       ret = TUI_SUCCESS;
305     }
306
307   return ret;
308 }
309
310 /* Function to display the registers in the content from
311    'start_element_no' until the end of the register content or the end
312    of the display height.  No checking for displaying past the end of
313    the registers is done here.  */
314 void
315 tui_display_registers_from (int start_element_no)
316 {
317   struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
318
319   if (display_info->regs_content != (tui_win_content) NULL 
320       && display_info->regs_content_count > 0)
321     {
322       int i = start_element_no;
323       int j, value_chars_wide, item_win_width, cur_y;
324
325       int max_len = 0;
326       for (i = 0; i < display_info->regs_content_count; i++)
327         {
328           struct tui_data_element *data;
329           struct tui_gen_win_info *data_item_win;
330           char *p;
331           int len;
332
333           data_item_win = &display_info->regs_content[i]->which_element.data_window;
334           data = &((struct tui_win_element *)
335                    data_item_win->content[0])->which_element.data;
336           len = 0;
337           p = data->content;
338           if (p != 0)
339             while (*p)
340               {
341                 if (*p++ == '\t')
342                   len = 8 * ((len / 8) + 1);
343                 else
344                   len++;
345               }
346
347           if (len > max_len)
348             max_len = len;
349         }
350       item_win_width = max_len + 1;
351       i = start_element_no;
352
353       display_info->regs_column_count =
354         (TUI_DATA_WIN->generic.width - 2) / item_win_width;
355       if (display_info->regs_column_count == 0)
356         display_info->regs_column_count = 1;
357       item_win_width =
358         (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count;
359
360       /* Now create each data "sub" window, and write the display into
361          it.  */
362       cur_y = 1;
363       while (i < display_info->regs_content_count 
364              && cur_y <= TUI_DATA_WIN->generic.viewport_height)
365         {
366           for (j = 0;
367                j < display_info->regs_column_count
368                  && i < display_info->regs_content_count;
369                j++)
370             {
371               struct tui_gen_win_info *data_item_win;
372               struct tui_data_element *data_element_ptr;
373
374               /* Create the window if necessary.  */
375               data_item_win = &display_info->regs_content[i]
376                 ->which_element.data_window;
377               data_element_ptr = &((struct tui_win_element *)
378                                  data_item_win->content[0])->which_element.data;
379               if (data_item_win->handle != (WINDOW*) NULL
380                   && (data_item_win->height != 1
381                       || data_item_win->width != item_win_width
382                       || data_item_win->origin.x != (item_win_width * j) + 1
383                       || data_item_win->origin.y != cur_y))
384                 {
385                   tui_delete_win (data_item_win->handle);
386                   data_item_win->handle = 0;
387                 }
388                   
389               if (data_item_win->handle == (WINDOW *) NULL)
390                 {
391                   data_item_win->height = 1;
392                   data_item_win->width = item_win_width;
393                   data_item_win->origin.x = (item_win_width * j) + 1;
394                   data_item_win->origin.y = cur_y;
395                   tui_make_window (data_item_win, DONT_BOX_WINDOW);
396                   scrollok (data_item_win->handle, FALSE);
397                 }
398               touchwin (data_item_win->handle);
399
400               /* Get the printable representation of the register
401                  and display it.  */
402               tui_display_register (data_element_ptr, data_item_win);
403               i++;              /* Next register.  */
404             }
405           cur_y++;              /* Next row.  */
406         }
407     }
408 }
409
410
411 /* Function to display the registers in the content from
412    'start_element_no' on 'start_line_no' until the end of the register
413    content or the end of the display height.  This function checks
414    that we won't display off the end of the register display.  */
415 static void
416 tui_display_reg_element_at_line (int start_element_no,
417                                  int start_line_no)
418 {
419   if (TUI_DATA_WIN->detail.data_display_info.regs_content != (tui_win_content) NULL
420       && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
421     {
422       int element_no = start_element_no;
423
424       if (start_element_no != 0 && start_line_no != 0)
425         {
426           int last_line_no, first_line_on_last_page;
427
428           last_line_no = tui_last_regs_line_no ();
429           first_line_on_last_page = last_line_no - (TUI_DATA_WIN->generic.height - 2);
430           if (first_line_on_last_page < 0)
431             first_line_on_last_page = 0;
432
433           /* If there is no other data displayed except registers, and
434              the element_no causes us to scroll past the end of the
435              registers, adjust what element to really start the
436              display at.  */
437           if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0
438               && start_line_no > first_line_on_last_page)
439             element_no = tui_first_reg_element_no_inline (first_line_on_last_page);
440         }
441       tui_display_registers_from (element_no);
442     }
443 }
444
445
446
447 /* Function to display the registers starting at line line_no in the
448    data window.  Answers the line number that the display actually
449    started from.  If nothing is displayed (-1) is returned.  */
450 int
451 tui_display_registers_from_line (int line_no, 
452                                  int force_display)
453 {
454   if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
455     {
456       int line, element_no;
457
458       if (line_no < 0)
459         line = 0;
460       else if (force_display)
461         { /* If we must display regs (force_display is true), then
462              make sure that we don't display off the end of the
463              registers.  */
464           if (line_no >= tui_last_regs_line_no ())
465             {
466               if ((line = tui_line_from_reg_element_no (
467                  TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0)
468                 line = 0;
469             }
470           else
471             line = line_no;
472         }
473       else
474         line = line_no;
475
476       element_no = tui_first_reg_element_no_inline (line);
477       if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
478         tui_display_reg_element_at_line (element_no, line);
479       else
480         line = (-1);
481
482       return line;
483     }
484
485   return (-1);                  /* Nothing was displayed.  */
486 }
487
488
489 /* This function check all displayed registers for changes in values,
490    given a particular frame.  If the values have changed, they are
491    updated with the new value and highlighted.  */
492 void
493 tui_check_register_values (struct frame_info *frame)
494 {
495   if (TUI_DATA_WIN != NULL
496       && TUI_DATA_WIN->generic.is_visible)
497     {
498       struct tui_data_info *display_info
499         = &TUI_DATA_WIN->detail.data_display_info;
500
501       if (display_info->regs_content_count <= 0 
502           && display_info->display_regs)
503         tui_show_registers (display_info->current_group);
504       else
505         {
506           int i, j;
507
508           for (i = 0; (i < display_info->regs_content_count); i++)
509             {
510               struct tui_data_element *data;
511               struct tui_gen_win_info *data_item_win_ptr;
512               int was_hilighted;
513
514               data_item_win_ptr = &display_info->regs_content[i]->
515                 which_element.data_window;
516               data = &((struct tui_win_element *)
517                        data_item_win_ptr->content[0])->which_element.data;
518               was_hilighted = data->highlight;
519
520               tui_get_register (frame, data,
521                                 data->item_no, &data->highlight);
522
523               if (data->highlight || was_hilighted)
524                 {
525                   tui_display_register (data, data_item_win_ptr);
526                 }
527             }
528         }
529     }
530 }
531
532 /* Display a register in a window.  If hilite is TRUE, then the value
533    will be displayed in reverse video.  */
534 static void
535 tui_display_register (struct tui_data_element *data,
536                       struct tui_gen_win_info *win_info)
537 {
538   if (win_info->handle != (WINDOW *) NULL)
539     {
540       int i;
541
542       if (data->highlight)
543         wstandout (win_info->handle);
544       
545       wmove (win_info->handle, 0, 0);
546       for (i = 1; i < win_info->width; i++)
547         waddch (win_info->handle, ' ');
548       wmove (win_info->handle, 0, 0);
549       if (data->content)
550         waddstr (win_info->handle, data->content);
551
552       if (data->highlight)
553         wstandend (win_info->handle);
554       tui_refresh_win (win_info);
555     }
556 }
557
558 static void
559 tui_reg_next_command (char *arg, int from_tty)
560 {
561   if (TUI_DATA_WIN != 0)
562     {
563       struct reggroup *group
564         = TUI_DATA_WIN->detail.data_display_info.current_group;
565
566       group = reggroup_next (current_gdbarch, group);
567       if (group == 0)
568         group = reggroup_next (current_gdbarch, 0);
569
570       if (group)
571         tui_show_registers (group);
572     }
573 }
574
575 static void
576 tui_reg_float_command (char *arg, int from_tty)
577 {
578   tui_show_registers (float_reggroup);
579 }
580
581 static void
582 tui_reg_general_command (char *arg, int from_tty)
583 {
584   tui_show_registers (general_reggroup);
585 }
586
587 static void
588 tui_reg_system_command (char *arg, int from_tty)
589 {
590   tui_show_registers (system_reggroup);
591 }
592
593 static struct cmd_list_element *tuireglist;
594
595 static void
596 tui_reg_command (char *args, int from_tty)
597 {
598   printf_unfiltered (_("\"tui reg\" must be followed by the name of a "
599                      "tui reg command.\n"));
600   help_list (tuireglist, "tui reg ", -1, gdb_stdout);
601 }
602
603 /* Provide a prototype to silence -Wmissing-prototypes.  */
604 extern initialize_file_ftype _initialize_tui_regs;
605
606 void
607 _initialize_tui_regs (void)
608 {
609   struct cmd_list_element **tuicmd;
610
611   tuicmd = tui_get_cmd_list ();
612
613   add_prefix_cmd ("reg", class_tui, tui_reg_command,
614                   _("TUI commands to control the register window."),
615                   &tuireglist, "tui reg ", 0,
616                   tuicmd);
617
618   add_cmd ("float", class_tui, tui_reg_float_command,
619            _("Display only floating point registers."),
620            &tuireglist);
621   add_cmd ("general", class_tui, tui_reg_general_command,
622            _("Display only general registers."),
623            &tuireglist);
624   add_cmd ("system", class_tui, tui_reg_system_command,
625            _("Display only system registers."),
626            &tuireglist);
627   add_cmd ("next", class_tui, tui_reg_next_command,
628            _("Display next register group."),
629            &tuireglist);
630
631   if (xdb_commands)
632     {
633       add_com ("fr", class_tui, tui_reg_float_command,
634                _("Display only floating point registers\n"));
635       add_com ("gr", class_tui, tui_reg_general_command,
636                _("Display only general registers\n"));
637       add_com ("sr", class_tui, tui_reg_system_command,
638                _("Display only special registers\n"));
639       add_com ("+r", class_tui, tui_scroll_regs_forward_command,
640                _("Scroll the registers window forward\n"));
641       add_com ("-r", class_tui, tui_scroll_regs_backward_command,
642                _("Scroll the register window backward\n"));
643     }
644 }
645
646
647 /*****************************************
648 ** STATIC LOCAL FUNCTIONS                 **
649 ******************************************/
650
651 extern int pagination_enabled;
652
653 static void
654 tui_restore_gdbout (void *ui)
655 {
656   ui_file_delete (gdb_stdout);
657   gdb_stdout = (struct ui_file*) ui;
658   pagination_enabled = 1;
659 }
660
661 /* Get the register from the frame and make a printable representation
662    of it in the data element.  */
663 static void
664 tui_register_format (struct frame_info *frame,
665                      struct tui_data_element *data_element, 
666                      int regnum)
667 {
668   struct gdbarch *gdbarch = get_frame_arch (frame);
669   struct ui_file *stream;
670   struct ui_file *old_stdout;
671   const char *name;
672   struct cleanup *cleanups;
673   char *p, *s;
674   int pos;
675   struct type *type = register_type (gdbarch, regnum);
676
677   name = gdbarch_register_name (gdbarch, regnum);
678   if (name == 0)
679     {
680       return;
681     }
682   
683   pagination_enabled = 0;
684   old_stdout = gdb_stdout;
685   stream = tui_sfileopen (256);
686   gdb_stdout = stream;
687   cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
688   if (TYPE_VECTOR (type) != 0 && 0)
689     {
690       gdb_byte buf[MAX_REGISTER_SIZE];
691       int len;
692       struct value_print_options opts;
693
694       len = register_size (gdbarch, regnum);
695       fprintf_filtered (stream, "%-14s ", name);
696       get_frame_register (frame, regnum, buf);
697       get_formatted_print_options (&opts, 'f');
698       print_scalar_formatted (buf, type, &opts, len, stream);
699     }
700   else
701     {
702       gdbarch_print_registers_info (gdbarch, stream,
703                                     frame, regnum, 1);
704     }
705
706   /* Save formatted output in the buffer.  */
707   p = tui_file_get_strbuf (stream);
708
709   /* Remove the possible \n.  */
710   s = strrchr (p, '\n');
711   if (s && s[1] == 0)
712     *s = 0;
713
714   xfree (data_element->content);
715   data_element->content = xstrdup (p);
716   do_cleanups (cleanups);
717 }
718
719 /* Get the register value from the given frame and format it for the
720    display.  When changep is set, check if the new register value has
721    changed with respect to the previous call.  */
722 static enum tui_status
723 tui_get_register (struct frame_info *frame,
724                   struct tui_data_element *data, 
725                   int regnum, int *changedp)
726 {
727   enum tui_status ret = TUI_FAILURE;
728
729   if (changedp)
730     *changedp = FALSE;
731   if (target_has_registers)
732     {
733       gdb_byte buf[MAX_REGISTER_SIZE];
734       get_frame_register (frame, regnum, buf);
735
736       if (changedp)
737         {
738           struct gdbarch *gdbarch = get_frame_arch (frame);
739           int size = register_size (gdbarch, regnum);
740           char *old = (char*) data->value;
741           int i;
742
743           for (i = 0; i < size; i++)
744             if (buf[i] != old[i])
745               {
746                 *changedp = TRUE;
747                 old[i] = buf[i];
748               }
749         }
750
751       /* Reformat the data content if the value changed.  */
752       if (changedp == 0 || *changedp == TRUE)
753         tui_register_format (frame, data, regnum);
754
755       ret = TUI_SUCCESS;
756     }
757   return ret;
758 }
759
760 static void
761 tui_scroll_regs_forward_command (char *arg, int from_tty)
762 {
763   tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1);
764 }
765
766
767 static void
768 tui_scroll_regs_backward_command (char *arg, int from_tty)
769 {
770   tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1);
771 }