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 | |
---|
36 | bool AW_cb::contains(AnyWinCB g) { |
---|
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 | |
---|
59 | void AW_cb::run_callbacks() { |
---|
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) || |
---|
75 | f == CASTSIG(AnyWinCB, input_history_cb) || |
---|
76 | f == CASTSIG(AnyWinCB, input_cb) || |
---|
77 | f == CASTSIG(AnyWinCB, file_selection_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 = |
---|
94 | aw->is_expose_callback(AW_MIDDLE_AREA, f) || |
---|
95 | aw->is_focus_callback(f) || |
---|
96 | aw->is_resize_callback(AW_MIDDLE_AREA, 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); |
---|
133 | useraction_done(aw); |
---|
134 | } |
---|