198944Sobrien/* User Interface Events.
298944Sobrien
3130803Smarcel   Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
4130803Smarcel
598944Sobrien   Contributed by Cygnus Solutions.
698944Sobrien
798944Sobrien   This file is part of GDB.
898944Sobrien
998944Sobrien   This program is free software; you can redistribute it and/or modify
1098944Sobrien   it under the terms of the GNU General Public License as published by
1198944Sobrien   the Free Software Foundation; either version 2 of the License, or
1298944Sobrien   (at your option) any later version.
1398944Sobrien
1498944Sobrien   This program is distributed in the hope that it will be useful,
1598944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1698944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1798944Sobrien   GNU General Public License for more details.
1898944Sobrien
1998944Sobrien   You should have received a copy of the GNU General Public License
2098944Sobrien   along with this program; if not, write to the Free Software
2198944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2298944Sobrien
2398944Sobrien/* Work in progress */
2498944Sobrien
2598944Sobrien/* This file was created with the aid of ``gdb-events.sh''.
2698944Sobrien
2798944Sobrien   The bourn shell script ``gdb-events.sh'' creates the files
2898944Sobrien   ``new-gdb-events.c'' and ``new-gdb-events.h and then compares
2998944Sobrien   them against the existing ``gdb-events.[hc]''.  Any differences
3098944Sobrien   found being reported.
3198944Sobrien
3298944Sobrien   If editing this file, please also run gdb-events.sh and merge any
3398944Sobrien   changes into that script. Conversely, when making sweeping changes
3498944Sobrien   to this file, modifying gdb-events.sh and using its output may
3598944Sobrien   prove easier. */
3698944Sobrien
3798944Sobrien
3898944Sobrien#include "defs.h"
3998944Sobrien#include "gdb-events.h"
4098944Sobrien#include "gdbcmd.h"
4198944Sobrien
4298944Sobrien#if WITH_GDB_EVENTS
4398944Sobrienstatic struct gdb_events null_event_hooks;
4498944Sobrienstatic struct gdb_events queue_event_hooks;
4598944Sobrienstatic struct gdb_events *current_event_hooks = &null_event_hooks;
4698944Sobrien#endif
4798944Sobrien
4898944Sobrienint gdb_events_debug;
4998944Sobrien
5098944Sobrien#if WITH_GDB_EVENTS
5198944Sobrien
5298944Sobrienvoid
5398944Sobrienbreakpoint_create_event (int b)
5498944Sobrien{
5598944Sobrien  if (gdb_events_debug)
5698944Sobrien    fprintf_unfiltered (gdb_stdlog, "breakpoint_create_event\n");
5798944Sobrien  if (!current_event_hooks->breakpoint_create)
5898944Sobrien    return;
5998944Sobrien  current_event_hooks->breakpoint_create (b);
6098944Sobrien}
6198944Sobrien
6298944Sobrienvoid
6398944Sobrienbreakpoint_delete_event (int b)
6498944Sobrien{
6598944Sobrien  if (gdb_events_debug)
6698944Sobrien    fprintf_unfiltered (gdb_stdlog, "breakpoint_delete_event\n");
6798944Sobrien  if (!current_event_hooks->breakpoint_delete)
6898944Sobrien    return;
6998944Sobrien  current_event_hooks->breakpoint_delete (b);
7098944Sobrien}
7198944Sobrien
7298944Sobrienvoid
7398944Sobrienbreakpoint_modify_event (int b)
7498944Sobrien{
7598944Sobrien  if (gdb_events_debug)
7698944Sobrien    fprintf_unfiltered (gdb_stdlog, "breakpoint_modify_event\n");
7798944Sobrien  if (!current_event_hooks->breakpoint_modify)
7898944Sobrien    return;
7998944Sobrien  current_event_hooks->breakpoint_modify (b);
8098944Sobrien}
8198944Sobrien
8298944Sobrienvoid
8398944Sobrientracepoint_create_event (int number)
8498944Sobrien{
8598944Sobrien  if (gdb_events_debug)
8698944Sobrien    fprintf_unfiltered (gdb_stdlog, "tracepoint_create_event\n");
8798944Sobrien  if (!current_event_hooks->tracepoint_create)
8898944Sobrien    return;
8998944Sobrien  current_event_hooks->tracepoint_create (number);
9098944Sobrien}
9198944Sobrien
9298944Sobrienvoid
9398944Sobrientracepoint_delete_event (int number)
9498944Sobrien{
9598944Sobrien  if (gdb_events_debug)
9698944Sobrien    fprintf_unfiltered (gdb_stdlog, "tracepoint_delete_event\n");
9798944Sobrien  if (!current_event_hooks->tracepoint_delete)
9898944Sobrien    return;
9998944Sobrien  current_event_hooks->tracepoint_delete (number);
10098944Sobrien}
10198944Sobrien
10298944Sobrienvoid
10398944Sobrientracepoint_modify_event (int number)
10498944Sobrien{
10598944Sobrien  if (gdb_events_debug)
10698944Sobrien    fprintf_unfiltered (gdb_stdlog, "tracepoint_modify_event\n");
10798944Sobrien  if (!current_event_hooks->tracepoint_modify)
10898944Sobrien    return;
10998944Sobrien  current_event_hooks->tracepoint_modify (number);
11098944Sobrien}
11198944Sobrien
11298944Sobrienvoid
11398944Sobrienarchitecture_changed_event (void)
11498944Sobrien{
11598944Sobrien  if (gdb_events_debug)
11698944Sobrien    fprintf_unfiltered (gdb_stdlog, "architecture_changed_event\n");
11798944Sobrien  if (!current_event_hooks->architecture_changed)
11898944Sobrien    return;
11998944Sobrien  current_event_hooks->architecture_changed ();
12098944Sobrien}
12198944Sobrien
122130803Smarcelvoid
123130803Smarceltarget_changed_event (void)
124130803Smarcel{
125130803Smarcel  if (gdb_events_debug)
126130803Smarcel    fprintf_unfiltered (gdb_stdlog, "target_changed_event\n");
127130803Smarcel  if (!current_event_hooks->target_changed)
128130803Smarcel    return;
129130803Smarcel  current_event_hooks->target_changed ();
130130803Smarcel}
131130803Smarcel
132130803Smarcelvoid
133130803Smarcelselected_frame_level_changed_event (int level)
134130803Smarcel{
135130803Smarcel  if (gdb_events_debug)
136130803Smarcel    fprintf_unfiltered (gdb_stdlog, "selected_frame_level_changed_event\n");
137130803Smarcel  if (!current_event_hooks->selected_frame_level_changed)
138130803Smarcel    return;
139130803Smarcel  current_event_hooks->selected_frame_level_changed (level);
140130803Smarcel}
141130803Smarcel
142130803Smarcelvoid
143130803Smarcelselected_thread_changed_event (int thread_num)
144130803Smarcel{
145130803Smarcel  if (gdb_events_debug)
146130803Smarcel    fprintf_unfiltered (gdb_stdlog, "selected_thread_changed_event\n");
147130803Smarcel  if (!current_event_hooks->selected_thread_changed)
148130803Smarcel    return;
149130803Smarcel  current_event_hooks->selected_thread_changed (thread_num);
150130803Smarcel}
151130803Smarcel
15298944Sobrien#endif
15398944Sobrien
15498944Sobrien#if WITH_GDB_EVENTS
15598944Sobrienstruct gdb_events *
15698944Sobrienset_gdb_event_hooks (struct gdb_events *vector)
15798944Sobrien{
15898944Sobrien  struct gdb_events *old_events = current_event_hooks;
15998944Sobrien  if (vector == NULL)
16098944Sobrien    current_event_hooks = &queue_event_hooks;
16198944Sobrien  else
16298944Sobrien    current_event_hooks = vector;
16398944Sobrien  return old_events;
16498944Sobrien}
16598944Sobrien#endif
16698944Sobrien
167130803Smarcel#if WITH_GDB_EVENTS
168130803Smarcelvoid
169130803Smarcelclear_gdb_event_hooks (void)
170130803Smarcel{
171130803Smarcel  set_gdb_event_hooks (&null_event_hooks);
172130803Smarcel}
173130803Smarcel#endif
174130803Smarcel
17598944Sobrienenum gdb_event
17698944Sobrien{
17798944Sobrien  breakpoint_create,
17898944Sobrien  breakpoint_delete,
17998944Sobrien  breakpoint_modify,
18098944Sobrien  tracepoint_create,
18198944Sobrien  tracepoint_delete,
18298944Sobrien  tracepoint_modify,
18398944Sobrien  architecture_changed,
184130803Smarcel  target_changed,
185130803Smarcel  selected_frame_level_changed,
186130803Smarcel  selected_thread_changed,
18798944Sobrien  nr_gdb_events
18898944Sobrien};
18998944Sobrien
19098944Sobrienstruct breakpoint_create
19198944Sobrien  {
19298944Sobrien    int b;
19398944Sobrien  };
19498944Sobrien
19598944Sobrienstruct breakpoint_delete
19698944Sobrien  {
19798944Sobrien    int b;
19898944Sobrien  };
19998944Sobrien
20098944Sobrienstruct breakpoint_modify
20198944Sobrien  {
20298944Sobrien    int b;
20398944Sobrien  };
20498944Sobrien
20598944Sobrienstruct tracepoint_create
20698944Sobrien  {
20798944Sobrien    int number;
20898944Sobrien  };
20998944Sobrien
21098944Sobrienstruct tracepoint_delete
21198944Sobrien  {
21298944Sobrien    int number;
21398944Sobrien  };
21498944Sobrien
21598944Sobrienstruct tracepoint_modify
21698944Sobrien  {
21798944Sobrien    int number;
21898944Sobrien  };
21998944Sobrien
220130803Smarcelstruct selected_frame_level_changed
221130803Smarcel  {
222130803Smarcel    int level;
223130803Smarcel  };
224130803Smarcel
225130803Smarcelstruct selected_thread_changed
226130803Smarcel  {
227130803Smarcel    int thread_num;
228130803Smarcel  };
229130803Smarcel
23098944Sobrienstruct event
23198944Sobrien  {
23298944Sobrien    enum gdb_event type;
23398944Sobrien    struct event *next;
23498944Sobrien    union
23598944Sobrien      {
23698944Sobrien	struct breakpoint_create breakpoint_create;
23798944Sobrien	struct breakpoint_delete breakpoint_delete;
23898944Sobrien	struct breakpoint_modify breakpoint_modify;
23998944Sobrien	struct tracepoint_create tracepoint_create;
24098944Sobrien	struct tracepoint_delete tracepoint_delete;
24198944Sobrien	struct tracepoint_modify tracepoint_modify;
242130803Smarcel	struct selected_frame_level_changed selected_frame_level_changed;
243130803Smarcel	struct selected_thread_changed selected_thread_changed;
24498944Sobrien      }
24598944Sobrien    data;
24698944Sobrien  };
24798944Sobrienstruct event *pending_events;
24898944Sobrienstruct event *delivering_events;
24998944Sobrien
25098944Sobrienstatic void
25198944Sobrienappend (struct event *new_event)
25298944Sobrien{
25398944Sobrien  struct event **event = &pending_events;
25498944Sobrien  while ((*event) != NULL)
25598944Sobrien    event = &((*event)->next);
25698944Sobrien  (*event) = new_event;
25798944Sobrien  (*event)->next = NULL;
25898944Sobrien}
25998944Sobrien
26098944Sobrienstatic void
26198944Sobrienqueue_breakpoint_create (int b)
26298944Sobrien{
26398944Sobrien  struct event *event = XMALLOC (struct event);
26498944Sobrien  event->type = breakpoint_create;
26598944Sobrien  event->data.breakpoint_create.b = b;
26698944Sobrien  append (event);
26798944Sobrien}
26898944Sobrien
26998944Sobrienstatic void
27098944Sobrienqueue_breakpoint_delete (int b)
27198944Sobrien{
27298944Sobrien  struct event *event = XMALLOC (struct event);
27398944Sobrien  event->type = breakpoint_delete;
27498944Sobrien  event->data.breakpoint_delete.b = b;
27598944Sobrien  append (event);
27698944Sobrien}
27798944Sobrien
27898944Sobrienstatic void
27998944Sobrienqueue_breakpoint_modify (int b)
28098944Sobrien{
28198944Sobrien  struct event *event = XMALLOC (struct event);
28298944Sobrien  event->type = breakpoint_modify;
28398944Sobrien  event->data.breakpoint_modify.b = b;
28498944Sobrien  append (event);
28598944Sobrien}
28698944Sobrien
28798944Sobrienstatic void
28898944Sobrienqueue_tracepoint_create (int number)
28998944Sobrien{
29098944Sobrien  struct event *event = XMALLOC (struct event);
29198944Sobrien  event->type = tracepoint_create;
29298944Sobrien  event->data.tracepoint_create.number = number;
29398944Sobrien  append (event);
29498944Sobrien}
29598944Sobrien
29698944Sobrienstatic void
29798944Sobrienqueue_tracepoint_delete (int number)
29898944Sobrien{
29998944Sobrien  struct event *event = XMALLOC (struct event);
30098944Sobrien  event->type = tracepoint_delete;
30198944Sobrien  event->data.tracepoint_delete.number = number;
30298944Sobrien  append (event);
30398944Sobrien}
30498944Sobrien
30598944Sobrienstatic void
30698944Sobrienqueue_tracepoint_modify (int number)
30798944Sobrien{
30898944Sobrien  struct event *event = XMALLOC (struct event);
30998944Sobrien  event->type = tracepoint_modify;
31098944Sobrien  event->data.tracepoint_modify.number = number;
31198944Sobrien  append (event);
31298944Sobrien}
31398944Sobrien
31498944Sobrienstatic void
31598944Sobrienqueue_architecture_changed (void)
31698944Sobrien{
31798944Sobrien  struct event *event = XMALLOC (struct event);
31898944Sobrien  event->type = architecture_changed;
31998944Sobrien  append (event);
32098944Sobrien}
32198944Sobrien
322130803Smarcelstatic void
323130803Smarcelqueue_target_changed (void)
324130803Smarcel{
325130803Smarcel  struct event *event = XMALLOC (struct event);
326130803Smarcel  event->type = target_changed;
327130803Smarcel  append (event);
328130803Smarcel}
329130803Smarcel
330130803Smarcelstatic void
331130803Smarcelqueue_selected_frame_level_changed (int level)
332130803Smarcel{
333130803Smarcel  struct event *event = XMALLOC (struct event);
334130803Smarcel  event->type = selected_frame_level_changed;
335130803Smarcel  event->data.selected_frame_level_changed.level = level;
336130803Smarcel  append (event);
337130803Smarcel}
338130803Smarcel
339130803Smarcelstatic void
340130803Smarcelqueue_selected_thread_changed (int thread_num)
341130803Smarcel{
342130803Smarcel  struct event *event = XMALLOC (struct event);
343130803Smarcel  event->type = selected_thread_changed;
344130803Smarcel  event->data.selected_thread_changed.thread_num = thread_num;
345130803Smarcel  append (event);
346130803Smarcel}
347130803Smarcel
34898944Sobrienvoid
34998944Sobriengdb_events_deliver (struct gdb_events *vector)
35098944Sobrien{
35198944Sobrien  /* Just zap any events left around from last time. */
35298944Sobrien  while (delivering_events != NULL)
35398944Sobrien    {
35498944Sobrien      struct event *event = delivering_events;
35598944Sobrien      delivering_events = event->next;
35698944Sobrien      xfree (event);
35798944Sobrien    }
35898944Sobrien  /* Process any pending events.  Because one of the deliveries could
35998944Sobrien     bail out we move everything off of the pending queue onto an
36098944Sobrien     in-progress queue where it can, later, be cleaned up if
36198944Sobrien     necessary. */
36298944Sobrien  delivering_events = pending_events;
36398944Sobrien  pending_events = NULL;
36498944Sobrien  while (delivering_events != NULL)
36598944Sobrien    {
36698944Sobrien      struct event *event = delivering_events;
36798944Sobrien      switch (event->type)
36898944Sobrien	{
36998944Sobrien	case breakpoint_create:
37098944Sobrien	  vector->breakpoint_create
37198944Sobrien	    (event->data.breakpoint_create.b);
37298944Sobrien	  break;
37398944Sobrien	case breakpoint_delete:
37498944Sobrien	  vector->breakpoint_delete
37598944Sobrien	    (event->data.breakpoint_delete.b);
37698944Sobrien	  break;
37798944Sobrien	case breakpoint_modify:
37898944Sobrien	  vector->breakpoint_modify
37998944Sobrien	    (event->data.breakpoint_modify.b);
38098944Sobrien	  break;
38198944Sobrien	case tracepoint_create:
38298944Sobrien	  vector->tracepoint_create
38398944Sobrien	    (event->data.tracepoint_create.number);
38498944Sobrien	  break;
38598944Sobrien	case tracepoint_delete:
38698944Sobrien	  vector->tracepoint_delete
38798944Sobrien	    (event->data.tracepoint_delete.number);
38898944Sobrien	  break;
38998944Sobrien	case tracepoint_modify:
39098944Sobrien	  vector->tracepoint_modify
39198944Sobrien	    (event->data.tracepoint_modify.number);
39298944Sobrien	  break;
39398944Sobrien	case architecture_changed:
39498944Sobrien	  vector->architecture_changed ();
39598944Sobrien	  break;
396130803Smarcel	case target_changed:
397130803Smarcel	  vector->target_changed ();
398130803Smarcel	  break;
399130803Smarcel	case selected_frame_level_changed:
400130803Smarcel	  vector->selected_frame_level_changed
401130803Smarcel	    (event->data.selected_frame_level_changed.level);
402130803Smarcel	  break;
403130803Smarcel	case selected_thread_changed:
404130803Smarcel	  vector->selected_thread_changed
405130803Smarcel	    (event->data.selected_thread_changed.thread_num);
406130803Smarcel	  break;
40798944Sobrien	}
40898944Sobrien      delivering_events = event->next;
40998944Sobrien      xfree (event);
41098944Sobrien    }
41198944Sobrien}
41298944Sobrien
41398944Sobrienvoid _initialize_gdb_events (void);
41498944Sobrienvoid
41598944Sobrien_initialize_gdb_events (void)
41698944Sobrien{
41798944Sobrien  struct cmd_list_element *c;
41898944Sobrien#if WITH_GDB_EVENTS
41998944Sobrien  queue_event_hooks.breakpoint_create = queue_breakpoint_create;
42098944Sobrien  queue_event_hooks.breakpoint_delete = queue_breakpoint_delete;
42198944Sobrien  queue_event_hooks.breakpoint_modify = queue_breakpoint_modify;
42298944Sobrien  queue_event_hooks.tracepoint_create = queue_tracepoint_create;
42398944Sobrien  queue_event_hooks.tracepoint_delete = queue_tracepoint_delete;
42498944Sobrien  queue_event_hooks.tracepoint_modify = queue_tracepoint_modify;
42598944Sobrien  queue_event_hooks.architecture_changed = queue_architecture_changed;
426130803Smarcel  queue_event_hooks.target_changed = queue_target_changed;
427130803Smarcel  queue_event_hooks.selected_frame_level_changed = queue_selected_frame_level_changed;
428130803Smarcel  queue_event_hooks.selected_thread_changed = queue_selected_thread_changed;
42998944Sobrien#endif
43098944Sobrien
43198944Sobrien  c = add_set_cmd ("eventdebug", class_maintenance, var_zinteger,
43298944Sobrien		   (char *) (&gdb_events_debug), "Set event debugging.\n\
43398944SobrienWhen non-zero, event/notify debugging is enabled.", &setlist);
43498944Sobrien  deprecate_cmd (c, "set debug event");
43598944Sobrien  deprecate_cmd (add_show_from_set (c, &showlist), "show debug event");
43698944Sobrien
43798944Sobrien  add_show_from_set (add_set_cmd ("event",
43898944Sobrien				  class_maintenance,
43998944Sobrien				  var_zinteger,
44098944Sobrien				  (char *) (&gdb_events_debug),
44198944Sobrien				  "Set event debugging.\n\
44298944SobrienWhen non-zero, event/notify debugging is enabled.", &setdebuglist),
44398944Sobrien		     &showdebuglist);
44498944Sobrien}
445