Subversion Repositories Filer-Free

Rev

Rev 58 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6 gdshaw@RISCPKG.ORG 1
// This file is part of the free Filer module for RISC OS.
2
// Copyright  2007 Graham Shaw.
3
// Redistribution and modification are permitted under the terms of the
4
// GNU General Public License (version 2 or any later version).
5
 
6
#include <setjmp.h>
7
#include <signal.h>
8
#include <kernel.h>
9
 
10
#include "oslib/os.h"
11
 
13 gdshaw@RISCPKG.ORG 12
#include "window.h"
16 gdshaw@RISCPKG.ORG 13
#include "menu.h"
6 gdshaw@RISCPKG.ORG 14
#include "application.h"
15
 
16
/** The recovery routine for handling a RISC OS error. */
17
static jmp_buf jmp_oserror;
18
 
19
/** Handle a RISC OS error signal.
20
 * This function is the signal handler for a RISC OS error.  It performs
21
 * a long jump to the recovery routine that should previously have been
22
 * specified in jmp_oserror.
23
 *
24
 * Note that performing a long jump out of a signal handler is not fully
25
 * portable, but it is acceptable in this context.
26
 */
27
static void handle_oserror(int)
28
{
29
        longjmp(jmp_oserror,1);
30
};
31
 
32
application::application(const char* appname,wimp_message_list* messages):
33
        _appname(appname),
34
        _handle(0),
16 gdshaw@RISCPKG.ORG 35
        _quit(false),
37 gdshaw@RISCPKG.ORG 36
        _current_menu(0),
37
        _current_drag(0)
6 gdshaw@RISCPKG.ORG 38
{
39
        _handle=wimp_initialise(310,appname,messages,0);
40
}
41
 
59 gdshaw@RISCPKG.ORG 42
application::~application()
43
{}
44
 
6 gdshaw@RISCPKG.ORG 45
void application::run(int* pollword)
46
{
47
        // Set signal handler for RISC OS errors.
48
        // (Note that jmp_oserror has not been initialised yet, so it is
49
        // important that no RISC OS errors occur between this point and
50
        // when it is initialised.)
51
        signal(SIGOSERROR,&handle_oserror);
52
 
53
        // Main polling loop: repeat until quit flag is set to true.
54
        while (!_quit)
55
        {
56
                // Establish signal handler for RISC OS errors.
57
                if (setjmp(jmp_oserror)==0)
58
                {
59
                        // Poll the window manager.
60
                        static wimp_block block;
61
                        wimp_poll_flags flags=poll_flags();
62
                        if (pollword) flags|=wimp_GIVEN_POLLWORD;
63
                        wimp_event_no event=wimp_poll(flags,&block,pollword);
64
 
65
                        // Handle the resulting event.
66
                        handle_event(event,block);
67
                }
68
                else
69
                {
70
                        // Recovery from a RISC OS error: display error window.
71
                        wimp_report_error((os_error*)_kernel_last_oserror(),
72
                                wimp_ERROR_BOX_OK_ICON,_appname);
73
 
74
                        // Reestablish signal handler.
75
                        signal(SIGOSERROR,&handle_oserror);
76
                }
77
        }
78
}
79
 
13 gdshaw@RISCPKG.ORG 80
window* application::find_window(wimp_w handle)
81
{
82
        return _windows.find(handle);
83
}
84
 
6 gdshaw@RISCPKG.ORG 85
wimp_poll_flags application::poll_flags()
86
{
87
        return 0;
88
}
89
 
90
void application::handle_event(wimp_event_no event,wimp_block& block)
10 gdshaw@RISCPKG.ORG 91
{
16 gdshaw@RISCPKG.ORG 92
        menu* m;
13 gdshaw@RISCPKG.ORG 93
        window* w;
10 gdshaw@RISCPKG.ORG 94
        switch (event)
95
        {
13 gdshaw@RISCPKG.ORG 96
        case wimp_REDRAW_WINDOW_REQUEST:
97
                if (w=_windows.find(((wimp_draw&)block).w))
98
                {
99
                        w->handle_redraw_request((wimp_draw&)block);
100
                }
101
        break;
102
        case wimp_OPEN_WINDOW_REQUEST:
103
                if (w=_windows.find(block.open.w))
104
                {
105
                        w->handle_open_request(block.open);
106
                }
107
                break;
108
        case wimp_CLOSE_WINDOW_REQUEST:
109
                if (w=_windows.find(block.close.w))
110
                {
111
                        w->handle_close_request(block.close);
112
                }
113
                break;
114
        case wimp_MOUSE_CLICK:
115
                if (block.pointer.w==wimp_ICON_BAR)
116
                {
117
                        handle_mouse_click(block.pointer);
118
                }
119
                else if (w=_windows.find(block.pointer.w))
120
                {
121
                        w->handle_mouse_click(block.pointer);
122
                }
123
                break;
37 gdshaw@RISCPKG.ORG 124
        case wimp_USER_DRAG_BOX:
125
                if (w=_current_drag)
126
                {
127
                        _current_drag=0;
128
                        w->handle_user_drag_box(block.dragged);
129
                }
130
                break;
13 gdshaw@RISCPKG.ORG 131
        case wimp_KEY_PRESSED:
132
                if (w=_windows.find(block.key.w))
133
                {
134
                        w->handle_key_pressed(block.key);
135
                }
136
                else
137
                {
58 gdshaw@RISCPKG.ORG 138
                        handle_key_pressed(block.key);
13 gdshaw@RISCPKG.ORG 139
                }
140
                break;
16 gdshaw@RISCPKG.ORG 141
        case wimp_MENU_SELECTION:
142
                if (m=_current_menu)
143
                {
144
                        _current_menu=0;
145
                        m->handle_menu_selection(block.selection);
146
                }
147
                break;
10 gdshaw@RISCPKG.ORG 148
        case wimp_USER_MESSAGE:
149
        case wimp_USER_MESSAGE_RECORDED:
150
                switch (block.message.action)
151
                {
152
                case message_QUIT:
153
                        _quit=true;
154
                        break;
56 gdshaw@RISCPKG.ORG 155
                case message_DATA_SAVE:
156
                case message_DATA_SAVE_ACK:
157
                case message_DATA_LOAD:
158
                case message_DATA_LOAD_ACK:
159
                        if (w=_windows.find(block.message.data.data_xfer.w))
160
                        {
161
                                w->handle_data_xfer(block.message);
162
                        }
163
                        break;
16 gdshaw@RISCPKG.ORG 164
                case message_MENUS_DELETED:
165
                        if (m=_current_menu)
166
                        {
167
                                _current_menu=0;
168
                                m->handle_menus_deleted();
169
                        }
170
                        break;
26 gdshaw@RISCPKG.ORG 171
                default:
172
                        handle_user_message(event,block.message);
173
                        break;
10 gdshaw@RISCPKG.ORG 174
                }
175
                break;
176
        }
177
}
13 gdshaw@RISCPKG.ORG 178
 
179
void application::handle_mouse_click(wimp_pointer& block)
180
{}
181
 
58 gdshaw@RISCPKG.ORG 182
void application::handle_key_pressed(wimp_key& block)
183
{
184
        wimp_process_key(block.c);
185
}
186
 
26 gdshaw@RISCPKG.ORG 187
void application::handle_user_message(wimp_event_no event,
188
        wimp_message& message)
189
{}
190
 
13 gdshaw@RISCPKG.ORG 191
void application::register_window(window& w)
192
{
193
        _windows.insert(w);
194
}
195
 
196
void application::deregister_window(window& w)
197
{
198
        _windows.erase(w);
199
}
16 gdshaw@RISCPKG.ORG 200
 
201
void application::register_menu(menu& m)
202
{
203
        _current_menu=&m;
204
}
37 gdshaw@RISCPKG.ORG 205
 
206
void application::register_drag(window& w)
207
{
208
        _current_drag=&w;
209
}