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