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/mouse.c | 282 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 frontends/riscos/mouse.c (limited to 'frontends/riscos/mouse.c') diff --git a/frontends/riscos/mouse.c b/frontends/riscos/mouse.c new file mode 100644 index 000000000..a0cc0e7ce --- /dev/null +++ b/frontends/riscos/mouse.c @@ -0,0 +1,282 @@ +/* + * Copyright 2013 Stephen Fryatt + * + * 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 + * Mouse dragging and tracking support implementation. + * + * Two different functions are provided:- + * + * 1. Wimp_DragBox support, allowing clients to start a drag and specify + * callbacks to be used + * + * - on Null Polls while the drag is active, + * - when the drag terminates with Event_DragEnd, and + * - when the drag terminates with Escape being pressed. + * + * 2. Mouse tracking support, allowing clients to track the mouse while it + * remains in the current window and specify callbacks to be used + * + * - on Null Polls while the pointer is in the window, and + * - when the pointer leaves the window. + */ + +#include +#include + +#include "utils/log.h" + +#include "riscos/mouse.h" +#include "riscos/gui.h" + +/* Data for the wimp drag handler. */ + +static void (*ro_mouse_drag_end_callback)(wimp_dragged *dragged, void *data) + = NULL; +static void (*ro_mouse_drag_track_callback)(wimp_pointer *pointer, void *data) + = NULL; +static void (*ro_mouse_drag_cancel_callback)(void *data) = NULL; +static void *ro_mouse_drag_data = NULL; + +static bool ro_mouse_ignore_leaving_event = false; + +/* Data for the wimp poll handler. */ + +static void (*ro_mouse_poll_end_callback)(wimp_leaving *leaving, void *data) + = NULL; +static void (*ro_mouse_poll_track_callback)(wimp_pointer *pointer, void *data) + = NULL; +static void *ro_mouse_poll_data = NULL; + + +/** + * Process Null polls for any drags and mouse trackers that are currently + * active. + */ + +void ro_mouse_poll(void) +{ + wimp_pointer pointer; + os_error *error; + + /* If no trackers are active, just exit. */ + + if (ro_mouse_drag_track_callback == NULL && + ro_mouse_poll_track_callback == NULL) + return; + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return; + } + + /* Process the drag tracker, if one is active. */ + + if (ro_mouse_drag_track_callback != NULL) + ro_mouse_drag_track_callback(&pointer, ro_mouse_drag_data); + + /* Process the window tracker, if one is active. */ + + if (ro_mouse_poll_track_callback != NULL) + ro_mouse_poll_track_callback(&pointer, ro_mouse_poll_data); +} + + +/** + * Start a drag, providing a function to be called when the Wimp_DragEnd event + * is received and optionally a tracking function to be called on null polls + * in between times. + * + * \param *drag_end Callback for when the drag terminates, or NULL for none. + * \param *drag_track Callback for mouse tracking during the drag, or NULL for + * none. + * \param *drag_cancel Callback for cancelling the drag, or NULL if the drag + * can't be cancelled. + * \param *data Data to be passed to the callback functions, or NULL. + */ + +void ro_mouse_drag_start(void (*drag_end)(wimp_dragged *dragged, void *data), + void (*drag_track)(wimp_pointer *pointer, void *data), + void (*drag_cancel)(void *data), void *data) +{ + /* A drag should never be started when one is already in progress. */ + + assert(ro_mouse_drag_end_callback == NULL && + ro_mouse_drag_track_callback == NULL && + ro_mouse_drag_cancel_callback == NULL && + ro_mouse_drag_data == NULL); + + ro_mouse_drag_end_callback = drag_end; + ro_mouse_drag_track_callback = drag_track; + ro_mouse_drag_cancel_callback = drag_cancel; + ro_mouse_drag_data = data; + + /* The Wimp sends a PointerLeaving event when Wimp_DragBox is called, + * so we mask out the next event that will come our way. + */ + + ro_mouse_ignore_leaving_event = true; +} + + +/** + * Process Wimp_DragEnd events by terminating an active drag track and passing + * the details on to any registered event handler. + * + * \param *dragged The Wimp_DragEnd data block. + */ + +void ro_mouse_drag_end(wimp_dragged *dragged) +{ + if (ro_mouse_drag_end_callback != NULL) + ro_mouse_drag_end_callback(dragged, ro_mouse_drag_data); + else + ro_warn_user("WimpError", "No callback"); + + /* Wimp_DragEnd is a one-shot event, so clear the data ready for + * another claimant. + */ + + ro_mouse_drag_end_callback = NULL; + ro_mouse_drag_track_callback = NULL; + ro_mouse_drag_cancel_callback = NULL; + ro_mouse_drag_data = NULL; +} + + +/** + * Start tracking the mouse in a window, providing a function to be called on + * null polls and optionally one to be called when it leaves the window. + * + * \param *poll_end Callback for when the pointer leaves the window, or + * NULL for none. Claimants can receive *leaving==NULL if + * a new tracker is started before a PointerLeaving event + * is received. + * \param *poll_track Callback for mouse tracking while the pointer remains + * in the window, or NULL for none. + * \param *data Data to be passed to the callback functions, or NULL. + */ + +void ro_mouse_track_start(void (*poll_end)(wimp_leaving *leaving, void *data), + void (*poll_track)(wimp_pointer *pointer, void *data), + void *data) +{ + /* It should never be possible for the mouse to be in two windows + * at the same time! However, some third-party extensions to RISC OS + * appear to make this possible (MouseAxess being one), so in the + * event that there's still a claimant we tidy them up first and then + * log the fact in case there are any unexpected consequences. + * + * NB: The Poll End callback will get called with *leaving == NULL in + * this situation, as there's no PointerLeaving event to pass on. + */ + + if (ro_mouse_poll_end_callback != NULL || + ro_mouse_poll_track_callback != NULL || + ro_mouse_poll_data != NULL) { + if (ro_mouse_poll_end_callback != NULL && + ro_mouse_ignore_leaving_event == false) + ro_mouse_poll_end_callback(NULL, ro_mouse_poll_data); + + LOG("Unexpected mouse track termination."); + + ro_mouse_ignore_leaving_event = false; + ro_mouse_poll_end_callback = NULL; + ro_mouse_poll_track_callback = NULL; + ro_mouse_poll_data = NULL; + } + + /* Now record details of the new claimant. */ + + ro_mouse_poll_end_callback = poll_end; + ro_mouse_poll_track_callback = poll_track; + ro_mouse_poll_data = data; +} + + +/** + * Process Wimp_PointerLeaving events by terminating an active mouse track and + * passing the details on to any registered event handler. + * + * If the ignore mask is set, we don't pass the event on to the client as it + * is assumed that it's a result of starting a Wimp_DragBox operation. + * + * \param *leaving The Wimp_PointerLeaving data block. + */ + +void ro_mouse_pointer_leaving_window(wimp_leaving *leaving) +{ + if (ro_mouse_poll_end_callback != NULL && + ro_mouse_ignore_leaving_event == false) + ro_mouse_poll_end_callback(leaving, ro_mouse_poll_data); + + ro_mouse_ignore_leaving_event = false; + + /* Poll tracking is a one-shot event, so clear the data ready for + * another claimant. + */ + + ro_mouse_poll_end_callback = NULL; + ro_mouse_poll_track_callback = NULL; + ro_mouse_poll_data = NULL; +} + + +/** + * Kill any tracking events if the data pointers match the supplied pointer. + * + * \param *data The data of the client to be killed. + */ + +void ro_mouse_kill(void *data) +{ + if (data == ro_mouse_drag_data) { + ro_mouse_drag_end_callback = NULL; + ro_mouse_drag_track_callback = NULL; + ro_mouse_drag_cancel_callback = NULL; + ro_mouse_drag_data = NULL; + } + + if (data == ro_mouse_poll_data) { + ro_mouse_poll_end_callback = NULL; + ro_mouse_poll_track_callback = NULL; + ro_mouse_poll_data = NULL; + } +} + + +/** + * Return the desired polling interval to allow the mouse tracking to be + * carried out. + * + * \return Desired poll interval (0 for none required). + */ + +os_t ro_mouse_poll_interval(void) +{ + if (ro_mouse_drag_track_callback != NULL) + return 4; + + if (ro_mouse_poll_track_callback != NULL) + return 10; + + return 0; + +} + -- cgit v1.2.3