From d21447d096a320a08b3efb2b8768fad0dcdcfd64 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 5 May 2016 22:28:51 +0100 Subject: move frontends into sub directory --- frontends/riscos/message.c | 247 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 frontends/riscos/message.c (limited to 'frontends/riscos/message.c') diff --git a/frontends/riscos/message.c b/frontends/riscos/message.c new file mode 100644 index 000000000..1c54ea0b7 --- /dev/null +++ b/frontends/riscos/message.c @@ -0,0 +1,247 @@ +/* + * Copyright 2006 Richard Wilson + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file + * Automated RISC OS message routing (implementation). + */ + +#include +#include +#include +#include "oslib/os.h" +#include "oslib/wimp.h" + +#include "utils/log.h" + +#include "riscos/message.h" +#include "riscos/gui.h" + +struct active_message { + unsigned int message_code; + int id; + void (*callback)(wimp_message *message); + struct active_message *next; + struct active_message *previous; +}; +struct active_message *current_messages = NULL; + +static struct active_message *ro_message_add(unsigned int message_code, + void (*callback)(wimp_message *message)); +static void ro_message_free(int ref); + + +/** + * Sends a message and registers a return route for a bounce. + * + * \param event the message event type + * \param message the message to register a route back for + * \param task the task to send a message to, or 0 for broadcast + * \param callback the code to call on a bounce + * \return true on success, false otherwise + */ +bool ro_message_send_message(wimp_event_no event, wimp_message *message, + wimp_t task, void (*callback)(wimp_message *message)) +{ + os_error *error; + + assert(message); + + /* send a message */ + error = xwimp_send_message(event, message, task); + if (error) { + LOG("xwimp_send_message: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + /* register the default bounce handler */ + if (callback) { + assert(event == wimp_USER_MESSAGE_RECORDED); + return ro_message_register_handler(message, message->action, + callback); + } + return true; +} + + +/** + * Sends a message and registers a return route for a bounce. + * + * \param event the message event type + * \param message the message to register a route back for + * \param to_w the window to send the message to + * \param to_i the icon + * \param callback the code to call on a bounce + * \param to_t receives the task handle of the window's creator + * \return true on success, false otherwise + */ +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) +{ + os_error *error; + + assert(message); + + /* send a message */ + error = xwimp_send_message_to_window(event, message, to_w, to_i, to_t); + if (error) { + LOG("xwimp_send_message_to_window: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return false; + } + + /* register the default bounce handler */ + if (callback) { + assert(event == wimp_USER_MESSAGE_RECORDED); + return ro_message_register_handler(message, message->action, + callback); + } + return true; +} + + +/** + * Registers a return route for a message. + * + * This function must be called after wimp_send_message so that a + * valid value is present in the my_ref field. + * + * \param message the message to register a route back for + * \param message_code the message action code to route + * \param callback the code to call for a matched action + * \return true on success, false on memory exhaustion + */ +bool ro_message_register_handler(wimp_message *message, + unsigned int message_code, + void (*callback)(wimp_message *message)) +{ + struct active_message *add; + + assert(message); + assert(callback); + + add = ro_message_add(message_code, callback); + if (add) + add->id = message->my_ref; + return (add != NULL); +} + + +/** + * Registers a route for a message code. + * + * \param message_code the message action code to route + * \param callback the code to call for a matched action + * \return true on success, false on memory exhaustion + */ +bool ro_message_register_route(unsigned int message_code, + void (*callback)(wimp_message *message)) +{ + assert(callback); + + return (ro_message_add(message_code, callback) != NULL); +} + +struct active_message *ro_message_add(unsigned int message_code, + void (*callback)(wimp_message *message)) +{ + struct active_message *add; + + assert(callback); + + add = (struct active_message *)malloc(sizeof(*add)); + if (!add) + return NULL; + add->message_code = message_code; + add->id = 0; + add->callback = callback; + add->next = current_messages; + add->previous = NULL; + current_messages = add; + return add; +} + + +/** + * Attempts to route a message. + * + * \param event wimp event + * \param message the message to attempt to route + * \return true if message was routed, false otherwise + */ +bool ro_message_handle_message(wimp_event_no event, wimp_message *message) +{ + struct active_message *test; + + assert(message); + + if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) { + /* handle message acknowledgement */ + bool handled = false; + int ref = message->my_ref; + + if (ref == 0) + return false; + + /* handle the message */ + for (test = current_messages; test; test = test->next) { + if ((ref == test->id) && + (message->action == test->message_code)) { + handled = true; + if (test->callback) + test->callback(message); + break; + } + } + + /* remove all handlers for this id */ + ro_message_free(ref); + return handled; + } else { + /* handle simple routing */ + for (test = current_messages; test; test = test->next) { + if ((test->id == 0) && + (message->action == test->message_code)) { + test->callback(message); + return true; + } + } + } + return false; +} + + +void ro_message_free(int ref) +{ + struct active_message *test; + struct active_message *next = current_messages; + + while ((test = next)) { + next = test->next; + if (ref == test->id) { + if (test->previous) + test->previous->next = test->next; + if (test->next) + test->next->previous = test->previous; + if (current_messages == test) + current_messages = test->next; + free(test); + } + } +} -- cgit v1.2.3