ARB
AW_cb_struct.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : AW_cb_struct.cxx //
4 // Purpose : //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // =============================================================== //
10 
11 #include "aw_root.hxx"
12 #include "aw_window.hxx"
13 #include "aw_window_Xm.hxx"
14 #include "aw_msg.hxx"
15 
16 #if defined(DEBUG)
17 // #define TRACE_CALLBACKS
18 #endif // DEBUG
19 
20 AW_cb_struct_guard AW_cb::guard_before = NULp;
21 AW_cb_struct_guard AW_cb::guard_after = NULp;
22 AW_postcb_cb AW_cb::postcb = NULp;
23 
24 
25 AW_cb::AW_cb(AW_window *awi, const WindowCallback& wcb, const char *help_texti, class AW_cb *nexti)
26  : cb(wcb)
27 {
28  aw = awi;
29  help_text = help_texti;
30  this->next = nexti;
31 
32  id = NULp;
33 }
34 
35 
37  return (AnyWinCB(cb.callee()) == g) || (next && next->contains(g));
38 }
39 
40 bool AW_cb::is_equal(const AW_cb& other) const {
41  bool equal = cb == other.cb;
42  if (equal) {
43  equal = aw == other.aw;
44  if (!equal) {
45  equal = aw->get_root() == other.aw->get_root();
46 #if defined(DEBUG) && 0
47  if (equal) {
48  fprintf(stderr,
49  "callback '%s' instantiated twice with different windows (w1='%s' w2='%s') -- assuming the callbacks are equal\n",
50  id, aw->get_window_id(), other.aw->get_window_id());
51  }
52 #endif // DEBUG
53  }
54  }
55  return equal;
56 }
57 
58 
60  if (next) next->run_callbacks(); // callback the whole list
61 
62  AnyWinCB f = AnyWinCB(cb.callee());
63  aw_assert(f);
64 
65  AW_root *root = aw->get_root();
66  if (root->disable_callbacks) {
67  // some functions (namely aw_message, aw_input and aw_file_selection)
68  // have to disable most callbacks, because they are often called from inside these callbacks
69  // (e.g. because some exceptional condition occurred which needs user interaction) and if
70  // callbacks weren't disabled, a recursive deadlock occurs.
71 
72  // the following callbacks are allowed even if disable_callbacks is true
73 
74  bool isModalCallback = (f == CASTSIG(AnyWinCB, message_cb) ||
76  f == CASTSIG(AnyWinCB, input_cb) ||
78 
79  bool isPopdown = (f == AnyWinCB(AW_POPDOWN));
80  bool isHelp = (f == CASTSIG(AnyWinCB, AW_help_popup));
81  bool allow = isModalCallback || isHelp || isPopdown;
82 
83  bool isInfoResizeExpose = false;
84 
85  if (!allow) {
86  isInfoResizeExpose = aw->is_expose_callback(AW_INFO_AREA, f) || aw->is_resize_callback(AW_INFO_AREA, f);
87  allow = isInfoResizeExpose;
88  }
89 
90  if (!allow) {
91  // do not change position of modal dialog, when one of the following callbacks happens - just raise it
92  // (other callbacks like pressing a button, will position the modal dialog under mouse)
93  bool onlyRaise =
95  aw->is_focus_callback(f) ||
97 
98  if (root->current_modal_window) {
99  AW_window *awmodal = root->current_modal_window;
100 
101  AW_PosRecalc prev = awmodal->get_recalc_pos_atShow();
102  if (onlyRaise) awmodal->recalc_pos_atShow(AW_KEEP_POS);
103  awmodal->activate();
104  awmodal->recalc_pos_atShow(prev);
105  }
106  else {
107  aw_message("Internal error (callback suppressed when no modal dialog active)");
108  aw_assert(0);
109  }
110 #if defined(TRACE_CALLBACKS)
111  printf("suppressing callback %p\n", f);
112 #endif // TRACE_CALLBACKS
113  return; // suppress the callback!
114  }
115 #if defined(TRACE_CALLBACKS)
116  else {
117  if (isModalCallback) printf("allowed modal callback %p\n", f);
118  else if (isPopdown) printf("allowed AW_POPDOWN\n");
119  else if (isHelp) printf("allowed AW_help_popup\n");
120  else if (isInfoResizeExpose) printf("allowed expose/resize infoarea\n");
121  else printf("allowed other (unknown) callback %p\n", f);
122  }
123 #endif // TRACE_CALLBACKS
124  }
125  else {
126 #if defined(TRACE_CALLBACKS)
127  printf("Callbacks are allowed (executing %p)\n", f);
128 #endif // TRACE_CALLBACKS
129  }
130 
131  useraction_init();
132  cb(aw);
134 }
bool is_resize_callback(AW_area area, AnyWinCB f)
Definition: AW_window.cxx:1508
const char * get_window_id() const
Definition: aw_window.hxx:364
AW_cb(AW_window *awi, const WindowCallback &wcb, const char *help_texti=NULp, AW_cb *next=NULp)
void(* AW_cb_struct_guard)()
Definition: aw_window.hxx:114
AW_window * current_modal_window
Definition: aw_root.hxx:115
AW_window * aw
Definition: aw_window.hxx:128
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
#define CASTSIG(sig, cb)
Definition: arbtools.h:123
bool is_focus_callback(AnyWinCB f)
Definition: AW_window.cxx:1453
void activate()
Definition: aw_window.hxx:354
#define cb(action)
const char * help_text
Definition: aw_window.hxx:129
bool contains(AnyWinCB g)
bool is_expose_callback(AW_area area, AnyWinCB f)
Definition: AW_window.cxx:1485
void message_cb(AW_window *, int result)
Definition: AW_modal.cxx:33
bool is_equal(const AW_cb &other) const
#define aw_assert(bed)
Definition: aw_position.hxx:29
void file_selection_cb(AW_window *aw, int ok_cancel_flag)
Definition: AW_modal.cxx:162
WindowCallbackSimple AnyWinCB
Definition: aw_window.hxx:115
AW_PosRecalc
Definition: aw_window.hxx:216
bool disable_callbacks
Definition: aw_root.hxx:114
void recalc_pos_atShow(AW_PosRecalc pr)
Definition: AW_window.cxx:1428
void aw_message(const char *msg)
Definition: AW_status.cxx:932
AW_root * get_root()
Definition: aw_window.hxx:348
#define NULp
Definition: cxxforward.h:97
void AW_help_popup(UNFIXED, const char *help_file)
Definition: AW_help.cxx:622
static void input_cb(AW_window *aww, MatrixDisplay *disp)
static void useraction_init()
Definition: aw_window.hxx:162
AW_PosRecalc get_recalc_pos_atShow() const
Definition: AW_window.cxx:1432
void run_callbacks()
static void useraction_done(AW_window *aw)
Definition: aw_window.hxx:165
void(* AW_postcb_cb)(AW_window *)
Definition: aw_base.hxx:24
void input_history_cb(AW_window *aw, int mode)
Definition: AW_modal.cxx:121