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