]> Git Repo - binutils.git/blame - gdb/gdbtk.c
* mpw-make.in (init.c): Use open-brace instead of mpw-open-brace.
[binutils.git] / gdb / gdbtk.c
CommitLineData
754e5da2
SG
1/* TK interface routines.
2 Copyright 1994 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program 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 of the License, or
9(at your option) any later version.
10
11This program 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 this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "defs.h"
21#include "symtab.h"
22#include "inferior.h"
23#include "command.h"
24#include "bfd.h"
25#include "symfile.h"
26#include "objfiles.h"
27#include "target.h"
754e5da2
SG
28#include <tcl.h>
29#include <tk.h>
cd2df226
SG
30#include <varargs.h>
31#include <signal.h>
32#include <fcntl.h>
8532893d 33#include <unistd.h>
86db943c
SG
34#include <setjmp.h>
35#include "top.h"
736a82e7
SG
36#include <sys/ioctl.h>
37#include <string.h>
38
39#ifndef FIOASYNC
546b8ca7
SG
40#include <sys/stropts.h>
41#endif
754e5da2
SG
42
43/* Non-zero means that we're doing the gdbtk interface. */
44int gdbtk = 0;
45
46/* Non-zero means we are reloading breakpoints, etc from the
47 Gdbtk kernel, and we should suppress various messages */
48static int gdbtk_reloading = 0;
49
50/* Handle for TCL interpreter */
51static Tcl_Interp *interp = NULL;
52
53/* Handle for TK main window */
54static Tk_Window mainWindow = NULL;
55
479f0f18
SG
56static int x_fd; /* X network socket */
57
754e5da2
SG
58static void
59null_routine(arg)
60 int arg;
61{
62}
63
546b8ca7
SG
64/* The following routines deal with stdout/stderr data, which is created by
65 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
66 lowest level of these routines and capture all output from the rest of GDB.
67 Normally they present their data to tcl via callbacks to the following tcl
68 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
69 in turn call tk routines to update the display.
86db943c 70
546b8ca7
SG
71 Under some circumstances, you may want to collect the output so that it can
72 be returned as the value of a tcl procedure. This can be done by
73 surrounding the output routines with calls to start_saving_output and
74 finish_saving_output. The saved data can then be retrieved with
75 get_saved_output (but this must be done before the call to
76 finish_saving_output). */
86db943c 77
546b8ca7 78/* Dynamic string header for stdout. */
86db943c 79
546b8ca7 80static Tcl_DString stdout_buffer;
86db943c 81
546b8ca7
SG
82/* Use this to collect stdout output that will be returned as the result of a
83 tcl command. */
86db943c 84
546b8ca7 85static int saving_output = 0;
86db943c 86
546b8ca7
SG
87static void
88start_saving_output ()
89{
90 saving_output = 1;
86db943c
SG
91}
92
546b8ca7 93#define get_saved_output() (Tcl_DStringValue (&stdout_buffer))
86db943c
SG
94
95static void
96finish_saving_output ()
97{
546b8ca7 98 saving_output = 0;
86db943c 99
546b8ca7 100 Tcl_DStringFree (&stdout_buffer);
86db943c 101}
754e5da2
SG
102\f
103/* This routine redirects the output of fputs_unfiltered so that
104 the user can see what's going on in his debugger window. */
105
106static void
8532893d 107flush_holdbuf ()
754e5da2 108{
546b8ca7
SG
109 char *s, *argv[1];
110
111 /* We use Tcl_Merge to quote braces and funny characters as necessary. */
112
113 argv[0] = Tcl_DStringValue (&stdout_buffer);
114 s = Tcl_Merge (1, argv);
8532893d 115
546b8ca7
SG
116 Tcl_DStringFree (&stdout_buffer);
117
118 Tcl_VarEval (interp, "gdbtk_tcl_fputs ", s, NULL);
119
120 free (s);
754e5da2
SG
121}
122
123static void
124gdbtk_flush (stream)
125 FILE *stream;
126{
546b8ca7 127 if (stream != gdb_stdout || saving_output)
86db943c
SG
128 return;
129
130 /* Flush output from C to tcl land. */
131
8532893d
SG
132 flush_holdbuf ();
133
86db943c
SG
134 /* Force immediate screen update */
135
754e5da2
SG
136 Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
137}
138
8532893d 139static void
86db943c 140gdbtk_fputs (ptr, stream)
8532893d 141 const char *ptr;
86db943c 142 FILE *stream;
8532893d
SG
143{
144 int len;
145
86db943c
SG
146 if (stream != gdb_stdout)
147 {
148 Tcl_VarEval (interp, "gdbtk_tcl_fputs_error ", "{", ptr, "}", NULL);
149 return;
150 }
151
546b8ca7 152 Tcl_DStringAppend (&stdout_buffer, ptr, -1);
8532893d 153
546b8ca7
SG
154 if (saving_output)
155 return;
8532893d 156
546b8ca7
SG
157 if (Tcl_DStringLength (&stdout_buffer) > 1000)
158 flush_holdbuf ();
8532893d
SG
159}
160
754e5da2
SG
161static int
162gdbtk_query (args)
163 va_list args;
164{
165 char *query;
166 char buf[200];
167 long val;
168
169 query = va_arg (args, char *);
170
171 vsprintf(buf, query, args);
172 Tcl_VarEval (interp, "gdbtk_tcl_query ", "{", buf, "}", NULL);
173
174 val = atol (interp->result);
175 return val;
176}
177\f
754e5da2
SG
178static void
179breakpoint_notify(b, action)
180 struct breakpoint *b;
181 const char *action;
182{
183 struct symbol *sym;
8532893d 184 char bpnum[50], line[50], pc[50];
754e5da2
SG
185 struct symtab_and_line sal;
186 char *filename;
187 int v;
188
189 if (b->type != bp_breakpoint)
190 return;
191
192 sal = find_pc_line (b->address, 0);
193
637b1661 194 filename = symtab_to_filename (sal.symtab);
754e5da2
SG
195
196 sprintf (bpnum, "%d", b->number);
197 sprintf (line, "%d", sal.line);
546b8ca7 198 sprintf (pc, "0x%lx", b->address);
754e5da2
SG
199
200 v = Tcl_VarEval (interp,
201 "gdbtk_tcl_breakpoint ",
202 action,
203 " ", bpnum,
204 " ", filename,
205 " ", line,
8532893d 206 " ", pc,
754e5da2
SG
207 NULL);
208
209 if (v != TCL_OK)
210 {
546b8ca7
SG
211 gdbtk_fputs (interp->result, gdb_stdout);
212 gdbtk_fputs ("\n", gdb_stdout);
754e5da2 213 }
754e5da2
SG
214}
215
216static void
217gdbtk_create_breakpoint(b)
218 struct breakpoint *b;
219{
220 breakpoint_notify(b, "create");
221}
222
223static void
224gdbtk_delete_breakpoint(b)
225 struct breakpoint *b;
226{
227 breakpoint_notify(b, "delete");
228}
229
230static void
231gdbtk_enable_breakpoint(b)
232 struct breakpoint *b;
233{
234 breakpoint_notify(b, "enable");
235}
236
237static void
238gdbtk_disable_breakpoint(b)
239 struct breakpoint *b;
240{
241 breakpoint_notify(b, "disable");
242}
243\f
244/* This implements the TCL command `gdb_loc', which returns a list consisting
245 of the source and line number associated with the current pc. */
246
247static int
248gdb_loc (clientData, interp, argc, argv)
249 ClientData clientData;
250 Tcl_Interp *interp;
251 int argc;
252 char *argv[];
253{
254 char *filename;
255 char buf[100];
256 struct symtab_and_line sal;
257 char *funcname;
8532893d 258 CORE_ADDR pc;
754e5da2
SG
259
260 if (argc == 1)
261 {
1dfc8dfb 262 pc = selected_frame ? selected_frame->pc : stop_pc;
754e5da2
SG
263 sal = find_pc_line (pc, 0);
264 }
265 else if (argc == 2)
266 {
754e5da2 267 struct symtabs_and_lines sals;
8532893d 268 int nelts;
754e5da2
SG
269
270 sals = decode_line_spec (argv[1], 1);
271
8532893d
SG
272 nelts = sals.nelts;
273 sal = sals.sals[0];
274 free (sals.sals);
275
754e5da2
SG
276 if (sals.nelts != 1)
277 {
278 Tcl_SetResult (interp, "Ambiguous line spec", TCL_STATIC);
754e5da2
SG
279 return TCL_ERROR;
280 }
281
8532893d 282 pc = sal.pc;
754e5da2
SG
283 }
284 else
285 {
286 Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
287 return TCL_ERROR;
288 }
289
754e5da2
SG
290 if (sal.symtab)
291 Tcl_AppendElement (interp, sal.symtab->filename);
292 else
293 Tcl_AppendElement (interp, "");
8532893d
SG
294
295 find_pc_partial_function (pc, &funcname, NULL, NULL);
754e5da2 296 Tcl_AppendElement (interp, funcname);
8532893d 297
637b1661 298 filename = symtab_to_filename (sal.symtab);
754e5da2 299 Tcl_AppendElement (interp, filename);
8532893d
SG
300
301 sprintf (buf, "%d", sal.line);
754e5da2
SG
302 Tcl_AppendElement (interp, buf); /* line number */
303
546b8ca7 304 sprintf (buf, "0x%lx", pc);
8532893d
SG
305 Tcl_AppendElement (interp, buf); /* PC */
306
754e5da2
SG
307 return TCL_OK;
308}
309\f
5b21fb68
SG
310/* This implements the TCL command `gdb_sourcelines', which returns a list of
311 all of the lines containing executable code for the specified source file
312 (ie: lines where you can put breakpoints). */
313
314static int
315gdb_sourcelines (clientData, interp, argc, argv)
316 ClientData clientData;
317 Tcl_Interp *interp;
318 int argc;
319 char *argv[];
320{
321 struct symtab *symtab;
322 struct linetable_entry *le;
323 int nlines;
324 char buf[100];
325
326 if (argc != 2)
327 {
328 Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
329 return TCL_ERROR;
330 }
331
332 symtab = lookup_symtab (argv[1]);
333
334 if (!symtab)
335 {
336 Tcl_SetResult (interp, "No such file", TCL_STATIC);
337 return TCL_ERROR;
338 }
339
340 /* If there's no linetable, or no entries, then we are done. */
341
342 if (!symtab->linetable
343 || symtab->linetable->nitems == 0)
344 {
345 Tcl_AppendElement (interp, "");
346 return TCL_OK;
347 }
348
349 le = symtab->linetable->item;
350 nlines = symtab->linetable->nitems;
351
352 for (;nlines > 0; nlines--, le++)
353 {
354 /* If the pc of this line is the same as the pc of the next line, then
355 just skip it. */
356 if (nlines > 1
357 && le->pc == (le + 1)->pc)
358 continue;
359
360 sprintf (buf, "%d", le->line);
361 Tcl_AppendElement (interp, buf);
362 }
363
364 return TCL_OK;
365}
366\f
746d1df4
SG
367static int
368map_arg_registers (argc, argv, func, argp)
369 int argc;
370 char *argv[];
371 int (*func) PARAMS ((int regnum, void *argp));
372 void *argp;
373{
374 int regnum;
375
376 /* Note that the test for a valid register must include checking the
377 reg_names array because NUM_REGS may be allocated for the union of the
378 register sets within a family of related processors. In this case, the
379 trailing entries of reg_names will change depending upon the particular
380 processor being debugged. */
381
382 if (argc == 0) /* No args, just do all the regs */
383 {
384 for (regnum = 0;
385 regnum < NUM_REGS
386 && reg_names[regnum] != NULL
387 && *reg_names[regnum] != '\000';
388 regnum++)
389 func (regnum, argp);
390
391 return TCL_OK;
392 }
393
394 /* Else, list of register #s, just do listed regs */
395 for (; argc > 0; argc--, argv++)
396 {
397 regnum = atoi (*argv);
398
399 if (regnum >= 0
400 && regnum < NUM_REGS
401 && reg_names[regnum] != NULL
402 && *reg_names[regnum] != '\000')
403 func (regnum, argp);
404 else
405 {
406 Tcl_SetResult (interp, "bad register number", TCL_STATIC);
407
408 return TCL_ERROR;
409 }
410 }
411
412 return TCL_OK;
413}
414
415static int
416get_register_name (regnum, argp)
417 int regnum;
418 void *argp; /* Ignored */
419{
420 Tcl_AppendElement (interp, reg_names[regnum]);
421}
422
5b21fb68
SG
423/* This implements the TCL command `gdb_regnames', which returns a list of
424 all of the register names. */
425
426static int
427gdb_regnames (clientData, interp, argc, argv)
428 ClientData clientData;
429 Tcl_Interp *interp;
430 int argc;
431 char *argv[];
432{
746d1df4
SG
433 argc--;
434 argv++;
435
436 return map_arg_registers (argc, argv, get_register_name, 0);
437}
438
746d1df4
SG
439#ifndef REGISTER_CONVERTIBLE
440#define REGISTER_CONVERTIBLE(x) (0 != 0)
441#endif
442
443#ifndef REGISTER_CONVERT_TO_VIRTUAL
444#define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
445#endif
446
447#ifndef INVALID_FLOAT
448#define INVALID_FLOAT(x, y) (0 != 0)
449#endif
450
451static int
452get_register (regnum, fp)
453 void *fp;
454{
455 char raw_buffer[MAX_REGISTER_RAW_SIZE];
456 char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
457 int format = (int)fp;
458
459 if (read_relative_register_raw_bytes (regnum, raw_buffer))
460 {
461 Tcl_AppendElement (interp, "Optimized out");
462 return;
463 }
464
86db943c 465 start_saving_output (); /* Start collecting stdout */
746d1df4
SG
466
467 /* Convert raw data to virtual format if necessary. */
468
469 if (REGISTER_CONVERTIBLE (regnum))
470 {
471 REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
472 raw_buffer, virtual_buffer);
473 }
474 else
475 memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
476
477 val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0,
478 gdb_stdout, format, 1, 0, Val_pretty_default);
479
86db943c 480 Tcl_AppendElement (interp, get_saved_output ());
746d1df4 481
86db943c 482 finish_saving_output (); /* Set stdout back to normal */
746d1df4
SG
483}
484
485static int
486gdb_fetch_registers (clientData, interp, argc, argv)
487 ClientData clientData;
488 Tcl_Interp *interp;
489 int argc;
490 char *argv[];
491{
492 int format;
493
494 if (argc < 2)
5b21fb68
SG
495 {
496 Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
497 return TCL_ERROR;
498 }
499
746d1df4
SG
500 argc--;
501 argv++;
5b21fb68 502
746d1df4
SG
503 argc--;
504 format = **argv++;
505
506 return map_arg_registers (argc, argv, get_register, format);
507}
508
509/* This contains the previous values of the registers, since the last call to
510 gdb_changed_register_list. */
511
512static char old_regs[REGISTER_BYTES];
513
514static int
515register_changed_p (regnum, argp)
516 void *argp; /* Ignored */
517{
518 char raw_buffer[MAX_REGISTER_RAW_SIZE];
519 char buf[100];
520
521 if (read_relative_register_raw_bytes (regnum, raw_buffer))
522 return;
523
524 if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
525 REGISTER_RAW_SIZE (regnum)) == 0)
526 return;
527
528 /* Found a changed register. Save new value and return it's number. */
529
530 memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
531 REGISTER_RAW_SIZE (regnum));
532
533 sprintf (buf, "%d", regnum);
534 Tcl_AppendElement (interp, buf);
535}
536
537static int
538gdb_changed_register_list (clientData, interp, argc, argv)
539 ClientData clientData;
540 Tcl_Interp *interp;
541 int argc;
542 char *argv[];
543{
544 int format;
545
546 argc--;
547 argv++;
548
549 return map_arg_registers (argc, argv, register_changed_p, NULL);
5b21fb68
SG
550}
551\f
754e5da2
SG
552/* This implements the TCL command `gdb_cmd', which sends it's argument into
553 the GDB command scanner. */
554
555static int
556gdb_cmd (clientData, interp, argc, argv)
557 ClientData clientData;
558 Tcl_Interp *interp;
559 int argc;
560 char *argv[];
561{
754e5da2
SG
562 if (argc != 2)
563 {
564 Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
565 return TCL_ERROR;
566 }
567
86db943c 568 execute_command (argv[1], 1);
479f0f18 569
754e5da2 570 bpstat_do_actions (&stop_bpstat);
754e5da2 571
8532893d
SG
572 /* Drain all buffered command output */
573
8532893d
SG
574 gdb_flush (gdb_stdout);
575
754e5da2
SG
576 return TCL_OK;
577}
578
86db943c
SG
579/* This routine acts as a top-level for all GDB code called by tcl/Tk. It
580 handles cleanups, and calls to return_to_top_level (usually via error).
581 This is necessary in order to prevent a longjmp out of the bowels of Tk,
582 possibly leaving things in a bad state. Since this routine can be called
583 recursively, it needs to save and restore the contents of the jmp_buf as
584 necessary. */
585
586static int
587call_wrapper (clientData, interp, argc, argv)
588 ClientData clientData;
589 Tcl_Interp *interp;
590 int argc;
591 char *argv[];
592{
593 int val;
594 struct cleanup *saved_cleanup_chain;
595 Tcl_CmdProc *func;
596 jmp_buf saved_error_return;
597
598 func = (Tcl_CmdProc *)clientData;
599 memcpy (saved_error_return, error_return, sizeof (jmp_buf));
600
601 saved_cleanup_chain = save_cleanups ();
602
603 if (!setjmp (error_return))
604 val = func (clientData, interp, argc, argv);
605 else
606 {
607 val = TCL_ERROR; /* Flag an error for TCL */
608
609 finish_saving_output (); /* Restore stdout to normal */
610
611 gdb_flush (gdb_stderr); /* Flush error output */
612
613/* In case of an error, we may need to force the GUI into idle mode because
614 gdbtk_call_command may have bombed out while in the command routine. */
615
616 Tcl_VarEval (interp, "gdbtk_tcl_idle", NULL);
617 }
618
619 do_cleanups (ALL_CLEANUPS);
620
621 restore_cleanups (saved_cleanup_chain);
622
623 memcpy (error_return, saved_error_return, sizeof (jmp_buf));
624
625 return val;
626}
627
754e5da2
SG
628static int
629gdb_listfiles (clientData, interp, argc, argv)
630 ClientData clientData;
631 Tcl_Interp *interp;
632 int argc;
633 char *argv[];
634{
635 int val;
636 struct objfile *objfile;
637 struct partial_symtab *psymtab;
546b8ca7 638 struct symtab *symtab;
754e5da2
SG
639
640 ALL_PSYMTABS (objfile, psymtab)
641 Tcl_AppendElement (interp, psymtab->filename);
642
546b8ca7
SG
643 ALL_SYMTABS (objfile, symtab)
644 Tcl_AppendElement (interp, symtab->filename);
645
754e5da2
SG
646 return TCL_OK;
647}
479f0f18
SG
648
649static int
650gdb_stop (clientData, interp, argc, argv)
651 ClientData clientData;
652 Tcl_Interp *interp;
653 int argc;
654 char *argv[];
655{
6c27841f 656 target_stop ();
546b8ca7
SG
657
658 return TCL_OK;
479f0f18
SG
659}
660
754e5da2
SG
661\f
662static void
663tk_command (cmd, from_tty)
664 char *cmd;
665 int from_tty;
666{
546b8ca7
SG
667 int retval;
668 char *result;
669 struct cleanup *old_chain;
670
671 retval = Tcl_Eval (interp, cmd);
672
673 result = strdup (interp->result);
754e5da2 674
546b8ca7
SG
675 old_chain = make_cleanup (free, result);
676
677 if (retval != TCL_OK)
678 error (result);
679
680 printf_unfiltered ("%s\n", result);
681
682 do_cleanups (old_chain);
754e5da2
SG
683}
684
685static void
686cleanup_init (ignored)
687 int ignored;
688{
689 if (mainWindow != NULL)
690 Tk_DestroyWindow (mainWindow);
691 mainWindow = NULL;
692
693 if (interp != NULL)
694 Tcl_DeleteInterp (interp);
695 interp = NULL;
696}
697
637b1661
SG
698/* Come here during long calculations to check for GUI events. Usually invoked
699 via the QUIT macro. */
700
701static void
702gdbtk_interactive ()
703{
704 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
705}
706
479f0f18
SG
707/* Come here when there is activity on the X file descriptor. */
708
709static void
710x_event (signo)
711 int signo;
712{
713 /* Process pending events */
714
715 while (Tk_DoOneEvent (TK_DONT_WAIT|TK_ALL_EVENTS) != 0);
716}
717
718static int
719gdbtk_wait (pid, ourstatus)
720 int pid;
721 struct target_waitstatus *ourstatus;
722{
736a82e7
SG
723 struct sigaction action;
724 static sigset_t nullsigmask = {0};
725
726#ifndef SA_RESTART
727 /* Needed for SunOS 4.1.x */
728#define SA_RESTART 0
546b8ca7 729#endif
479f0f18 730
736a82e7
SG
731 action.sa_handler = x_event;
732 action.sa_mask = nullsigmask;
733 action.sa_flags = SA_RESTART;
734 sigaction(SIGIO, &action, NULL);
735
479f0f18
SG
736 pid = target_wait (pid, ourstatus);
737
736a82e7
SG
738 action.sa_handler = SIG_IGN;
739 sigaction(SIGIO, &action, NULL);
479f0f18
SG
740
741 return pid;
742}
743
744/* This is called from execute_command, and provides a wrapper around
745 various command routines in a place where both protocol messages and
746 user input both flow through. Mostly this is used for indicating whether
747 the target process is running or not.
748*/
749
750static void
751gdbtk_call_command (cmdblk, arg, from_tty)
752 struct cmd_list_element *cmdblk;
753 char *arg;
754 int from_tty;
755{
756 if (cmdblk->class == class_run)
757 {
758 Tcl_VarEval (interp, "gdbtk_tcl_busy", NULL);
759 (*cmdblk->function.cfunc)(arg, from_tty);
760 Tcl_VarEval (interp, "gdbtk_tcl_idle", NULL);
761 }
762 else
763 (*cmdblk->function.cfunc)(arg, from_tty);
764}
765
754e5da2
SG
766static void
767gdbtk_init ()
768{
769 struct cleanup *old_chain;
770 char *gdbtk_filename;
479f0f18 771 int i;
736a82e7
SG
772 struct sigaction action;
773 static sigset_t nullsigmask = {0};
754e5da2
SG
774
775 old_chain = make_cleanup (cleanup_init, 0);
776
777 /* First init tcl and tk. */
778
779 interp = Tcl_CreateInterp ();
780
781 if (!interp)
782 error ("Tcl_CreateInterp failed");
783
546b8ca7
SG
784 Tcl_DStringInit (&stdout_buffer); /* Setup stdout buffer */
785
754e5da2
SG
786 mainWindow = Tk_CreateMainWindow (interp, NULL, "gdb", "Gdb");
787
788 if (!mainWindow)
789 return; /* DISPLAY probably not set */
790
791 if (Tcl_Init(interp) != TCL_OK)
792 error ("Tcl_Init failed: %s", interp->result);
793
794 if (Tk_Init(interp) != TCL_OK)
795 error ("Tk_Init failed: %s", interp->result);
796
86db943c
SG
797 Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
798 Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
799 Tcl_CreateCommand (interp, "gdb_sourcelines", call_wrapper, gdb_sourcelines,
800 NULL);
801 Tcl_CreateCommand (interp, "gdb_listfiles", call_wrapper, gdb_listfiles,
746d1df4 802 NULL);
86db943c
SG
803 Tcl_CreateCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
804 Tcl_CreateCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
805 Tcl_CreateCommand (interp, "gdb_fetch_registers", call_wrapper,
806 gdb_fetch_registers, NULL);
807 Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper,
808 gdb_changed_register_list, NULL);
754e5da2
SG
809
810 gdbtk_filename = getenv ("GDBTK_FILENAME");
8532893d
SG
811 if (!gdbtk_filename)
812 if (access ("gdbtk.tcl", R_OK) == 0)
813 gdbtk_filename = "gdbtk.tcl";
814 else
815 gdbtk_filename = GDBTK_FILENAME;
816
817 if (Tcl_EvalFile (interp, gdbtk_filename) != TCL_OK)
818 error ("Failure reading %s: %s", gdbtk_filename, interp->result);
754e5da2 819
cd2df226 820 /* Get the file descriptor for the X server */
479f0f18 821
cd2df226 822 x_fd = ConnectionNumber (Tk_Display (mainWindow));
479f0f18
SG
823
824 /* Setup for I/O interrupts */
825
736a82e7
SG
826 action.sa_mask = nullsigmask;
827 action.sa_flags = 0;
828 action.sa_handler = SIG_IGN;
829 sigaction(SIGIO, &action, NULL);
830
831#ifdef FIOASYNC
832 i = 1;
833 if (ioctl (x_fd, FIOASYNC, &i))
834 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
479f0f18 835
736a82e7
SG
836 i = getpid();
837 if (ioctl (x_fd, SIOCSPGRP, &i))
838 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
546b8ca7
SG
839#else
840 if (ioctl (x_fd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
736a82e7
SG
841 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
842#endif /* ifndef FIOASYNC */
479f0f18 843
754e5da2
SG
844 command_loop_hook = Tk_MainLoop;
845 fputs_unfiltered_hook = gdbtk_fputs;
846 print_frame_info_listing_hook = null_routine;
847 query_hook = gdbtk_query;
848 flush_hook = gdbtk_flush;
849 create_breakpoint_hook = gdbtk_create_breakpoint;
850 delete_breakpoint_hook = gdbtk_delete_breakpoint;
851 enable_breakpoint_hook = gdbtk_enable_breakpoint;
852 disable_breakpoint_hook = gdbtk_disable_breakpoint;
637b1661 853 interactive_hook = gdbtk_interactive;
479f0f18
SG
854 target_wait_hook = gdbtk_wait;
855 call_command_hook = gdbtk_call_command;
754e5da2
SG
856
857 discard_cleanups (old_chain);
858
859 add_com ("tk", class_obscure, tk_command,
860 "Send a command directly into tk.");
861}
862
863/* Come here during initialze_all_files () */
864
865void
866_initialize_gdbtk ()
867{
c5197511
SG
868 if (use_windows)
869 {
870 /* Tell the rest of the world that Gdbtk is now set up. */
754e5da2 871
c5197511
SG
872 init_ui_hook = gdbtk_init;
873 }
754e5da2 874}
This page took 0.203838 seconds and 4 git commands to generate.