source: branches/stable/WINDOW/AW_cb_struct.cxx

Last change on this file was 16986, checked in by westram, 6 years ago

Update: continued by [17178]

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.9 KB
Line 
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
20AW_cb_struct_guard AW_cb::guard_before = NULp;
21AW_cb_struct_guard AW_cb::guard_after  = NULp;
22AW_postcb_cb       AW_cb::postcb       = NULp;
23
24
25AW_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
36bool AW_cb::contains(AnyWinCB g) {
37    return (AnyWinCB(cb.callee()) == g) || (next && next->contains(g));
38}
39
40bool 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
59void 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}
Note: See TracBrowser for help on using the repository browser.