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