NetSurf
message.c
Go to the documentation of this file.
1/*
2 * Copyright 2006 Richard Wilson <info@tinct.net>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/** \file
20 * Automated RISC OS message routing (implementation).
21 */
22
23#include <assert.h>
24#include <stdbool.h>
25#include <stdlib.h>
26#include "oslib/os.h"
27#include "oslib/wimp.h"
28
29#include "utils/log.h"
30
31#include "riscos/message.h"
32#include "riscos/gui.h"
33
35 unsigned int message_code;
36 int id;
37 void (*callback)(wimp_message *message);
40};
42
43static struct active_message *ro_message_add(unsigned int message_code,
44 void (*callback)(wimp_message *message));
45static void ro_message_free(int ref);
46
47
48/**
49 * Sends a message and registers a return route for a bounce.
50 *
51 * \param event the message event type
52 * \param message the message to register a route back for
53 * \param task the task to send a message to, or 0 for broadcast
54 * \param callback the code to call on a bounce
55 * \return true on success, false otherwise
56 */
57bool ro_message_send_message(wimp_event_no event, wimp_message *message,
58 wimp_t task, void (*callback)(wimp_message *message))
59{
60 os_error *error;
61
62 assert(message);
63
64 /* send a message */
65 error = xwimp_send_message(event, message, task);
66 if (error) {
67 NSLOG(netsurf, INFO, "xwimp_send_message: 0x%x: %s",
68 error->errnum, error->errmess);
69 ro_warn_user("WimpError", error->errmess);
70 return false;
71 }
72
73 /* register the default bounce handler */
74 if (callback) {
75 assert(event == wimp_USER_MESSAGE_RECORDED);
76 return ro_message_register_handler(message, message->action,
77 callback);
78 }
79 return true;
80}
81
82
83/**
84 * Sends a message and registers a return route for a bounce.
85 *
86 * \param event the message event type
87 * \param message the message to register a route back for
88 * \param to_w the window to send the message to
89 * \param to_i the icon
90 * \param callback the code to call on a bounce
91 * \param to_t receives the task handle of the window's creator
92 * \return true on success, false otherwise
93 */
94bool ro_message_send_message_to_window(wimp_event_no event, wimp_message *message,
95 wimp_w to_w, wimp_i to_i, void (*callback)(wimp_message *message),
96 wimp_t *to_t)
97{
98 os_error *error;
99
100 assert(message);
101
102 /* send a message */
103 error = xwimp_send_message_to_window(event, message, to_w, to_i, to_t);
104 if (error) {
105 NSLOG(netsurf, INFO,
106 "xwimp_send_message_to_window: 0x%x: %s",
107 error->errnum,
108 error->errmess);
109 ro_warn_user("WimpError", error->errmess);
110 return false;
111 }
112
113 /* register the default bounce handler */
114 if (callback) {
115 assert(event == wimp_USER_MESSAGE_RECORDED);
116 return ro_message_register_handler(message, message->action,
117 callback);
118 }
119 return true;
120}
121
122
123/**
124 * Registers a return route for a message.
125 *
126 * This function must be called after wimp_send_message so that a
127 * valid value is present in the my_ref field.
128 *
129 * \param message the message to register a route back for
130 * \param message_code the message action code to route
131 * \param callback the code to call for a matched action
132 * \return true on success, false on memory exhaustion
133 */
134bool ro_message_register_handler(wimp_message *message,
135 unsigned int message_code,
136 void (*callback)(wimp_message *message))
137{
138 struct active_message *add;
139
140 assert(message);
141 assert(callback);
142
144 if (add)
145 add->id = message->my_ref;
146 return (add != NULL);
147}
148
149
150/**
151 * Registers a route for a message code.
152 *
153 * \param message_code the message action code to route
154 * \param callback the code to call for a matched action
155 * \return true on success, false on memory exhaustion
156 */
158 void (*callback)(wimp_message *message))
159{
160 assert(callback);
161
162 return (ro_message_add(message_code, callback) != NULL);
163}
164
166 void (*callback)(wimp_message *message))
167{
168 struct active_message *add;
169
170 assert(callback);
171
172 add = (struct active_message *)malloc(sizeof(*add));
173 if (!add)
174 return NULL;
176 add->id = 0;
177 add->callback = callback;
178 add->next = current_messages;
179 add->previous = NULL;
180 current_messages = add;
181 return add;
182}
183
184
185/**
186 * Attempts to route a message.
187 *
188 * \param event wimp event
189 * \param message the message to attempt to route
190 * \return true if message was routed, false otherwise
191 */
192bool ro_message_handle_message(wimp_event_no event, wimp_message *message)
193{
194 struct active_message *test;
195
196 assert(message);
197
198 if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) {
199 /* handle message acknowledgement */
200 bool handled = false;
201 int ref = message->my_ref;
202
203 if (ref == 0)
204 return false;
205
206 /* handle the message */
207 for (test = current_messages; test; test = test->next) {
208 if ((ref == test->id) &&
209 (message->action == test->message_code)) {
210 handled = true;
211 if (test->callback)
212 test->callback(message);
213 break;
214 }
215 }
216
217 /* remove all handlers for this id */
218 ro_message_free(ref);
219 return handled;
220 } else {
221 /* handle simple routing */
222 for (test = current_messages; test; test = test->next) {
223 if ((test->id == 0) &&
224 (message->action == test->message_code)) {
225 test->callback(message);
226 return true;
227 }
228 }
229 }
230 return false;
231}
232
233
234void ro_message_free(int ref)
235{
236 struct active_message *test;
238
239 while ((test = next)) {
240 next = test->next;
241 if (ref == test->id) {
242 if (test->previous)
243 test->previous->next = test->next;
244 if (test->next)
245 test->next->previous = test->previous;
246 if (current_messages == test)
247 current_messages = test->next;
248 free(test);
249 }
250 }
251}
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
static void ro_message_free(int ref)
Definition: message.c:234
bool ro_message_handle_message(wimp_event_no event, wimp_message *message)
Attempts to route a message.
Definition: message.c:192
bool ro_message_register_handler(wimp_message *message, unsigned int message_code, void(*callback)(wimp_message *message))
Registers a return route for a message.
Definition: message.c:134
static struct active_message * ro_message_add(unsigned int message_code, void(*callback)(wimp_message *message))
Definition: message.c:165
bool ro_message_send_message(wimp_event_no event, wimp_message *message, wimp_t task, void(*callback)(wimp_message *message))
Sends a message and registers a return route for a bounce.
Definition: message.c:57
bool ro_message_register_route(unsigned int message_code, void(*callback)(wimp_message *message))
Registers a route for a message code.
Definition: message.c:157
bool ro_message_send_message_to_window(wimp_event_no event, wimp_message *message, wimp_w to_w, wimp_i to_i, void(*callback)(wimp_message *message), wimp_t *to_t)
Sends a message and registers a return route for a bounce.
Definition: message.c:94
struct active_message * current_messages
Definition: message.c:41
Automated RISC OS message routing (interface).
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2077
struct active_message * next
Definition: message.c:38
unsigned int message_code
Definition: message.c:35
struct active_message * previous
Definition: message.c:39
void(* callback)(wimp_message *message)
Definition: message.c:37