NetSurf
mouse.c
Go to the documentation of this file.
1/*
2 * Copyright 2013 Stephen Fryatt <stevef@netsurf-browser.org>
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 * Mouse dragging and tracking support implementation.
21 *
22 * Two different functions are provided:-
23 *
24 * 1. Wimp_DragBox support, allowing clients to start a drag and specify
25 * callbacks to be used
26 *
27 * - on Null Polls while the drag is active,
28 * - when the drag terminates with Event_DragEnd, and
29 * - when the drag terminates with Escape being pressed.
30 *
31 * 2. Mouse tracking support, allowing clients to track the mouse while it
32 * remains in the current window and specify callbacks to be used
33 *
34 * - on Null Polls while the pointer is in the window, and
35 * - when the pointer leaves the window.
36 */
37
38#include <assert.h>
39#include <oslib/wimp.h>
40
41#include "utils/log.h"
42
43#include "riscos/mouse.h"
44#include "riscos/gui.h"
45
46/* Data for the wimp drag handler. */
47
48static void (*ro_mouse_drag_end_callback)(wimp_dragged *dragged, void *data)
49 = NULL;
50static void (*ro_mouse_drag_track_callback)(wimp_pointer *pointer, void *data)
51 = NULL;
52static void (*ro_mouse_drag_cancel_callback)(void *data) = NULL;
53static void *ro_mouse_drag_data = NULL;
54
56
57/* Data for the wimp poll handler. */
58
59static void (*ro_mouse_poll_end_callback)(wimp_leaving *leaving, void *data)
60 = NULL;
61static void (*ro_mouse_poll_track_callback)(wimp_pointer *pointer, void *data)
62 = NULL;
63static void *ro_mouse_poll_data = NULL;
64
65
66/**
67 * Process Null polls for any drags and mouse trackers that are currently
68 * active.
69 */
70
71void ro_mouse_poll(void)
72{
73 wimp_pointer pointer;
74 os_error *error;
75
76 /* If no trackers are active, just exit. */
77
78 if (ro_mouse_drag_track_callback == NULL &&
80 return;
81
82 error = xwimp_get_pointer_info(&pointer);
83 if (error) {
84 NSLOG(netsurf, INFO, "xwimp_get_pointer_info: 0x%x: %s",
85 error->errnum, error->errmess);
86 ro_warn_user("WimpError", error->errmess);
87 return;
88 }
89
90 /* Process the drag tracker, if one is active. */
91
94
95 /* Process the window tracker, if one is active. */
96
99}
100
101
102/**
103 * Start a drag, providing a function to be called when the Wimp_DragEnd event
104 * is received and optionally a tracking function to be called on null polls
105 * in between times.
106 *
107 * \param *drag_end Callback for when the drag terminates, or NULL for none.
108 * \param *drag_track Callback for mouse tracking during the drag, or NULL for
109 * none.
110 * \param *drag_cancel Callback for cancelling the drag, or NULL if the drag
111 * can't be cancelled.
112 * \param *data Data to be passed to the callback functions, or NULL.
113 */
114
115void ro_mouse_drag_start(void (*drag_end)(wimp_dragged *dragged, void *data),
116 void (*drag_track)(wimp_pointer *pointer, void *data),
117 void (*drag_cancel)(void *data), void *data)
118{
119 /* A drag should never be started when one is already in progress. */
120
121 assert(ro_mouse_drag_end_callback == NULL &&
124 ro_mouse_drag_data == NULL);
125
127 ro_mouse_drag_track_callback = drag_track;
128 ro_mouse_drag_cancel_callback = drag_cancel;
129 ro_mouse_drag_data = data;
130
131 /* The Wimp sends a PointerLeaving event when Wimp_DragBox is called,
132 * so we mask out the next event that will come our way.
133 */
134
136}
137
138
139/**
140 * Process Wimp_DragEnd events by terminating an active drag track and passing
141 * the details on to any registered event handler.
142 *
143 * \param *dragged The Wimp_DragEnd data block.
144 */
145
146void ro_mouse_drag_end(wimp_dragged *dragged)
147{
148 if (ro_mouse_drag_end_callback != NULL)
150 else
151 ro_warn_user("WimpError", "No callback");
152
153 /* Wimp_DragEnd is a one-shot event, so clear the data ready for
154 * another claimant.
155 */
156
160 ro_mouse_drag_data = NULL;
161}
162
163
164/**
165 * Start tracking the mouse in a window, providing a function to be called on
166 * null polls and optionally one to be called when it leaves the window.
167 *
168 * \param *poll_end Callback for when the pointer leaves the window, or
169 * NULL for none. Claimants can receive *leaving==NULL if
170 * a new tracker is started before a PointerLeaving event
171 * is received.
172 * \param *poll_track Callback for mouse tracking while the pointer remains
173 * in the window, or NULL for none.
174 * \param *data Data to be passed to the callback functions, or NULL.
175 */
176
177void ro_mouse_track_start(void (*poll_end)(wimp_leaving *leaving, void *data),
178 void (*poll_track)(wimp_pointer *pointer, void *data),
179 void *data)
180{
181 /* It should never be possible for the mouse to be in two windows
182 * at the same time! However, some third-party extensions to RISC OS
183 * appear to make this possible (MouseAxess being one), so in the
184 * event that there's still a claimant we tidy them up first and then
185 * log the fact in case there are any unexpected consequences.
186 *
187 * NB: The Poll End callback will get called with *leaving == NULL in
188 * this situation, as there's no PointerLeaving event to pass on.
189 */
190
191 if (ro_mouse_poll_end_callback != NULL ||
193 ro_mouse_poll_data != NULL) {
194 if (ro_mouse_poll_end_callback != NULL &&
197
198 NSLOG(netsurf, INFO, "Unexpected mouse track termination.");
199
203 ro_mouse_poll_data = NULL;
204 }
205
206 /* Now record details of the new claimant. */
207
209 ro_mouse_poll_track_callback = poll_track;
210 ro_mouse_poll_data = data;
211}
212
213
214/**
215 * Process Wimp_PointerLeaving events by terminating an active mouse track and
216 * passing the details on to any registered event handler.
217 *
218 * If the ignore mask is set, we don't pass the event on to the client as it
219 * is assumed that it's a result of starting a Wimp_DragBox operation.
220 *
221 * \param *leaving The Wimp_PointerLeaving data block.
222 */
223
224void ro_mouse_pointer_leaving_window(wimp_leaving *leaving)
225{
226 if (ro_mouse_poll_end_callback != NULL &&
229
231
232 /* Poll tracking is a one-shot event, so clear the data ready for
233 * another claimant.
234 */
235
238 ro_mouse_poll_data = NULL;
239}
240
241
242/**
243 * Kill any tracking events if the data pointers match the supplied pointer.
244 *
245 * \param *data The data of the client to be killed.
246 */
247
248void ro_mouse_kill(void *data)
249{
250 if (data == ro_mouse_drag_data) {
254 ro_mouse_drag_data = NULL;
255 }
256
257 if (data == ro_mouse_poll_data) {
260 ro_mouse_poll_data = NULL;
261 }
262}
263
264
265/**
266 * Return the desired polling interval to allow the mouse tracking to be
267 * carried out.
268 *
269 * \return Desired poll interval (0 for none required).
270 */
271
273{
275 return 4;
276
278 return 10;
279
280 return 0;
281
282}
283
static void(* ro_mouse_drag_end_callback)(wimp_dragged *dragged, void *data)
Definition: mouse.c:48
void ro_mouse_pointer_leaving_window(wimp_leaving *leaving)
Process Wimp_PointerLeaving events by terminating an active mouse track and passing the details on to...
Definition: mouse.c:224
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)
Start a drag, providing a function to be called when the Wimp_DragEnd event is received and optionall...
Definition: mouse.c:115
static void(* ro_mouse_drag_track_callback)(wimp_pointer *pointer, void *data)
Definition: mouse.c:50
static bool ro_mouse_ignore_leaving_event
Definition: mouse.c:55
static void(* ro_mouse_poll_track_callback)(wimp_pointer *pointer, void *data)
Definition: mouse.c:61
os_t ro_mouse_poll_interval(void)
Return the desired polling interval to allow the mouse tracking to be carried out.
Definition: mouse.c:272
static void(* ro_mouse_poll_end_callback)(wimp_leaving *leaving, void *data)
Definition: mouse.c:59
void ro_mouse_drag_end(wimp_dragged *dragged)
Process Wimp_DragEnd events by terminating an active drag track and passing the details on to any reg...
Definition: mouse.c:146
static void * ro_mouse_drag_data
Definition: mouse.c:53
static void(* ro_mouse_drag_cancel_callback)(void *data)
Definition: mouse.c:52
static void * ro_mouse_poll_data
Definition: mouse.c:63
void ro_mouse_poll(void)
Process Null polls for any drags and mouse trackers that are currently active.
Definition: mouse.c:71
void ro_mouse_track_start(void(*poll_end)(wimp_leaving *leaving, void *data), void(*poll_track)(wimp_pointer *pointer, void *data), void *data)
Start tracking the mouse in a window, providing a function to be called on null polls and optionally ...
Definition: mouse.c:177
void ro_mouse_kill(void *data)
Kill any tracking events if the data pointers match the supplied pointer.
Definition: mouse.c:248
Mouse dragging and tracking support interface for RISC OS.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
nserror ro_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.c:2217