source: vendor/emx/current/src/pmgdb/display.cc

Last change on this file was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 24.7 KB
Line 
1/* display.cc
2 Copyright (c) 1996 Eberhard Mattes
3
4This file is part of pmgdb.
5
6pmgdb is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11pmgdb is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with pmgdb; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22#define INCL_WIN
23#include <os2.h>
24#include <stdlib.h>
25#include <stdio.h> // sprintf()
26#include <stdarg.h>
27#include <string.h>
28#include <ctype.h>
29#include "string.h"
30#include "pmapp.h"
31#include "pmframe.h"
32#include "pmtxt.h"
33#include "pmtty.h"
34#include "pmgdb.h"
35#include "help.h"
36#include "breakpoi.h"
37#include "display.h"
38#include "annotati.h"
39#include "capture.h"
40#include "gdbio.h"
41#include "command.h"
42
43
44class dispfmt
45{
46public:
47 dispfmt () { count = 1; format = 0; size = 0; }
48 ~dispfmt () {}
49 void parse (const char *str);
50 void print (char *str) const;
51
52 int count;
53 char format;
54 char size;
55};
56
57
58class display_window::display
59{
60public:
61 display () { enable = true; type = not_set; }
62 display (const display &src);
63 ~display () {}
64 bool is_line (int y) { return line <= y && y < line + line_count; }
65 void set_type (gdbio *gdb);
66 display &operator = (const display &src);
67
68 // Dialog box
69 MRESULT display_msg (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
70
71 vstring expr;
72 vstring format;
73 vstring value;
74 display *next;
75 int number;
76 int line;
77 int line_count;
78 enum
79 {
80 not_set,
81 pointer,
82 other,
83 } type;
84 bool enable;
85};
86
87
88void dispfmt::parse (const char *s)
89{
90 count = 1; size = 0; format = 0;
91 s = strchr (s, '/');
92 s = s != NULL ? s + 1 : "";
93 if (*s >= '0' && *s <= '9')
94 {
95 count = atoi (s);
96 while (*s >= '0' && *s <= '9')
97 ++s;
98 }
99 while (*s != 0)
100 if (*s == 'b' || *s == 'h' || *s == 'w' || *s == 'g')
101 size = *s++;
102 else if (*s >= 'a' && *s <= 'z')
103 format = *s++;
104 else
105 break;
106}
107
108
109void dispfmt::print (char *str) const
110{
111 if (count != 1 || format != 0 || size != 0)
112 {
113 if (count != 1)
114 str += sprintf (str, "/%d", count);
115 else
116 *str++ = '/';
117 if (format != 0)
118 *str++ = format;
119 if (size != 0)
120 *str++ = size;
121 }
122 *str = 0;
123}
124
125
126display_window::display::display (const display &src)
127{
128 expr = src.expr;
129 format = src.format;
130 value = src.value;
131 next = NULL;
132 number = src.number;
133 line = src.line;
134 line_count = src.line_count;
135 enable = src.enable;
136}
137
138
139void display_window::display::set_type (gdbio *gdb)
140{
141 capture *capt;
142 capt = gdb->capture_cmd ("whatis %s", (const char *)expr);
143 if (capt == NULL)
144 return;
145 if (capt->error.is_set ())
146 type = other;
147 else
148 {
149 const char *s = gdb->get_output ();
150 int len = gdb->get_output ().length ();
151 while (len > 0 && s[len-1] == '\n')
152 --len;
153 if (len > 0 && s[len-1] == '*')
154 type = pointer;
155 else
156 type = other;
157 }
158 delete_capture (capt);
159}
160
161
162display_window::display
163&display_window::display::operator = (const display &src)
164{
165 expr = src.expr;
166 format = src.format;
167 value = src.value;
168 next = NULL;
169 number = src.number;
170 line = src.line;
171 line_count = src.line_count;
172 enable = src.enable;
173 type = src.type;
174 return *this;
175}
176
177
178static const struct
179{
180 const char *desc;
181 char chr;
182} formats[] =
183 {
184 {"Default", 0},
185 {"Signed decimal", 'd'},
186 {"Unsigned decimal", 'u'},
187 {"Hexadecimal", 'x'},
188 {"Octal", 'o'},
189 {"Binary", 't'},
190 {"Character", 'c'},
191 {"Address", 'a'},
192 {"Floating point", 'f'},
193 {"String", 's'},
194 {"Instruction", 'i'}
195 };
196
197#define N_FORMATS (sizeof (formats) / sizeof (formats[0]))
198
199MRESULT display_window::display::display_msg (HWND hwnd, ULONG msg,
200 MPARAM mp1, MPARAM mp2)
201{
202 MRESULT mr;
203 HWND hwndTemp;
204 int i;
205 char fmtstr[40];
206
207 switch (msg)
208 {
209 case WM_INITDLG:
210 {
211 dispfmt fmt;
212 dlg_sys_menu (hwnd);
213 WinSetWindowPtr (hwnd, QWL_USER, this);
214 WinSendDlgItemMsg (hwnd, IDC_ENABLE, BM_SETCHECK,
215 MPFROMSHORT (enable), NULL);
216 WinSendDlgItemMsg (hwnd, IDC_EXPR, EM_SETTEXTLIMIT,
217 MPFROMSHORT (128), 0);
218 if (!expr.is_null ())
219 WinSetDlgItemText (hwnd, IDC_EXPR, (PCSZ)expr);
220 if (!format.is_null ())
221 fmt.parse (format);
222 hwndTemp = WinWindowFromID (hwnd, IDC_FORMAT);
223 for (i = 0; i < (int)N_FORMATS; ++i)
224 {
225 WinSendMsg (hwndTemp, LM_INSERTITEM, MPFROMSHORT (i),
226 MPFROMP (formats[i].desc));
227 if (formats[i].chr == fmt.format)
228 WinSendMsg (hwndTemp, LM_SELECTITEM,
229 MPFROMSHORT (i), MPFROMSHORT (TRUE));
230 }
231 if (fmt.format == 0)
232 WinSendMsg (hwndTemp, LM_SELECTITEM,
233 MPFROMSHORT (0), MPFROMSHORT (TRUE));
234 WinSendDlgItemMsg (hwnd, IDC_COUNT, SPBM_SETCURRENTVALUE,
235 MPFROMLONG (fmt.count), 0);
236 WinSendDlgItemMsg (hwnd, IDC_COUNT, SPBM_SETLIMITS,
237 MPFROMLONG (99), MPFROMLONG (1));
238 break;
239 }
240
241 case WM_CONTROL:
242 switch (SHORT1FROMMP (mp1))
243 {
244 case IDC_FORMAT:
245 mr = WinSendDlgItemMsg (hwnd, IDC_FORMAT, LM_QUERYSELECTION,
246 MPFROMSHORT (LIT_FIRST), 0);
247 i = SHORT1FROMMR (mr);
248 bool enable_count = (i != LIT_NONE
249 && (formats[i].chr == 's'
250 || formats[i].chr == 'i'));
251 WinEnableWindow (WinWindowFromID (hwnd, IDC_COUNT), enable_count);
252 break;
253 }
254 return 0;
255
256 case WM_COMMAND:
257 switch (SHORT1FROMMP (mp1))
258 {
259 case DID_OK:
260 {
261 dispfmt fmt;
262 LONG n;
263 mr = WinSendDlgItemMsg (hwnd, IDC_ENABLE, BM_QUERYCHECK, 0, 0);
264 enable = (bool)SHORT1FROMMR (mr);
265 LONG len = WinQueryDlgItemTextLength (hwnd, IDC_EXPR);
266 expr.set (len);
267 WinQueryDlgItemText (hwnd, IDC_EXPR, len + 1, (PSZ)expr.modify ());
268
269 mr = WinSendDlgItemMsg (hwnd, IDC_FORMAT, LM_QUERYSELECTION,
270 MPFROMSHORT (LIT_FIRST), 0);
271 i = SHORT1FROMMR (mr);
272 if (i != LIT_NONE && i != 0)
273 {
274 fmt.format = formats[i].chr;
275 if (fmt.format == 's' || fmt.format == 'i')
276 {
277 mr = WinSendDlgItemMsg (hwnd, IDC_COUNT, SPBM_QUERYVALUE,
278 MPFROMP (&n),
279 MPFROM2SHORT (0,
280 SPBQ_ALWAYSUPDATE));
281 if (SHORT1FROMMR (mr))
282 fmt.count = n;
283 }
284 fmt.print (fmtstr);
285 format.set (fmtstr);
286 }
287 else
288 format.set ("");
289 WinDismissDlg (hwnd, DID_OK);
290 return 0;
291 }
292 }
293 break;
294 }
295 return WinDefDlgProc (hwnd, msg, mp1, mp2);
296}
297
298
299MRESULT EXPENTRY dlg_display (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
300{
301 display_window::display *p;
302
303 if (msg == WM_INITDLG)
304 p = (display_window::display *)((struct pm_create *)PVOIDFROMMP (mp2))->ptr;
305 else
306 p = (display_window::display *)WinQueryWindowPtr (hwnd, QWL_USER);
307 return p->display_msg (hwnd, msg, mp1, mp2);
308}
309
310
311#define DSP_HEADER_LINES 1
312
313display_window::display_window (command_window *in_cmd, gdbio *in_gdb,
314 unsigned in_id, const SWP *pswp,
315 const char *fontnamesize)
316 : pmtxt (in_cmd->get_app (), in_id,
317 pswp == NULL ? FCF_SHELLPOSITION : 0, pswp, fontnamesize)
318{
319 cmd = in_cmd; gdb = in_gdb;
320 head = NULL;
321 sel_line = -1;
322 exp_number = -1;
323
324 sel_attr = get_default_attr ();
325 set_fg_color (sel_attr, CLR_BLACK);
326 set_bg_color (sel_attr, CLR_PALEGRAY);
327
328 delete_all_displays (true); // Update menu, insert header line
329 set_title ("pmgdb - Display");
330 set_keys_help_id (HELP_THR_KEYS);
331}
332
333
334display_window::~display_window ()
335{
336 delete_all_displays (false);
337}
338
339
340void display_window::delete_all_displays (bool init)
341{
342 display *p, *next;
343 for (p = head; p != NULL; p = next)
344 {
345 next = p->next;
346 delete p;
347 }
348 head = NULL;
349 sel_line = -1;
350
351 if (init)
352 {
353 delete_all ();
354 int x = 0;
355 put (0, x, 4, " No ", false); x += 4;
356 put_tab (0, x++, false);
357 put_vrule (0, x++, false);
358 put (0, x, 5, " Ena ", false); x += 5;
359 put_tab (0, x++, false);
360 put_vrule (0, x++, false);
361 put (0, x, 5, " Fmt ", false); x += 5;
362 put_tab (0, x++, false);
363 put_vrule (0, x++, false);
364 put (0, x, 6, " Expr ", false); x += 6;
365 put_tab (0, x++, false);
366 put_vrule (0, x++, false);
367 put (0, x, 6, " Value", false); x += 6;
368 underline (0, true, false);
369 sync ();
370 menu_enable (IDM_ENABLE, false);
371 menu_enable (IDM_DISABLE, false);
372 menu_enable (IDM_MODIFY, false);
373 menu_enable (IDM_DELETE, false);
374 menu_enable (IDM_ENABLE_ALL, false);
375 menu_enable (IDM_DISABLE_ALL, false);
376 menu_enable (IDM_DELETE_ALL, false);
377 menu_enable (IDM_REPMENU, false);
378 menu_enable (IDM_DEREFERENCE, false);
379 }
380}
381
382
383bool display_window::add (HWND hwnd)
384{
385 bool result = false;
386 display temp;
387 pm_create create;
388 create.cb = sizeof (create);
389 create.ptr = (void *)&temp;
390 if (WinDlgBox (HWND_DESKTOP, hwnd, dlg_display, 0, IDD_DISPLAY,
391 &create) == DID_OK
392 && temp.expr[0] != 0)
393 {
394 select_line (-1);
395 capture *capt;
396 capt = gdb->capture_cmd ("server display %s %s",
397 (const char *)temp.format,
398 (const char *)temp.expr);
399 if (capt != NULL && capt->disp_number.is_set ())
400 {
401 int number = capt->disp_number.get ();
402 if (!temp.enable)
403 gdb->send_cmd ("server disable display %d", number);
404 exp_number = number;
405 exp_line = -1;
406 exp_enable = temp.enable;
407 result = true;
408 }
409 delete_capture (capt);
410 }
411 return result;
412}
413
414
415MRESULT display_window::wm_close (HWND, ULONG, MPARAM, MPARAM)
416{
417 show (false);
418 return 0;
419}
420
421
422MRESULT display_window::wm_command (HWND hwnd, ULONG msg,
423 MPARAM mp1, MPARAM mp2)
424{
425 display *p;
426
427 switch (SHORT1FROMMP (mp1))
428 {
429 case IDM_ENABLE:
430 p = find_by_line (sel_line);
431 if (p == NULL)
432 WinAlarm (HWND_DESKTOP, WA_ERROR);
433 else
434 gdb->send_cmd ("server enable display %d", p->number);
435 return 0;
436
437 case IDM_DISABLE:
438 p = find_by_line (sel_line);
439 if (p == NULL)
440 WinAlarm (HWND_DESKTOP, WA_ERROR);
441 else
442 gdb->send_cmd ("server disable display %d", p->number);
443 return 0;
444
445 case IDM_DELETE:
446 p = find_by_line (sel_line);
447 if (p == NULL)
448 WinAlarm (HWND_DESKTOP, WA_ERROR);
449 else
450 gdb->send_cmd ("server undisplay %d", p->number);
451 return 0;
452
453 case IDM_ADD:
454 add (hwnd);
455 return 0;
456
457 case IDM_MODIFY:
458 p = find_by_line (sel_line);
459 if (p == NULL)
460 WinAlarm (HWND_DESKTOP, WA_ERROR);
461 else
462 modify (p);
463 return 0;
464
465 case IDM_ENABLE_ALL:
466 gdb->send_cmd ("server enable display");
467 return 0;
468
469 case IDM_DISABLE_ALL:
470 gdb->send_cmd ("server disable display");
471 return 0;
472
473 case IDM_DELETE_ALL:
474 gdb->send_cmd ("server undisplay");
475 delete_all_displays (true); // GDB doesn't send an annotation!
476 return 0;
477
478 case IDM_REP_DEC_S:
479 change_representation ('d');
480 return 0;
481
482 case IDM_REP_DEC_U:
483 change_representation ('u');
484 return 0;
485
486 case IDM_REP_HEX:
487 change_representation ('x');
488 return 0;
489
490 case IDM_REP_OCT:
491 change_representation ('o');
492 return 0;
493
494 case IDM_REP_BIN:
495 change_representation ('t');
496 return 0;
497
498 case IDM_REP_ADR:
499 change_representation ('a');
500 return 0;
501
502 case IDM_REP_CHR:
503 change_representation ('c');
504 return 0;
505
506 case IDM_REP_FLT:
507 change_representation ('f');
508 return 0;
509
510 case IDM_REP_STR:
511 change_representation ('s');
512 return 0;
513
514 case IDM_REP_INS:
515 change_representation ('i');
516 return 0;
517
518 case IDM_DEREFERENCE:
519 p = find_by_line (sel_line);
520 if (p == NULL)
521 WinAlarm (HWND_DESKTOP, WA_ERROR);
522 else
523 dereference (p, false);
524 return 0;
525
526 default:
527 return cmd->wm_command (hwnd, msg, mp1, mp2);
528 }
529}
530
531
532bool display_window::wm_user (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
533{
534 if (parent::wm_user (hwnd, msg, mp1, mp2))
535 return true;
536 switch (msg)
537 {
538 case UWM_MENU:
539 // TODO: Cache
540 if (sel_line == -1)
541 {
542 menu_enable (IDM_ENABLE, false);
543 menu_enable (IDM_DISABLE, false);
544 menu_enable (IDM_MODIFY, false);
545 menu_enable (IDM_DELETE, false);
546 menu_enable (IDM_REPMENU, false);
547 menu_enable (IDM_DEREFERENCE, false);
548 }
549 else
550 {
551 const display *p = find_by_line (sel_line);
552 menu_enable (IDM_ENABLE, !p->enable);
553 menu_enable (IDM_DISABLE, p->enable);
554 menu_enable (IDM_MODIFY, true);
555 menu_enable (IDM_DELETE, true);
556 menu_enable (IDM_REPMENU, true);
557 // TODO: null pointer
558 menu_enable (IDM_DEREFERENCE, p->type == display::pointer);
559 }
560 menu_enable (IDM_ENABLE_ALL, head != NULL);
561 menu_enable (IDM_DISABLE_ALL, head != NULL);
562 menu_enable (IDM_DELETE_ALL, head != NULL);
563 return true;
564
565 default:
566 return false;
567 }
568}
569
570
571MRESULT display_window::wm_activate (HWND hwnd, ULONG msg,
572 MPARAM mp1, MPARAM mp2)
573{
574 if (SHORT1FROMMP (mp1))
575 cmd->associate_help (get_hwndFrame ());
576 return WinDefWindowProc (hwnd, msg, mp1, mp2);
577}
578
579
580void display_window::button_event (int line, int column, int tab, int button,
581 int clicks)
582{
583 if (line >= 0 && column >= 0)
584 {
585 // TODO: Context menu
586 if (button == 1 && clicks == 2 && tab == 1)
587 {
588 const display *p = find_by_line (line);
589 if (p == NULL)
590 WinAlarm (HWND_DESKTOP, WA_ERROR);
591 else
592 gdb->send_cmd ("server %s display %d",
593 p->enable ? "disable" : "enable", p->number);
594 }
595 else if (button == 1 && clicks == 2 && tab >= 2 && tab <= 3)
596 {
597 display *p = find_by_line (line);
598 if (p == NULL)
599 WinAlarm (HWND_DESKTOP, WA_ERROR);
600 else
601 {
602 select_line (line);
603 modify (p);
604 }
605 }
606 else if (button == 1 && clicks == 1)
607 select_line (line, true);
608 else if (button == 1 && clicks == 2)
609 select_line (line);
610 }
611 else
612 select_line (-1);
613}
614
615
616display_window::display *display_window::find_by_number (int number)
617{
618 for (display *p = head; p != NULL; p = p->next)
619 if (p->number == number)
620 return p;
621 return NULL;
622}
623
624
625display_window::display *display_window::find_by_line (int line)
626{
627 for (display *p = head; p != NULL; p = p->next)
628 if (p->is_line (line))
629 return p;
630 return NULL;
631}
632
633
634void display_window::enable (int number)
635{
636 display *p = find_by_number (number);
637 if (p != NULL && !p->enable)
638 {
639 p->enable = true;
640 if (p->line == sel_line)
641 WinPostMsg (get_hwndClient (), UWM_MENU, 0, 0);
642 update (p);
643 }
644}
645
646
647void display_window::disable (int number)
648{
649 display *p = find_by_number (number);
650 if (p != NULL && p->enable)
651 {
652 p->enable = false;
653 if (p->line == sel_line)
654 WinPostMsg (get_hwndClient (), UWM_MENU, 0, 0);
655 update (p);
656 }
657}
658
659
660void display_window::remove (int number)
661{
662 for (display **patch = &head; *patch != NULL; patch = &(*patch)->next)
663 if ((*patch)->number == number)
664 {
665 display *p = *patch;
666 for (display *q = (*patch)->next; q != NULL; q = q->next)
667 q->line -= p->line_count;
668 if (p->line == sel_line)
669 {
670 sel_line = -1;
671 WinPostMsg (get_hwndClient (), UWM_MENU, 0, 0);
672 }
673 delete_lines (p->line, p->line_count, true);
674 *patch = p->next;
675 delete p;
676 return;
677 }
678}
679
680
681void display_window::update (display *p)
682{
683 char buf[400];
684 int x = 0, len, line_count, diff;
685 pmtxt_attr attr;
686
687 if (p->line == sel_line)
688 attr = sel_attr;
689 else
690 attr = get_default_attr ();
691
692 line_count = 1;
693 if (p->enable)
694 for (const char *s = p->value; *s != 0; ++s)
695 if (*s == '\n')
696 ++line_count;
697
698 diff = line_count - p->line_count;
699 if (diff < 0)
700 delete_lines (p->line + line_count, -diff, true);
701 if (diff > 0)
702 insert_lines (p->line + p->line_count, diff, true);
703 if (diff != 0)
704 {
705 for (display *q = p->next; q != NULL; q = q->next)
706 q->line += diff;
707 if (sel_line == p->line)
708 sel_count = line_count;
709 else if (sel_line > p->line)
710 sel_line += diff;
711 p->line_count = line_count;
712 }
713 clear_lines (p->line, line_count, true);
714
715 len = snprintf (buf, sizeof (buf), " %d ", p->number);
716 put (p->line, x, len, buf, attr, true); x += len;
717 put_tab (p->line, x++, attr, true);
718 put_vrule (p->line, x++, attr, true);
719
720 len = snprintf (buf, sizeof (buf), " %c ", p->enable ? 'y' : 'n');
721 put (p->line, x, len, buf, attr, true); x += len;
722 put_tab (p->line, x++, attr, true);
723 put_vrule (p->line, x++, attr, true);
724
725 len = snprintf (buf, sizeof (buf), " %s ", (const char *)p->format);
726 put (p->line, x, len, buf, attr, true); x += len;
727 put_tab (p->line, x++, attr, true);
728 put_vrule (p->line, x++, attr, true);
729
730 len = snprintf (buf, sizeof (buf), " %s ", (const char *)p->expr);
731 put (p->line, x, len, buf, attr, true); x += len;
732 put_tab (p->line, x++, attr, true);
733 put_vrule (p->line, x++, attr, true);
734
735 if (p->line == sel_line)
736 set_eol_attr (p->line, sel_attr, true);
737
738 if (p->enable)
739 {
740 int y = p->line;
741 const char *s = p->value;
742 while (*s != 0)
743 {
744 const char *nl = strchr (s, '\n');
745 len = nl != NULL ? nl - s : strlen (s);
746 if (y != p->line)
747 {
748 if (p->line == sel_line)
749 set_eol_attr (y, sel_attr, true);
750 for (int i = 0; i < 4; ++i)
751 {
752 put_tab (y, x++, attr, true);
753 put_vrule (y, x++, attr, true);
754 }
755 }
756 put (y, x++, 1, " ", attr, true);
757 const char *tab;
758 while ((tab = (const char *)memchr (s, '\t', len)) != NULL)
759 {
760 if (tab != s)
761 {
762 put (y, x, tab - s, s, attr, true);
763 x += tab - s; len -= tab - s; s = tab;
764 }
765 ++s; --len; // Skip TAB
766 put (y, x++, 1, " ", attr, true);
767 put_tab (y, x++, attr, true);
768 }
769 if (len != 0)
770 {
771 put (y, x, len, s, attr, true);
772 s += len;
773 }
774 if (*s != 0)
775 {
776 ++s; // Skip linefeed
777 ++y; x = 0; // New line
778 }
779 }
780 }
781}
782
783
784void display_window::update (int number, const char *expr, const char *format,
785 const char *value, bool enable)
786{
787 int undisplay = -1;
788 display *p = find_by_number (number);
789 if (value == NULL) value = "";
790
791 if (p == NULL)
792 {
793 if (exp_number == number && exp_line != -1
794 && (p = find_by_line (exp_line)) != NULL)
795 {
796 // Modifying a display
797 undisplay = p->number;
798 p->line = exp_line;
799 }
800 else
801 {
802 // New display
803 if (head == NULL)
804 {
805 menu_enable (IDM_ENABLE_ALL, true);
806 menu_enable (IDM_DISABLE_ALL, true);
807 menu_enable (IDM_DELETE_ALL, true);
808 }
809
810 display **patch = &head;
811 int line = DSP_HEADER_LINES;
812 while (*patch != NULL)
813 {
814 line += (*patch)->line_count;
815 patch = &(*patch)->next;
816 }
817 p = new display;
818 *patch = p;
819 p->next = NULL;
820 p->line = line;
821 p->line_count = 1;
822 p->enable = true;
823 }
824 p->number = number;
825 p->expr.set (expr);
826 p->format.set (format);
827 p->value.set (value);
828 p->set_type (gdb);
829 }
830 else
831 {
832 if (number != exp_number && strcmp (value, p->value) == 0)
833 return;
834 // TODO: Redraw value only (if only the value changed)
835 p->value.set (value);
836 }
837
838 // Set the state of a new display before GDB knows about and reports
839 // the new state
840 if (number == exp_number)
841 {
842 p->enable = exp_enable;
843 select_line (p->line);
844 }
845 if (!enable)
846 p->enable = false;
847 exp_number = -1;
848 if (undisplay != -1)
849 gdb->send_cmd ("server undisplay %d", undisplay);
850 update (p);
851}
852
853
854void display_window::select_line (int line, bool toggle)
855{
856 const display *p = line == -1 ? (display *)NULL : find_by_line (line);
857 line = p != NULL ? p->line : -1; // Normalize
858 if (toggle && line != -1 && line == sel_line)
859 line = -1;
860 if (line != sel_line)
861 {
862 if (sel_line != -1)
863 for (int i = 0; i < sel_count; ++i)
864 {
865 put (sel_line + i, 0, max_line_len, get_default_attr (), true);
866 set_eol_attr (sel_line + i, get_default_attr (), true);
867 }
868 if (line != -1)
869 {
870 sel_count = p->line_count;
871 for (int i = 0; i < sel_count; ++i)
872 {
873 put (line + i, 0, max_line_len, sel_attr, true);
874 set_eol_attr (line + i, sel_attr, true);
875 }
876 }
877 sel_line = line;
878 }
879 // TODO: Cache
880 if (line != -1)
881 {
882 menu_enable (IDM_ENABLE, !p->enable);
883 menu_enable (IDM_DISABLE, p->enable);
884 menu_enable (IDM_MODIFY, true);
885 menu_enable (IDM_DELETE, true);
886 menu_enable (IDM_REPMENU, true);
887 menu_enable (IDM_DEREFERENCE, p->type == display::pointer);
888 show_line (line, 1, 1);
889 }
890 else
891 {
892 menu_enable (IDM_ENABLE, false);
893 menu_enable (IDM_DISABLE, false);
894 menu_enable (IDM_MODIFY, false);
895 menu_enable (IDM_DELETE, false);
896 menu_enable (IDM_REPMENU, false);
897 menu_enable (IDM_DEREFERENCE, false);
898 }
899}
900
901
902void display_window::modify (const display *p, const char *new_format,
903 const char *new_expr, bool new_enable, bool add)
904{
905 select_line (-1);
906 if (new_format == NULL)
907 new_format = p->format;
908 if (new_expr == NULL)
909 new_expr = p->expr;
910 capture *capt;
911 capt = gdb->capture_cmd ("server display %s %s", new_format, new_expr);
912 if (capt != NULL && capt->disp_number.is_set ())
913 {
914 int number = capt->disp_number.get ();
915 exp_number = number;
916 exp_enable = new_enable;
917 exp_line = add ? -1 : p->line;
918 if (!new_enable)
919 gdb->send_cmd ("server disable display %d", number);
920 }
921 delete_capture (capt);
922}
923
924
925void display_window::change_representation (char fmtchr)
926{
927 display *p = find_by_line (sel_line);
928 if (p == NULL)
929 {
930 WinAlarm (HWND_DESKTOP, WA_ERROR);
931 return;
932 }
933
934 dispfmt fmt;
935 fmt.parse (p->format);
936
937 if (fmtchr == fmt.format)
938 return;
939 fmt.format = fmtchr;
940 char new_format_buf[20];
941 fmt.print (new_format_buf);
942 modify (p, new_format_buf, NULL, p->enable, false);
943}
944
945
946void display_window::modify (display *p)
947{
948 display temp = *p;
949 pm_create create;
950 create.cb = sizeof (create);
951 create.ptr = (void *)&temp;
952 if (WinDlgBox (HWND_DESKTOP, get_hwndClient (), dlg_display, 0, IDD_DISPLAY,
953 &create) == DID_OK
954 && temp.expr[0] != 0
955 && (temp.enable != p->enable
956 || strcmp (temp.expr, p->expr) != 0
957 || strcmp (temp.format, p->format) != 0))
958 {
959 if (strcmp (temp.expr, p->expr) == 0
960 && strcmp (temp.format, p->format) == 0)
961 gdb->send_cmd ("server %s display %d",
962 temp.enable ? "enable" : "disable", p->number);
963 else
964 modify (p, temp.format, temp.expr, temp.enable, false);
965 }
966}
967
968
969void display_window::dereference (display *p, bool add)
970{
971 astring expr;
972 expr = "*(";
973 expr.append (p->expr);
974 expr.append (")");
975 modify (p, "", expr, true, add);
976}
Note: See TracBrowser for help on using the repository browser.