/[james]/archive/guilib/main_riscos.c
ViewVC logotype

Contents of /archive/guilib/main_riscos.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (show annotations) (download) (as text)
Mon Feb 10 22:56:40 2003 UTC (21 years, 9 months ago) by james
File MIME type: text/x-csrc
File size: 10751 byte(s)
Initial import.

1 /*
2 * main_riscos.c -- portable gui library, RISC OS
3 */
4
5 #include "gui.h"
6
7 wimp_t gui_wimp_task; /* wimp task handle */
8 os_error *gui_error; /* last error block pointer */
9 const char *gui_error_message; /* last error message */
10 int gui_error_line; /* last error line */
11 jmp_buf gui_error_jump; /* longjmp buffer for error handling */
12 bool quit = 0;
13
14 char **gui_message;
15
16 struct gui_window_data *gui_window_list; /* array of window details */
17 unsigned int gui_window_list_items; /* length of windows list */
18 signed int gui_window_origin_x, gui_window_origin_y;
19
20 static void redraw_window_request(wimp_draw *redraw);
21 static void open_window_request(wimp_open *open);
22 static void close_window_request(wimp_close *close);
23 static void mouse_click(wimp_pointer *pointer);
24 static void key_pressed(wimp_key *key);
25 static void menu_selection(wimp_selection *selection);
26 static void user_message(wimp_message *message);
27 static void help_request(wimp_message *message, help_message_request *request);
28
29
30 /****************************************************************************************/
31 /* main() */
32 /****************************************************************************************/
33
34 int main(int argc, char *argv[])
35 {
36 gui_initialise();
37 task_initialise();
38
39 gui_event_loop();
40
41 task_finalise();
42
43 return 0;
44 }
45
46
47 /****************************************************************************************/
48 /* Initialisation */
49 /****************************************************************************************/
50
51 /*
52 * gui_initialise -- initialise the program with the os or window manager
53 *
54 * => name -- program name to pass to the os if applicable
55 *
56 * <= nothing
57 */
58
59 void gui_initialise()
60 {
61 char file_name[30];
62 wimp_MESSAGE_LIST(2) messages;
63
64 gui_log("gui_initialise: task_name = '%s'\n", task_name);
65
66 if (setjmp(gui_error_jump))
67 {
68 gui_log("gui_initialise: *** error %i: %s ***\n", gui_error_line, gui_error_message);
69
70 printf("%s (%i)\n", gui_error_message, gui_error_line);
71 fflush(stdout);
72 exit(1);
73 }
74
75 messages.messages[0] = message_HELP_REQUEST;
76 messages.messages[1] = message_QUIT;
77
78 gui_error = xwimp_initialise(wimp_VERSION_RO3, task_name,
79 (wimp_message_list const *) &messages,
80 NULL, &gui_wimp_task);
81 gui_check_error();
82
83 gui_window_list = NULL;
84 gui_window_list_items = 0;
85
86 sprintf(file_name, "<%s$Messages>", task_name);
87 gui_message = gui_messages_read(file_name);
88
89 gui_log("gui_initialise: gui_wimp_task = 0x%x\n", (unsigned int) gui_wimp_task);
90 }
91
92
93 /****************************************************************************************/
94 /* Event handling */
95 /****************************************************************************************/
96
97 /*
98 * gui_event_loop -- receive and handle os or window manager events
99 *
100 * => nothing
101 *
102 * <= does not return directly, except on exit
103 */
104
105 #define MASK (wimp_MASK_NULL | wimp_MASK_LEAVING | wimp_MASK_ENTERING | wimp_MASK_LOSE | wimp_MASK_GAIN | wimp_MASK_POLLWORD)
106
107 static gui_window_id menu_window_id;
108
109 void gui_event_loop(void)
110 {
111 wimp_block block;
112 wimp_event_no event;
113 os_error err;
114
115 if (setjmp(gui_error_jump))
116 {
117 gui_log("gui_event_loop: *** error %i: %s ***\n", gui_error_line, gui_error_message);
118
119 err.errnum = 1;
120 sprintf(err.errmess, "%s (%i)\n", gui_error_message, gui_error_line);
121 xwimp_report_error(&err, wimp_ERROR_BOX_OK_ICON, task_name, NULL);
122 }
123
124 while (!quit)
125 {
126 gui_error = xwimp_poll(MASK, &block, NULL, &event);
127 gui_check_error();
128
129 gui_log("gui_event_loop: event = %i\n", event);
130 switch (event)
131 {
132 case wimp_REDRAW_WINDOW_REQUEST: redraw_window_request(&block.redraw); break;
133 case wimp_OPEN_WINDOW_REQUEST: open_window_request(&block.open); break;
134 case wimp_CLOSE_WINDOW_REQUEST: close_window_request(&block.close); break;
135 case wimp_MOUSE_CLICK: mouse_click(&block.pointer); break;
136 case wimp_KEY_PRESSED: key_pressed(&block.key); break;
137 case wimp_MENU_SELECTION: menu_selection(&block.selection); break;
138 case wimp_USER_MESSAGE:
139 case wimp_USER_MESSAGE_RECORDED: user_message(&block.message); break;
140 }
141 }
142 }
143
144
145 /*
146 * redraw window request
147 */
148
149 void redraw_window_request(wimp_draw *redraw)
150 {
151 bool more;
152 unsigned int invalid[4]; /* why was this signed ?? */
153 gui_window_id window_id = gui_handle_to_window_id(redraw->w);
154
155 assert(window_id == gui_WINDOW_UNKNOWN ||
156 (window_id < gui_window_list_items && gui_window_list[window_id].used));
157
158 gui_error = xwimp_redraw_window(redraw, &more);
159 gui_check_error();
160
161 gui_window_origin_x = redraw->box.x0 - redraw->xscroll;
162 gui_window_origin_y = redraw->box.y1 - redraw->yscroll;
163
164 gui_log("gui_event_loop: redraw origin %i %i\n", gui_window_origin_x, gui_window_origin_y);
165
166 while (more)
167 {
168 if (window_id != gui_WINDOW_UNKNOWN && gui_window_list[window_id].redraw_fn)
169 {
170 invalid[0] = redraw->clip.x0 - gui_window_origin_x;
171 invalid[1] = gui_window_origin_y - redraw->clip.y1;
172 invalid[2] = redraw->clip.x1 - gui_window_origin_x;
173 invalid[3] = gui_window_origin_y - redraw->clip.y0;
174
175 gui_log("gui_event_loop: redraw invalid %i %i %i %i\n",
176 invalid[0], invalid[1], invalid[2], invalid[3]);
177
178 gui_window_list[window_id].redraw_fn(window_id, invalid);
179 }
180 gui_error = xwimp_get_rectangle(redraw, &more);
181 gui_check_error();
182 }
183 }
184
185
186 /*
187 * open window request
188 */
189
190 void open_window_request(wimp_open *open)
191 {
192 gui_window_id window_id = gui_handle_to_window_id(open->w);
193
194 gui_error = xwimp_open_window(open);
195 gui_check_error();
196
197 if (window_id != gui_WINDOW_UNKNOWN)
198 {
199 assert(window_id < gui_window_list_items && gui_window_list[window_id].used);
200 if ((unsigned int) (open->visible.x1 - open->visible.x0) != gui_window_list[window_id].width ||
201 (unsigned int) (open->visible.y1 - open->visible.y0) != gui_window_list[window_id].height)
202 {
203 gui_window_list[window_id].width = open->visible.x1 - open->visible.x0;
204 gui_window_list[window_id].height = open->visible.y1 - open->visible.y0;
205 gui_log("open_window_request: resized to %i %i\n",
206 gui_window_list[window_id].width, gui_window_list[window_id].height);
207 if (gui_window_list[window_id].resize_fn)
208 gui_window_list[window_id].resize_fn(window_id,
209 gui_window_list[window_id].width, gui_window_list[window_id].height);
210 }
211 }
212 }
213
214
215 /*
216 * close window request
217 */
218
219 void close_window_request(wimp_close *close)
220 {
221 gui_window_id window_id = gui_handle_to_window_id(close->w);
222
223 gui_log("gui_event_loop: window_id = 0x%x\n", window_id);
224
225 if (window_id != gui_WINDOW_UNKNOWN)
226 {
227 assert(window_id < gui_window_list_items && gui_window_list[window_id].used);
228 gui_window_list[window_id].close_fn(window_id);
229 }
230 }
231
232
233 /*
234 * mouse click
235 */
236
237 void mouse_click(wimp_pointer *pointer)
238 {
239 gui_window_id window_id = gui_handle_to_window_id(pointer->w);
240
241 gui_log("gui_event_loop: window_id = 0x%x\n", window_id);
242
243 if (window_id != gui_WINDOW_UNKNOWN)
244 {
245 assert(window_id < gui_window_list_items && gui_window_list[window_id].used);
246 if (gui_window_list[window_id].menu && (pointer->buttons & wimp_CLICK_MENU))
247 {
248 gui_error = xwimp_create_menu(gui_window_list[window_id].menu,
249 pointer->pos.x - 64, pointer->pos.y);
250 gui_check_error();
251 menu_window_id = window_id;
252 }
253 else if (gui_window_list[window_id].click_fn)
254 {
255 unsigned int x, y, z;
256 wimp_window_state state;
257
258 state.w = pointer->w;
259 gui_error = xwimp_get_window_state(&state);
260 gui_check_error();
261
262 x = pointer->pos.x - (state.visible.x0 - state.xscroll);
263 y = (state.visible.y1 - state.yscroll) - pointer->pos.y;
264 z = (pointer->buttons & wimp_CLICK_SELECT ? gui_CLICK :
265 (pointer->buttons & wimp_CLICK_ADJUST ? gui_CLICK_RIGHT :
266 (pointer->buttons & wimp_DRAG_SELECT ? gui_DRAG :
267 (pointer->buttons & wimp_DRAG_ADJUST ? gui_DRAG_RIGHT : 0))));
268 gui_window_list[window_id].click_fn(window_id, x, y, z);
269 }
270 }
271 }
272
273
274 /*
275 * key pressed
276 */
277
278 void key_pressed(wimp_key *key)
279 {
280 gui_window_id window_id = gui_handle_to_window_id(key->w);
281
282 gui_log("gui_event_loop: window_id = 0x%x\n", window_id);
283
284 if (window_id != gui_WINDOW_UNKNOWN)
285 {
286 assert(window_id < gui_window_list_items && gui_window_list[window_id].used);
287
288 if ((key->c & (1<<31)) || (key->c < 256))
289 {
290 if (gui_window_list[window_id].input_fn)
291 gui_window_list[window_id].input_fn(window_id, (wchar_t) (key->c & 0xffff));
292 }
293 else
294 {
295 if (gui_window_list[window_id].key_fn)
296 gui_window_list[window_id].key_fn(window_id, (unsigned int) key->c);
297 }
298 }
299 }
300
301
302 /*
303 * menu selection
304 */
305
306 void menu_selection(wimp_selection *selection)
307 {
308 wimp_pointer pointer;
309
310 gui_error = xwimp_get_pointer_info(&pointer);
311 gui_check_error();
312
313 gui_window_list[menu_window_id].menu_fn(menu_window_id, (unsigned int *) selection->items);
314
315 if (pointer.buttons == wimp_CLICK_ADJUST)
316 {
317 gui_error = xwimp_create_menu(gui_window_list[menu_window_id].menu, 0, 0);
318 gui_check_error();
319 }
320 }
321
322
323 /*
324 * user message, user message recorded
325 */
326
327 void user_message(wimp_message *message)
328 {
329 gui_log("gui_event_loop: block.message.action = 0x%x\n", message->action);
330
331 switch (message->action)
332 {
333 case message_QUIT:
334 quit = 1;
335 break;
336 case message_HELP_REQUEST:
337 help_request(message, (help_message_request *) &message->data);
338 break;
339 }
340 }
341
342 /*
343 * interactive help request
344 */
345
346 void help_request(wimp_message *message, help_message_request *request)
347 {
348 const char *help;
349 wimp_message reply;
350 gui_window_id window_id = gui_handle_to_window_id(request->w);
351
352 if (window_id != gui_WINDOW_UNKNOWN)
353 {
354 if (gui_window_list[window_id].used == DIALOG && request->i >= 0)
355 help = gui_window_list[window_id].icon[request->i].help;
356 else
357 help = gui_window_list[window_id].help;
358
359 gui_log(help);
360 reply.size = (20 + strlen(help) + 3) & ~3u;
361 reply.your_ref = message->my_ref;
362 reply.action = message_HELP_REPLY;
363 strcpy((char *) &reply.data.reserved, help);
364 gui_error = xwimp_send_message(wimp_USER_MESSAGE, &reply, message->sender);
365 gui_check_error();
366 }
367 }

  ViewVC Help
Powered by ViewVC 1.1.26