]> Git Repo - binutils.git/blob - gdb/tui/tuiRegs.c
2003-05-08 Andrew Cagney <[email protected]>
[binutils.git] / gdb / tui / tuiRegs.c
1 /* TUI display registers in window.
2
3    Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
4    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 2 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, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330,
23    Boston, MA 02111-1307, USA.  */
24
25 /* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
26    "defs.h" should be included first.  Unfortunatly some systems
27    (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
28    and they clash with "bfd.h"'s definiton of true/false.  The correct
29    fix is to remove true/false from "bfd.h", however, until that
30    happens, hack around it by including "config.h" and <curses.h>
31    first.  */
32
33 #include "config.h"
34 #ifdef HAVE_NCURSES_H       
35 #include <ncurses.h>
36 #else
37 #ifdef HAVE_CURSES_H
38 #include <curses.h>
39 #endif
40 #endif
41
42 #include "defs.h"
43 #include "tui.h"
44 #include "tuiData.h"
45 #include "symtab.h"
46 #include "gdbtypes.h"
47 #include "gdbcmd.h"
48 #include "frame.h"
49 #include "regcache.h"
50 #include "inferior.h"
51 #include "target.h"
52 #include "tuiLayout.h"
53 #include "tuiWin.h"
54 #include "tuiDataWin.h"
55 #include "tuiGeneralWin.h"
56 #include "tui-file.h"
57
58 /*****************************************
59 ** LOCAL DEFINITIONS                    **
60 ******************************************/
61 #define DOUBLE_FLOAT_LABEL_WIDTH    6
62 #define DOUBLE_FLOAT_LABEL_FMT      "%6.6s: "
63 #define DOUBLE_FLOAT_VALUE_WIDTH    30  /*min of 16 but may be in sci notation */
64
65 #define SINGLE_FLOAT_LABEL_WIDTH    6
66 #define SINGLE_FLOAT_LABEL_FMT      "%6.6s: "
67 #define SINGLE_FLOAT_VALUE_WIDTH    25  /* min of 8 but may be in sci notation */
68
69 #define SINGLE_LABEL_WIDTH    16
70 #define SINGLE_LABEL_FMT      "%10.10s: "
71 #define SINGLE_VALUE_WIDTH    20 /* minimum of 8 but may be in sci notation */
72
73 /* In the code HP gave Cygnus, this was actually a function call to a
74    PA-specific function, which was supposed to determine whether the
75    target was a 64-bit or 32-bit processor.  However, the 64-bit
76    support wasn't complete, so we didn't merge that in, so we leave
77    this here as a stub.  */
78 #define IS_64BIT 0
79
80 /*****************************************
81 ** STATIC DATA                          **
82 ******************************************/
83
84
85 /*****************************************
86 ** STATIC LOCAL FUNCTIONS FORWARD DECLS    **
87 ******************************************/
88 static TuiStatus _tuiSetRegsContent
89   (int, int, struct frame_info *, TuiRegisterDisplayType, int);
90 static const char *_tuiRegisterName (int);
91 static TuiStatus _tuiGetRegisterRawValue (int, char *, struct frame_info *);
92 static void _tuiSetRegisterElement
93   (int, struct frame_info *, TuiDataElementPtr, int);
94 static void _tuiDisplayRegister (int, TuiGenWinInfoPtr, enum precision_type);
95 static void _tuiRegisterFormat
96   (char *, int, int, TuiDataElementPtr, enum precision_type);
97 static TuiStatus _tuiSetGeneralRegsContent (int);
98 static TuiStatus _tuiSetSpecialRegsContent (int);
99 static TuiStatus _tuiSetGeneralAndSpecialRegsContent (int);
100 static TuiStatus _tuiSetFloatRegsContent (TuiRegisterDisplayType, int);
101 static int _tuiRegValueHasChanged
102   (TuiDataElementPtr, struct frame_info *, char *);
103 static void _tuiShowFloat_command (char *, int);
104 static void _tuiShowGeneral_command (char *, int);
105 static void _tuiShowSpecial_command (char *, int);
106 static void _tui_vShowRegisters_commandSupport (TuiRegisterDisplayType);
107 static void _tuiToggleFloatRegs_command (char *, int);
108 static void _tuiScrollRegsForward_command (char *, int);
109 static void _tuiScrollRegsBackward_command (char *, int);
110
111
112
113 /*****************************************
114 ** PUBLIC FUNCTIONS                     **
115 ******************************************/
116
117 /*
118    ** tuiLastRegsLineNo()
119    **        Answer the number of the last line in the regs display.
120    **        If there are no registers (-1) is returned.
121  */
122 int
123 tuiLastRegsLineNo (void)
124 {
125   register int numLines = (-1);
126
127   if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
128     {
129       numLines = (dataWin->detail.dataDisplayInfo.regsContentCount /
130                   dataWin->detail.dataDisplayInfo.regsColumnCount);
131       if (dataWin->detail.dataDisplayInfo.regsContentCount %
132           dataWin->detail.dataDisplayInfo.regsColumnCount)
133         numLines++;
134     }
135   return numLines;
136 }                               /* tuiLastRegsLineNo */
137
138
139 /*
140    ** tuiLineFromRegElementNo()
141    **        Answer the line number that the register element at elementNo is
142    **        on.  If elementNo is greater than the number of register elements
143    **        there are, -1 is returned.
144  */
145 int
146 tuiLineFromRegElementNo (int elementNo)
147 {
148   if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
149     {
150       int i, line = (-1);
151
152       i = 1;
153       while (line == (-1))
154         {
155           if (elementNo <
156               (dataWin->detail.dataDisplayInfo.regsColumnCount * i))
157             line = i - 1;
158           else
159             i++;
160         }
161
162       return line;
163     }
164   else
165     return (-1);
166 }                               /* tuiLineFromRegElementNo */
167
168
169 /*
170    ** tuiFirstRegElementNoInLine()
171    **        Answer the index of the first element in lineNo.  If lineNo is
172    **        past the register area (-1) is returned.
173  */
174 int
175 tuiFirstRegElementNoInLine (int lineNo)
176 {
177   if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount)
178       <= dataWin->detail.dataDisplayInfo.regsContentCount)
179     return ((lineNo + 1) *
180             dataWin->detail.dataDisplayInfo.regsColumnCount) -
181       dataWin->detail.dataDisplayInfo.regsColumnCount;
182   else
183     return (-1);
184 }                               /* tuiFirstRegElementNoInLine */
185
186
187 /*
188    ** tuiLastRegElementNoInLine()
189    **        Answer the index of the last element in lineNo.  If lineNo is past
190    **        the register area (-1) is returned.
191  */
192 int
193 tuiLastRegElementNoInLine (int lineNo)
194 {
195   if ((lineNo * dataWin->detail.dataDisplayInfo.regsColumnCount) <=
196       dataWin->detail.dataDisplayInfo.regsContentCount)
197     return ((lineNo + 1) *
198             dataWin->detail.dataDisplayInfo.regsColumnCount) - 1;
199   else
200     return (-1);
201 }                               /* tuiLastRegElementNoInLine */
202
203
204 /*
205    ** tuiCalculateRegsColumnCount
206    **        Calculate the number of columns that should be used to display
207    **        the registers.
208  */
209 int
210 tuiCalculateRegsColumnCount (TuiRegisterDisplayType dpyType)
211 {
212   int colCount, colWidth;
213
214   if (IS_64BIT || dpyType == TUI_DFLOAT_REGS)
215     colWidth = DOUBLE_FLOAT_VALUE_WIDTH + DOUBLE_FLOAT_LABEL_WIDTH;
216   else
217     {
218       if (dpyType == TUI_SFLOAT_REGS)
219         colWidth = SINGLE_FLOAT_VALUE_WIDTH + SINGLE_FLOAT_LABEL_WIDTH;
220       else
221         colWidth = SINGLE_VALUE_WIDTH + SINGLE_LABEL_WIDTH;
222     }
223   colCount = (dataWin->generic.width - 2) / colWidth;
224
225   return colCount;
226 }                               /* tuiCalulateRegsColumnCount */
227
228
229 /*
230    ** tuiShowRegisters().
231    **        Show the registers int the data window as indicated by dpyType.
232    **        If there is any other registers being displayed, then they are
233    **        cleared.  What registers are displayed is dependent upon dpyType.
234  */
235 void
236 tuiShowRegisters (TuiRegisterDisplayType dpyType)
237 {
238   TuiStatus ret = TUI_FAILURE;
239   int refreshValuesOnly = FALSE;
240
241   /* Say that registers should be displayed, even if there is a problem */
242   dataWin->detail.dataDisplayInfo.displayRegs = TRUE;
243
244   if (target_has_registers)
245     {
246       refreshValuesOnly =
247         (dpyType == dataWin->detail.dataDisplayInfo.regsDisplayType);
248       switch (dpyType)
249         {
250         case TUI_GENERAL_REGS:
251           ret = _tuiSetGeneralRegsContent (refreshValuesOnly);
252           break;
253         case TUI_SFLOAT_REGS:
254         case TUI_DFLOAT_REGS:
255           ret = _tuiSetFloatRegsContent (dpyType, refreshValuesOnly);
256           break;
257
258 /* could ifdef out */
259
260         case TUI_SPECIAL_REGS:
261           ret = _tuiSetSpecialRegsContent (refreshValuesOnly);
262           break;
263         case TUI_GENERAL_AND_SPECIAL_REGS:
264           ret = _tuiSetGeneralAndSpecialRegsContent (refreshValuesOnly);
265           break;
266
267 /* end of potential if def */
268
269         default:
270           break;
271         }
272     }
273   if (ret == TUI_FAILURE)
274     {
275       dataWin->detail.dataDisplayInfo.regsDisplayType = TUI_UNDEFINED_REGS;
276       tuiEraseDataContent (NO_REGS_STRING);
277     }
278   else
279     {
280       int i;
281
282       /* Clear all notation of changed values */
283       for (i = 0; (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
284         {
285           TuiGenWinInfoPtr dataItemWin;
286
287           dataItemWin = &dataWin->detail.dataDisplayInfo.
288             regsContent[i]->whichElement.dataWindow;
289           (&((TuiWinElementPtr)
290              dataItemWin->content[0])->whichElement.data)->highlight = FALSE;
291         }
292       dataWin->detail.dataDisplayInfo.regsDisplayType = dpyType;
293       tuiDisplayAllData ();
294     }
295   (tuiLayoutDef ())->regsDisplayType = dpyType;
296
297   return;
298 }                               /* tuiShowRegisters */
299
300
301 /*
302    ** tuiDisplayRegistersFrom().
303    **        Function to display the registers in the content from
304    **        'startElementNo' until the end of the register content or the
305    **        end of the display height.  No checking for displaying past
306    **        the end of the registers is done here.
307  */
308 void
309 tuiDisplayRegistersFrom (int startElementNo)
310 {
311   if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
312       dataWin->detail.dataDisplayInfo.regsContentCount > 0)
313     {
314       register int i = startElementNo;
315       int j, valueCharsWide, itemWinWidth, curY, labelWidth;
316       enum precision_type precision;
317
318       precision = (dataWin->detail.dataDisplayInfo.regsDisplayType
319                    == TUI_DFLOAT_REGS) ?
320         double_precision : unspecified_precision;
321       if (IS_64BIT ||
322           dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
323         {
324           valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
325           labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
326         }
327       else
328         {
329           if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
330               TUI_SFLOAT_REGS)
331             {
332               valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
333               labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
334             }
335           else
336             {
337               valueCharsWide = SINGLE_VALUE_WIDTH;
338               labelWidth = SINGLE_LABEL_WIDTH;
339             }
340         }
341       itemWinWidth = valueCharsWide + labelWidth;
342       /*
343          ** Now create each data "sub" window, and write the display into it.
344        */
345       curY = 1;
346       while (i < dataWin->detail.dataDisplayInfo.regsContentCount &&
347              curY <= dataWin->generic.viewportHeight)
348         {
349           for (j = 0;
350                (j < dataWin->detail.dataDisplayInfo.regsColumnCount &&
351                 i < dataWin->detail.dataDisplayInfo.regsContentCount); j++)
352             {
353               TuiGenWinInfoPtr dataItemWin;
354               TuiDataElementPtr dataElementPtr;
355
356               /* create the window if necessary */
357               dataItemWin = &dataWin->detail.dataDisplayInfo.
358                 regsContent[i]->whichElement.dataWindow;
359               dataElementPtr = &((TuiWinElementPtr)
360                                  dataItemWin->content[0])->whichElement.data;
361               if (dataItemWin->handle == (WINDOW *) NULL)
362                 {
363                   dataItemWin->height = 1;
364                   dataItemWin->width = (precision == double_precision) ?
365                     itemWinWidth + 2 : itemWinWidth + 1;
366                   dataItemWin->origin.x = (itemWinWidth * j) + 1;
367                   dataItemWin->origin.y = curY;
368                   makeWindow (dataItemWin, DONT_BOX_WINDOW);
369                   scrollok (dataItemWin->handle, FALSE);
370                 }
371               touchwin (dataItemWin->handle);
372
373               /*
374                  ** Get the printable representation of the register
375                  ** and display it
376                */
377               _tuiDisplayRegister (
378                             dataElementPtr->itemNo, dataItemWin, precision);
379               i++;              /* next register */
380             }
381           curY++;               /* next row; */
382         }
383     }
384
385   return;
386 }                               /* tuiDisplayRegistersFrom */
387
388
389 /*
390    ** tuiDisplayRegElementAtLine().
391    **        Function to display the registers in the content from
392    **        'startElementNo' on 'startLineNo' until the end of the
393    **        register content or the end of the display height.
394    **        This function checks that we won't display off the end
395    **        of the register display.
396  */
397 void
398 tuiDisplayRegElementAtLine (int startElementNo, int startLineNo)
399 {
400   if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL &&
401       dataWin->detail.dataDisplayInfo.regsContentCount > 0)
402     {
403       register int elementNo = startElementNo;
404
405       if (startElementNo != 0 && startLineNo != 0)
406         {
407           register int lastLineNo, firstLineOnLastPage;
408
409           lastLineNo = tuiLastRegsLineNo ();
410           firstLineOnLastPage = lastLineNo - (dataWin->generic.height - 2);
411           if (firstLineOnLastPage < 0)
412             firstLineOnLastPage = 0;
413           /*
414              ** If there is no other data displayed except registers,
415              ** and the elementNo causes us to scroll past the end of the
416              ** registers, adjust what element to really start the display at.
417            */
418           if (dataWin->detail.dataDisplayInfo.dataContentCount <= 0 &&
419               startLineNo > firstLineOnLastPage)
420             elementNo = tuiFirstRegElementNoInLine (firstLineOnLastPage);
421         }
422       tuiDisplayRegistersFrom (elementNo);
423     }
424
425   return;
426 }                               /* tuiDisplayRegElementAtLine */
427
428
429
430 /*
431    ** tuiDisplayRegistersFromLine().
432    **        Function to display the registers starting at line lineNo in
433    **        the data window.  Answers the line number that the display
434    **        actually started from.  If nothing is displayed (-1) is returned.
435  */
436 int
437 tuiDisplayRegistersFromLine (int lineNo, int forceDisplay)
438 {
439   if (dataWin->detail.dataDisplayInfo.regsContentCount > 0)
440     {
441       int line, elementNo;
442
443       if (lineNo < 0)
444         line = 0;
445       else if (forceDisplay)
446         {                       /*
447                                    ** If we must display regs (forceDisplay is true), then make
448                                    ** sure that we don't display off the end of the registers.
449                                  */
450           if (lineNo >= tuiLastRegsLineNo ())
451             {
452               if ((line = tuiLineFromRegElementNo (
453                  dataWin->detail.dataDisplayInfo.regsContentCount - 1)) < 0)
454                 line = 0;
455             }
456           else
457             line = lineNo;
458         }
459       else
460         line = lineNo;
461
462       elementNo = tuiFirstRegElementNoInLine (line);
463       if (elementNo < dataWin->detail.dataDisplayInfo.regsContentCount)
464         tuiDisplayRegElementAtLine (elementNo, line);
465       else
466         line = (-1);
467
468       return line;
469     }
470
471   return (-1);                  /* nothing was displayed */
472 }                               /* tuiDisplayRegistersFromLine */
473
474
475 /*
476    ** tuiCheckRegisterValues()
477    **        This function check all displayed registers for changes in
478    **        values, given a particular frame.  If the values have changed,
479    **        they are updated with the new value and highlighted.
480  */
481 void
482 tuiCheckRegisterValues (struct frame_info *frame)
483 {
484   if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
485     {
486       if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0 &&
487           dataWin->detail.dataDisplayInfo.displayRegs)
488         tuiShowRegisters ((tuiLayoutDef ())->regsDisplayType);
489       else
490         {
491           int i, j;
492           char rawBuf[MAX_REGISTER_SIZE];
493
494           for (i = 0;
495                (i < dataWin->detail.dataDisplayInfo.regsContentCount); i++)
496             {
497               TuiDataElementPtr dataElementPtr;
498               TuiGenWinInfoPtr dataItemWinPtr;
499               int wasHilighted;
500
501               dataItemWinPtr = &dataWin->detail.dataDisplayInfo.
502                 regsContent[i]->whichElement.dataWindow;
503               dataElementPtr = &((TuiWinElementPtr)
504                              dataItemWinPtr->content[0])->whichElement.data;
505               wasHilighted = dataElementPtr->highlight;
506               dataElementPtr->highlight =
507                 _tuiRegValueHasChanged (dataElementPtr, frame, &rawBuf[0]);
508               if (dataElementPtr->highlight)
509                 {
510                   int size;
511
512                   size = REGISTER_RAW_SIZE (dataElementPtr->itemNo);
513                   for (j = 0; j < size; j++)
514                     ((char *) dataElementPtr->value)[j] = rawBuf[j];
515                   _tuiDisplayRegister (
516                                         dataElementPtr->itemNo,
517                                         dataItemWinPtr,
518                         ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
519                           TUI_DFLOAT_REGS) ?
520                          double_precision : unspecified_precision));
521                 }
522               else if (wasHilighted)
523                 {
524                   dataElementPtr->highlight = FALSE;
525                   _tuiDisplayRegister (
526                                         dataElementPtr->itemNo,
527                                         dataItemWinPtr,
528                         ((dataWin->detail.dataDisplayInfo.regsDisplayType ==
529                           TUI_DFLOAT_REGS) ?
530                          double_precision : unspecified_precision));
531                 }
532             }
533         }
534     }
535   return;
536 }                               /* tuiCheckRegisterValues */
537
538
539 /*
540    ** tuiToggleFloatRegs().
541  */
542 void
543 tuiToggleFloatRegs (void)
544 {
545   TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
546
547   if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
548     layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
549   else
550     layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
551
552   if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible &&
553       (dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_SFLOAT_REGS ||
554        dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS))
555     tuiShowRegisters (layoutDef->floatRegsDisplayType);
556
557   return;
558 }                               /* tuiToggleFloatRegs */
559
560
561 void
562 _initialize_tuiRegs (void)
563 {
564   if (xdb_commands)
565     {
566       add_com ("fr", class_tui, _tuiShowFloat_command,
567                "Display only floating point registers\n");
568       add_com ("gr", class_tui, _tuiShowGeneral_command,
569                "Display only general registers\n");
570       add_com ("sr", class_tui, _tuiShowSpecial_command,
571                "Display only special registers\n");
572       add_com ("+r", class_tui, _tuiScrollRegsForward_command,
573                "Scroll the registers window forward\n");
574       add_com ("-r", class_tui, _tuiScrollRegsBackward_command,
575                "Scroll the register window backward\n");
576       add_com ("tf", class_tui, _tuiToggleFloatRegs_command,
577                "Toggle between single and double precision floating point registers.\n");
578       add_cmd (TUI_FLOAT_REGS_NAME_LOWER,
579                class_tui,
580                _tuiToggleFloatRegs_command,
581                "Toggle between single and double precision floating point \
582 registers.\n",
583                &togglelist);
584     }
585 }
586
587
588 /*****************************************
589 ** STATIC LOCAL FUNCTIONS                 **
590 ******************************************/
591
592
593 /*
594    ** _tuiRegisterName().
595    **        Return the register name.
596  */
597 static const char *
598 _tuiRegisterName (int regNum)
599 {
600   return REGISTER_NAME (regNum);
601 }
602 extern int pagination_enabled;
603
604 static void
605 tui_restore_gdbout (void *ui)
606 {
607   ui_file_delete (gdb_stdout);
608   gdb_stdout = (struct ui_file*) ui;
609   pagination_enabled = 1;
610 }
611
612 /*
613    ** _tuiRegisterFormat
614    **        Function to format the register name and value into a buffer,
615    **        suitable for printing or display
616  */
617 static void
618 _tuiRegisterFormat (char *buf, int bufLen, int regNum,
619                     TuiDataElementPtr dataElement,
620                     enum precision_type precision)
621 {
622   struct ui_file *stream;
623   struct ui_file *old_stdout;
624   const char *name;
625   struct cleanup *cleanups;
626   char *p;
627   int pos;
628
629   name = REGISTER_NAME (regNum);
630   if (name == 0)
631     {
632       strcpy (buf, "");
633       return;
634     }
635   
636   pagination_enabled = 0;
637   old_stdout = gdb_stdout;
638   stream = tui_sfileopen (bufLen);
639   gdb_stdout = stream;
640   cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
641   gdbarch_print_registers_info (current_gdbarch, stream, deprecated_selected_frame,
642                                 regNum, 1);
643
644   /* Save formatted output in the buffer.  */
645   p = tui_file_get_strbuf (stream);
646   pos = 0;
647   while (*p && *p == *name++ && bufLen)
648     {
649       *buf++ = *p++;
650       bufLen--;
651       pos++;
652     }
653   while (*p == ' ')
654     p++;
655   while (pos < 8 && bufLen)
656     {
657       *buf++ = ' ';
658       bufLen--;
659       pos++;
660     }
661   strncpy (buf, p, bufLen);
662
663   /* Remove the possible \n.  */
664   p = strchr (buf, '\n');
665   if (p)
666     *p = 0;
667
668   do_cleanups (cleanups);
669 }
670
671
672 #define NUM_GENERAL_REGS    32
673 /*
674    ** _tuiSetGeneralRegsContent().
675    **      Set the content of the data window to consist of the general registers.
676  */
677 static TuiStatus
678 _tuiSetGeneralRegsContent (int refreshValuesOnly)
679 {
680   return (_tuiSetRegsContent (0,
681                               NUM_GENERAL_REGS - 1,
682                               deprecated_selected_frame,
683                               TUI_GENERAL_REGS,
684                               refreshValuesOnly));
685
686 }                               /* _tuiSetGeneralRegsContent */
687
688
689 #ifndef PCOQ_HEAD_REGNUM
690 #define START_SPECIAL_REGS  0
691 #else
692 #define START_SPECIAL_REGS    PCOQ_HEAD_REGNUM
693 #endif
694
695 /*
696    ** _tuiSetSpecialRegsContent().
697    **      Set the content of the data window to consist of the special registers.
698  */
699 static TuiStatus
700 _tuiSetSpecialRegsContent (int refreshValuesOnly)
701 {
702   TuiStatus ret = TUI_FAILURE;
703   int endRegNum;
704
705   endRegNum = FP0_REGNUM - 1;
706   ret = _tuiSetRegsContent (START_SPECIAL_REGS,
707                             endRegNum,
708                             deprecated_selected_frame,
709                             TUI_SPECIAL_REGS,
710                             refreshValuesOnly);
711
712   return ret;
713 }                               /* _tuiSetSpecialRegsContent */
714
715
716 /*
717    ** _tuiSetGeneralAndSpecialRegsContent().
718    **      Set the content of the data window to consist of the special registers.
719  */
720 static TuiStatus
721 _tuiSetGeneralAndSpecialRegsContent (int refreshValuesOnly)
722 {
723   TuiStatus ret = TUI_FAILURE;
724   int endRegNum = (-1);
725
726   endRegNum = FP0_REGNUM - 1;
727   ret = _tuiSetRegsContent (
728          0, endRegNum, deprecated_selected_frame, TUI_SPECIAL_REGS, refreshValuesOnly);
729
730   return ret;
731 }                               /* _tuiSetGeneralAndSpecialRegsContent */
732
733 /*
734    ** _tuiSetFloatRegsContent().
735    **        Set the content of the data window to consist of the float registers.
736  */
737 static TuiStatus
738 _tuiSetFloatRegsContent (TuiRegisterDisplayType dpyType, int refreshValuesOnly)
739 {
740   TuiStatus ret = TUI_FAILURE;
741   int startRegNum;
742
743   startRegNum = FP0_REGNUM;
744   ret = _tuiSetRegsContent (startRegNum,
745                             NUM_REGS - 1,
746                             deprecated_selected_frame,
747                             dpyType,
748                             refreshValuesOnly);
749
750   return ret;
751 }                               /* _tuiSetFloatRegsContent */
752
753
754 /*
755    ** _tuiRegValueHasChanged().
756    **        Answer TRUE if the register's value has changed, FALSE otherwise.
757    **        If TRUE, newValue is filled in with the new value.
758  */
759 static int
760 _tuiRegValueHasChanged (TuiDataElementPtr dataElement,
761                         struct frame_info *frame,
762                         char *newValue)
763 {
764   int hasChanged = FALSE;
765
766   if (dataElement->itemNo != UNDEFINED_ITEM &&
767       _tuiRegisterName (dataElement->itemNo) != (char *) NULL)
768     {
769       char rawBuf[MAX_REGISTER_SIZE];
770       int i;
771
772       if (_tuiGetRegisterRawValue (
773                          dataElement->itemNo, rawBuf, frame) == TUI_SUCCESS)
774         {
775           int size = REGISTER_RAW_SIZE (dataElement->itemNo);
776           
777           for (i = 0; (i < size && !hasChanged); i++)
778             hasChanged = (((char *) dataElement->value)[i] != rawBuf[i]);
779           if (hasChanged && newValue != (char *) NULL)
780             {
781               for (i = 0; i < size; i++)
782                 newValue[i] = rawBuf[i];
783             }
784         }
785     }
786   return hasChanged;
787 }                               /* _tuiRegValueHasChanged */
788
789
790
791 /*
792    ** _tuiGetRegisterRawValue().
793    **        Get the register raw value.  The raw value is returned in regValue.
794  */
795 static TuiStatus
796 _tuiGetRegisterRawValue (int regNum, char *regValue, struct frame_info *frame)
797 {
798   TuiStatus ret = TUI_FAILURE;
799
800   if (target_has_registers)
801     {
802       frame_read_register (frame, regNum, regValue);
803       /* NOTE: cagney/2003-03-13: This is bogus.  It is refering to
804          the register cache and not the frame which could have pulled
805          the register value off the stack.  */
806       if (register_cached (regNum) >= 0)
807         ret = TUI_SUCCESS;
808     }
809   return ret;
810 }                               /* _tuiGetRegisterRawValue */
811
812
813
814 /*
815    ** _tuiSetRegisterElement().
816    **       Function to initialize a data element with the input and
817    **       the register value.
818  */
819 static void
820 _tuiSetRegisterElement (int regNum, struct frame_info *frame,
821                         TuiDataElementPtr dataElement,
822                         int refreshValueOnly)
823 {
824   if (dataElement != (TuiDataElementPtr) NULL)
825     {
826       if (!refreshValueOnly)
827         {
828           dataElement->itemNo = regNum;
829           dataElement->name = _tuiRegisterName (regNum);
830           dataElement->highlight = FALSE;
831         }
832       if (dataElement->value == (Opaque) NULL)
833         dataElement->value = (Opaque) xmalloc (MAX_REGISTER_SIZE);
834       if (dataElement->value != (Opaque) NULL)
835         _tuiGetRegisterRawValue (regNum, dataElement->value, frame);
836     }
837
838   return;
839 }                               /* _tuiSetRegisterElement */
840
841
842 /*
843    ** _tuiSetRegsContent().
844    **        Set the content of the data window to consist of the registers
845    **        numbered from startRegNum to endRegNum.  Note that if
846    **        refreshValuesOnly is TRUE, startRegNum and endRegNum are ignored.
847  */
848 static TuiStatus
849 _tuiSetRegsContent (int startRegNum, int endRegNum,
850                     struct frame_info *frame,
851                     TuiRegisterDisplayType dpyType,
852                     int refreshValuesOnly)
853 {
854   TuiStatus ret = TUI_FAILURE;
855   int numRegs = endRegNum - startRegNum + 1;
856   int allocatedHere = FALSE;
857
858   if (dataWin->detail.dataDisplayInfo.regsContentCount > 0 &&
859       !refreshValuesOnly)
860     {
861       freeDataContent (dataWin->detail.dataDisplayInfo.regsContent,
862                        dataWin->detail.dataDisplayInfo.regsContentCount);
863       dataWin->detail.dataDisplayInfo.regsContentCount = 0;
864     }
865   if (dataWin->detail.dataDisplayInfo.regsContentCount <= 0)
866     {
867       dataWin->detail.dataDisplayInfo.regsContent =
868         allocContent (numRegs, DATA_WIN);
869       allocatedHere = TRUE;
870     }
871
872   if (dataWin->detail.dataDisplayInfo.regsContent != (TuiWinContent) NULL)
873     {
874       int i;
875
876       if (!refreshValuesOnly || allocatedHere)
877         {
878           dataWin->generic.content = (OpaquePtr) NULL;
879           dataWin->generic.contentSize = 0;
880           addContentElements (&dataWin->generic, numRegs);
881           dataWin->detail.dataDisplayInfo.regsContent =
882             (TuiWinContent) dataWin->generic.content;
883           dataWin->detail.dataDisplayInfo.regsContentCount = numRegs;
884         }
885       /*
886          ** Now set the register names and values
887        */
888       for (i = startRegNum; (i <= endRegNum); i++)
889         {
890           TuiGenWinInfoPtr dataItemWin;
891
892           dataItemWin = &dataWin->detail.dataDisplayInfo.
893             regsContent[i - startRegNum]->whichElement.dataWindow;
894           _tuiSetRegisterElement (
895                                    i,
896                                    frame,
897            &((TuiWinElementPtr) dataItemWin->content[0])->whichElement.data,
898                                    !allocatedHere && refreshValuesOnly);
899         }
900       dataWin->detail.dataDisplayInfo.regsColumnCount =
901         tuiCalculateRegsColumnCount (dpyType);
902 #ifdef LATER
903       if (dataWin->detail.dataDisplayInfo.dataContentCount > 0)
904         {
905           /* delete all the windows? */
906           /* realloc content equal to dataContentCount + regsContentCount */
907           /* append dataWin->detail.dataDisplayInfo.dataContent to content */
908         }
909 #endif
910       dataWin->generic.contentSize =
911         dataWin->detail.dataDisplayInfo.regsContentCount +
912         dataWin->detail.dataDisplayInfo.dataContentCount;
913       ret = TUI_SUCCESS;
914     }
915
916   return ret;
917 }                               /* _tuiSetRegsContent */
918
919
920 /*
921    ** _tuiDisplayRegister().
922    **        Function to display a register in a window.  If hilite is TRUE,
923    **        than the value will be displayed in reverse video
924  */
925 static void
926 _tuiDisplayRegister (int regNum,
927                      TuiGenWinInfoPtr winInfo,          /* the data item window */
928                      enum precision_type precision)
929 {
930   if (winInfo->handle != (WINDOW *) NULL)
931     {
932       int i;
933       char buf[40];
934       int valueCharsWide, labelWidth;
935       TuiDataElementPtr dataElementPtr = &((TuiWinContent)
936                                     winInfo->content)[0]->whichElement.data;
937
938       if (IS_64BIT ||
939           dataWin->detail.dataDisplayInfo.regsDisplayType == TUI_DFLOAT_REGS)
940         {
941           valueCharsWide = DOUBLE_FLOAT_VALUE_WIDTH;
942           labelWidth = DOUBLE_FLOAT_LABEL_WIDTH;
943         }
944       else
945         {
946           if (dataWin->detail.dataDisplayInfo.regsDisplayType ==
947               TUI_SFLOAT_REGS)
948             {
949               valueCharsWide = SINGLE_FLOAT_VALUE_WIDTH;
950               labelWidth = SINGLE_FLOAT_LABEL_WIDTH;
951             }
952           else
953             {
954               valueCharsWide = SINGLE_VALUE_WIDTH;
955               labelWidth = SINGLE_LABEL_WIDTH;
956             }
957         }
958
959       buf[0] = (char) 0;
960       _tuiRegisterFormat (buf,
961                           valueCharsWide + labelWidth,
962                           regNum,
963                           dataElementPtr,
964                           precision);
965
966       if (dataElementPtr->highlight)
967         wstandout (winInfo->handle);
968
969       wmove (winInfo->handle, 0, 0);
970       for (i = 1; i < winInfo->width; i++)
971         waddch (winInfo->handle, ' ');
972       wmove (winInfo->handle, 0, 0);
973       waddstr (winInfo->handle, buf);
974
975       if (dataElementPtr->highlight)
976         wstandend (winInfo->handle);
977       tuiRefreshWin (winInfo);
978     }
979   return;
980 }                               /* _tuiDisplayRegister */
981
982
983 static void
984 _tui_vShowRegisters_commandSupport (TuiRegisterDisplayType dpyType)
985 {
986
987   if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
988     {                           /* Data window already displayed, show the registers */
989       if (dataWin->detail.dataDisplayInfo.regsDisplayType != dpyType)
990         tuiShowRegisters (dpyType);
991     }
992   else
993     (tuiLayoutDef ())->regsDisplayType = dpyType;
994
995   return;
996 }                               /* _tui_vShowRegisters_commandSupport */
997
998
999 static void
1000 _tuiShowFloat_command (char *arg, int fromTTY)
1001 {
1002   if (m_winPtrIsNull (dataWin) || !dataWin->generic.isVisible ||
1003       (dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_SFLOAT_REGS &&
1004        dataWin->detail.dataDisplayInfo.regsDisplayType != TUI_DFLOAT_REGS))
1005     _tui_vShowRegisters_commandSupport ((tuiLayoutDef ())->floatRegsDisplayType);
1006
1007   return;
1008 }                               /* _tuiShowFloat_command */
1009
1010
1011 static void
1012 _tuiShowGeneral_command (char *arg, int fromTTY)
1013 {
1014   _tui_vShowRegisters_commandSupport (TUI_GENERAL_REGS);
1015 }
1016
1017
1018 static void
1019 _tuiShowSpecial_command (char *arg, int fromTTY)
1020 {
1021   _tui_vShowRegisters_commandSupport (TUI_SPECIAL_REGS);
1022 }
1023
1024
1025 static void
1026 _tuiToggleFloatRegs_command (char *arg, int fromTTY)
1027 {
1028   if (m_winPtrNotNull (dataWin) && dataWin->generic.isVisible)
1029     tuiToggleFloatRegs ();
1030   else
1031     {
1032       TuiLayoutDefPtr layoutDef = tuiLayoutDef ();
1033
1034       if (layoutDef->floatRegsDisplayType == TUI_SFLOAT_REGS)
1035         layoutDef->floatRegsDisplayType = TUI_DFLOAT_REGS;
1036       else
1037         layoutDef->floatRegsDisplayType = TUI_SFLOAT_REGS;
1038     }
1039
1040
1041   return;
1042 }                               /* _tuiToggleFloatRegs_command */
1043
1044
1045 static void
1046 _tuiScrollRegsForward_command (char *arg, int fromTTY)
1047 {
1048   tui_scroll (FORWARD_SCROLL, dataWin, 1);
1049 }
1050
1051
1052 static void
1053 _tuiScrollRegsBackward_command (char *arg, int fromTTY)
1054 {
1055   tui_scroll (BACKWARD_SCROLL, dataWin, 1);
1056 }
This page took 0.085511 seconds and 4 git commands to generate.