/src/gstreamer/subprojects/gst-plugins-base/gst-libs/gst/video/navigation.c
Line | Count | Source |
1 | | /* GStreamer Navigation |
2 | | * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net> |
3 | | * Copyright (C) 2007-2009 Jan Schmidt <thaytan@noraisin.net> |
4 | | * |
5 | | * navigation.c: navigation event virtual class function wrappers |
6 | | * |
7 | | * This library is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Library General Public |
9 | | * License as published by the Free Software Foundation; either |
10 | | * version 2 of the License, or (at your option) any later version. |
11 | | * |
12 | | * This library is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Library General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Library General Public |
18 | | * License along with this library; if not, write to the |
19 | | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
20 | | * Boston, MA 02110-1301, USA. |
21 | | */ |
22 | | |
23 | | /** |
24 | | * SECTION:gstnavigation |
25 | | * @title: GstNavigation |
26 | | * @short_description: Interface for creating, sending and parsing navigation |
27 | | * events. |
28 | | * |
29 | | * The Navigation interface is used for creating and injecting navigation |
30 | | * related events such as mouse button presses, cursor motion and key presses. |
31 | | * The associated library also provides methods for parsing received events, and |
32 | | * for sending and receiving navigation related bus events. One main usecase is |
33 | | * DVD menu navigation. |
34 | | * |
35 | | * The main parts of the API are: |
36 | | * |
37 | | * * The GstNavigation interface, implemented by elements which provide an |
38 | | * application with the ability to create and inject navigation events into |
39 | | * the pipeline. |
40 | | * * GstNavigation event handling API. GstNavigation events are created in |
41 | | * response to calls on a GstNavigation interface implementation, and sent in |
42 | | * the pipeline. Upstream elements can use the navigation event API functions |
43 | | * to parse the contents of received messages. |
44 | | * |
45 | | * * GstNavigation message handling API. GstNavigation messages may be sent on |
46 | | * the message bus to inform applications of navigation related changes in the |
47 | | * pipeline, such as the mouse moving over a clickable region, or the set of |
48 | | * available angles changing. |
49 | | * |
50 | | * The GstNavigation message functions provide functions for creating and |
51 | | * parsing custom bus messages for signaling GstNavigation changes. |
52 | | */ |
53 | | |
54 | | #ifdef HAVE_CONFIG_H |
55 | | #include "config.h" |
56 | | #endif |
57 | | |
58 | | #include <gst/video/navigation.h> |
59 | | #include <gst/video/video-enumtypes.h> |
60 | | |
61 | 0 | #define GST_NAVIGATION_MESSAGE_NAME "GstNavigationMessage" |
62 | 0 | #define GST_NAVIGATION_QUERY_NAME "GstNavigationQuery" |
63 | 0 | #define GST_NAVIGATION_EVENT_NAME "application/x-gst-navigation" |
64 | | |
65 | 0 | #define WARN_IF_FAIL(exp,msg) if(G_UNLIKELY(!(exp))){g_warning("%s",(msg));} |
66 | | |
67 | 8 | G_DEFINE_INTERFACE (GstNavigation, gst_navigation, 0); |
68 | 8 | |
69 | 8 | static void |
70 | 8 | gst_navigation_default_send_event_simple (GstNavigation * navigation, |
71 | 8 | GstEvent * event) |
72 | 8 | { |
73 | 0 | GstNavigationInterface *iface = GST_NAVIGATION_GET_INTERFACE (navigation); |
74 | |
|
75 | 0 | if (iface->send_event) { |
76 | 0 | iface->send_event (navigation, |
77 | 0 | gst_structure_copy (gst_event_get_structure (event))); |
78 | 0 | } else { |
79 | 0 | gst_event_unref (event); |
80 | 0 | } |
81 | 0 | } |
82 | | |
83 | | static void |
84 | | gst_navigation_default_init (GstNavigationInterface * iface) |
85 | 2 | { |
86 | | /* default virtual functions */ |
87 | 2 | iface->send_event = NULL; |
88 | 2 | iface->send_event_simple = gst_navigation_default_send_event_simple; |
89 | 2 | } |
90 | | |
91 | | /* The interface implementer should make sure that the object can handle |
92 | | * the event. */ |
93 | | void |
94 | | gst_navigation_send_event (GstNavigation * navigation, GstStructure * structure) |
95 | 0 | { |
96 | 0 | GstNavigationInterface *iface; |
97 | |
|
98 | 0 | g_return_if_fail (GST_IS_NAVIGATION (navigation)); |
99 | | |
100 | 0 | iface = GST_NAVIGATION_GET_INTERFACE (navigation); |
101 | 0 | if (iface->send_event) { |
102 | 0 | iface->send_event (navigation, structure); |
103 | 0 | } else if (iface->send_event_simple) { |
104 | 0 | iface->send_event_simple (navigation, gst_event_new_navigation (structure)); |
105 | 0 | } else { |
106 | 0 | gst_structure_free (structure); |
107 | 0 | } |
108 | 0 | } |
109 | | |
110 | | /** |
111 | | * gst_navigation_send_key_event: |
112 | | * @navigation: The navigation interface instance |
113 | | * @event: The type of the key event. Recognised values are "key-press" and |
114 | | * "key-release" |
115 | | * @key: Character representation of the key. This is typically as produced |
116 | | * by XKeysymToString. |
117 | | */ |
118 | | void |
119 | | gst_navigation_send_key_event (GstNavigation * navigation, const char *event, |
120 | | const char *key) |
121 | 0 | { |
122 | 0 | g_return_if_fail (GST_IS_NAVIGATION (navigation)); |
123 | 0 | g_return_if_fail (g_strcmp0 (event, "key-press") == 0 || |
124 | 0 | g_strcmp0 (event, "key-release") == 0); |
125 | | |
126 | 0 | gst_navigation_send_event (navigation, |
127 | 0 | gst_structure_new (GST_NAVIGATION_EVENT_NAME, "event", G_TYPE_STRING, |
128 | 0 | event, "key", G_TYPE_STRING, key, NULL)); |
129 | 0 | } |
130 | | |
131 | | /** |
132 | | * gst_navigation_send_mouse_event: |
133 | | * @navigation: The navigation interface instance |
134 | | * @event: The type of mouse event, as a text string. Recognised values are |
135 | | * "mouse-button-press", "mouse-button-release", "mouse-move" and "mouse-double-click". |
136 | | * @button: The button number of the button being pressed or released. Pass 0 |
137 | | * for mouse-move events. |
138 | | * @x: The x coordinate of the mouse event. |
139 | | * @y: The y coordinate of the mouse event. |
140 | | * |
141 | | * Sends a mouse event to the navigation interface. Mouse event coordinates |
142 | | * are sent relative to the display space of the related output area. This is |
143 | | * usually the size in pixels of the window associated with the element |
144 | | * implementing the #GstNavigation interface. |
145 | | * |
146 | | */ |
147 | | void |
148 | | gst_navigation_send_mouse_event (GstNavigation * navigation, const char *event, |
149 | | int button, double x, double y) |
150 | 0 | { |
151 | 0 | g_return_if_fail (GST_IS_NAVIGATION (navigation)); |
152 | 0 | g_return_if_fail (g_strcmp0 (event, "mouse-button-press") == 0 || |
153 | 0 | g_strcmp0 (event, "mouse-button-release") == 0 || |
154 | 0 | g_strcmp0 (event, "mouse-move") == 0 || |
155 | 0 | g_strcmp0 (event, "mouse-double-click") == 0); |
156 | | |
157 | 0 | gst_navigation_send_event (navigation, |
158 | 0 | gst_structure_new (GST_NAVIGATION_EVENT_NAME, "event", G_TYPE_STRING, |
159 | 0 | event, "button", G_TYPE_INT, button, "pointer_x", G_TYPE_DOUBLE, x, |
160 | 0 | "pointer_y", G_TYPE_DOUBLE, y, NULL)); |
161 | 0 | } |
162 | | |
163 | | /** |
164 | | * gst_navigation_send_mouse_scroll_event: |
165 | | * @navigation: The navigation interface instance |
166 | | * @x: The x coordinate of the mouse event. |
167 | | * @y: The y coordinate of the mouse event. |
168 | | * @delta_x: The delta_x coordinate of the mouse event. |
169 | | * @delta_y: The delta_y coordinate of the mouse event. |
170 | | * |
171 | | * Sends a mouse scroll event to the navigation interface. Mouse event coordinates |
172 | | * are sent relative to the display space of the related output area. This is |
173 | | * usually the size in pixels of the window associated with the element |
174 | | * implementing the #GstNavigation interface. |
175 | | * |
176 | | * Since: 1.18 |
177 | | */ |
178 | | void |
179 | | gst_navigation_send_mouse_scroll_event (GstNavigation * navigation, |
180 | | double x, double y, double delta_x, double delta_y) |
181 | 0 | { |
182 | 0 | g_return_if_fail (GST_IS_NAVIGATION (navigation)); |
183 | | |
184 | 0 | gst_navigation_send_event (navigation, |
185 | 0 | gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
186 | 0 | "event", G_TYPE_STRING, "mouse-scroll", |
187 | 0 | "pointer_x", G_TYPE_DOUBLE, x, |
188 | 0 | "pointer_y", G_TYPE_DOUBLE, y, |
189 | 0 | "delta_pointer_x", G_TYPE_DOUBLE, delta_x, |
190 | 0 | "delta_pointer_y", G_TYPE_DOUBLE, delta_y, NULL)); |
191 | 0 | } |
192 | | |
193 | | /** |
194 | | * gst_navigation_send_command: |
195 | | * @navigation: The navigation interface instance |
196 | | * @command: The command to issue |
197 | | * |
198 | | * Sends the indicated command to the navigation interface. |
199 | | */ |
200 | | void |
201 | | gst_navigation_send_command (GstNavigation * navigation, |
202 | | GstNavigationCommand command) |
203 | 0 | { |
204 | 0 | g_return_if_fail (GST_IS_NAVIGATION (navigation)); |
205 | | |
206 | 0 | gst_navigation_send_event (navigation, |
207 | 0 | gst_structure_new (GST_NAVIGATION_EVENT_NAME, "event", G_TYPE_STRING, |
208 | 0 | "command", "command-code", G_TYPE_UINT, (guint) command, NULL)); |
209 | 0 | } |
210 | | |
211 | | /** |
212 | | * gst_navigation_send_event_simple: |
213 | | * @navigation: The navigation interface instance |
214 | | * @event: (transfer full): The event to send |
215 | | * |
216 | | * Sends an event to the navigation interface. |
217 | | * Since: 1.22 |
218 | | */ |
219 | | void |
220 | | gst_navigation_send_event_simple (GstNavigation * navigation, GstEvent * event) |
221 | 0 | { |
222 | 0 | GstNavigationInterface *iface; |
223 | |
|
224 | 0 | g_return_if_fail (GST_IS_NAVIGATION (navigation)); |
225 | 0 | g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_NAVIGATION); |
226 | | |
227 | 0 | iface = GST_NAVIGATION_GET_INTERFACE (navigation); |
228 | 0 | if (iface->send_event_simple) { |
229 | 0 | iface->send_event_simple (navigation, event); |
230 | 0 | } else if (iface->send_event) { |
231 | 0 | iface->send_event (navigation, |
232 | 0 | gst_structure_copy (gst_event_get_structure (event))); |
233 | 0 | gst_event_unref (event); |
234 | 0 | } else { |
235 | 0 | gst_event_unref (event); |
236 | 0 | } |
237 | 0 | } |
238 | | |
239 | | /* Navigation Queries */ |
240 | | |
241 | | #define GST_NAVIGATION_QUERY_HAS_TYPE(query,query_type) \ |
242 | | (gst_navigation_query_get_type (query) == GST_NAVIGATION_QUERY_ ## query_type) |
243 | | |
244 | | /** |
245 | | * gst_navigation_query_get_type: |
246 | | * @query: The query to inspect |
247 | | * |
248 | | * Inspect a #GstQuery and return the #GstNavigationQueryType associated with |
249 | | * it if it is a #GstNavigation query. |
250 | | * |
251 | | * Returns: The #GstNavigationQueryType of the query, or |
252 | | * #GST_NAVIGATION_QUERY_INVALID |
253 | | */ |
254 | | GstNavigationQueryType |
255 | | gst_navigation_query_get_type (GstQuery * query) |
256 | 0 | { |
257 | 0 | const GstStructure *s; |
258 | 0 | const gchar *q_type; |
259 | |
|
260 | 0 | if (query == NULL || GST_QUERY_TYPE (query) != GST_QUERY_CUSTOM) |
261 | 0 | return GST_NAVIGATION_QUERY_INVALID; |
262 | | |
263 | 0 | s = gst_query_get_structure (query); |
264 | 0 | if (s == NULL || !gst_structure_has_name (s, GST_NAVIGATION_QUERY_NAME)) |
265 | 0 | return GST_NAVIGATION_QUERY_INVALID; |
266 | | |
267 | 0 | q_type = gst_structure_get_string (s, "type"); |
268 | 0 | if (q_type == NULL) |
269 | 0 | return GST_NAVIGATION_QUERY_INVALID; |
270 | | |
271 | 0 | if (g_str_equal (q_type, "commands")) |
272 | 0 | return GST_NAVIGATION_QUERY_COMMANDS; |
273 | 0 | else if (g_str_equal (q_type, "angles")) |
274 | 0 | return GST_NAVIGATION_QUERY_ANGLES; |
275 | | |
276 | 0 | return GST_NAVIGATION_QUERY_INVALID; |
277 | 0 | } |
278 | | |
279 | | /** |
280 | | * gst_navigation_query_new_commands: |
281 | | * |
282 | | * Create a new #GstNavigation commands query. When executed, it will |
283 | | * query the pipeline for the set of currently available commands. |
284 | | * |
285 | | * Returns: The new query. |
286 | | */ |
287 | | GstQuery * |
288 | | gst_navigation_query_new_commands (void) |
289 | 0 | { |
290 | 0 | GstQuery *query; |
291 | 0 | GstStructure *structure; |
292 | |
|
293 | 0 | structure = gst_structure_new (GST_NAVIGATION_QUERY_NAME, |
294 | 0 | "type", G_TYPE_STRING, "commands", NULL); |
295 | 0 | query = gst_query_new_custom (GST_QUERY_CUSTOM, structure); |
296 | |
|
297 | 0 | return query; |
298 | 0 | } |
299 | | |
300 | | static void |
301 | | gst_query_list_add_command (GValue * list, GstNavigationCommand val) |
302 | 0 | { |
303 | 0 | GValue item = { 0, }; |
304 | |
|
305 | 0 | g_value_init (&item, GST_TYPE_NAVIGATION_COMMAND); |
306 | 0 | g_value_set_enum (&item, val); |
307 | 0 | gst_value_list_append_value (list, &item); |
308 | 0 | g_value_unset (&item); |
309 | 0 | } |
310 | | |
311 | | /** |
312 | | * gst_navigation_query_set_commands: |
313 | | * @query: a #GstQuery |
314 | | * @n_cmds: the number of commands to set. |
315 | | * @...: A list of @GstNavigationCommand values, @n_cmds entries long. |
316 | | * |
317 | | * Set the #GstNavigation command query result fields in @query. The number |
318 | | * of commands passed must be equal to @n_commands. |
319 | | */ |
320 | | void |
321 | | gst_navigation_query_set_commands (GstQuery * query, gint n_cmds, ...) |
322 | 0 | { |
323 | 0 | va_list ap; |
324 | 0 | GValue list = { 0, }; |
325 | 0 | GstStructure *structure; |
326 | 0 | gint i; |
327 | |
|
328 | 0 | g_return_if_fail (GST_NAVIGATION_QUERY_HAS_TYPE (query, COMMANDS)); |
329 | | |
330 | 0 | g_value_init (&list, GST_TYPE_LIST); |
331 | |
|
332 | 0 | va_start (ap, n_cmds); |
333 | 0 | for (i = 0; i < n_cmds; i++) { |
334 | 0 | GstNavigationCommand val = va_arg (ap, GstNavigationCommand); |
335 | 0 | gst_query_list_add_command (&list, val); |
336 | 0 | } |
337 | 0 | va_end (ap); |
338 | |
|
339 | 0 | structure = gst_query_writable_structure (query); |
340 | 0 | gst_structure_take_value (structure, "commands", &list); |
341 | 0 | } |
342 | | |
343 | | /** |
344 | | * gst_navigation_query_set_commandsv: |
345 | | * @query: a #GstQuery |
346 | | * @n_cmds: the number of commands to set. |
347 | | * @cmds: (array length=n_cmds): An array containing @n_cmds |
348 | | * @GstNavigationCommand values. |
349 | | * |
350 | | * Set the #GstNavigation command query result fields in @query. The number |
351 | | * of commands passed must be equal to @n_commands. |
352 | | */ |
353 | | void |
354 | | gst_navigation_query_set_commandsv (GstQuery * query, gint n_cmds, |
355 | | GstNavigationCommand * cmds) |
356 | 0 | { |
357 | 0 | GValue list = { 0, }; |
358 | 0 | GstStructure *structure; |
359 | 0 | gint i; |
360 | |
|
361 | 0 | g_return_if_fail (GST_NAVIGATION_QUERY_HAS_TYPE (query, COMMANDS)); |
362 | | |
363 | 0 | g_value_init (&list, GST_TYPE_LIST); |
364 | 0 | for (i = 0; i < n_cmds; i++) { |
365 | 0 | gst_query_list_add_command (&list, cmds[i]); |
366 | 0 | } |
367 | 0 | structure = gst_query_writable_structure (query); |
368 | 0 | gst_structure_take_value (structure, "commands", &list); |
369 | 0 | } |
370 | | |
371 | | /** |
372 | | * gst_navigation_query_parse_commands_length: |
373 | | * @query: a #GstQuery |
374 | | * @n_cmds: (out) (optional): the number of commands in this query. |
375 | | * |
376 | | * Parse the number of commands in the #GstNavigation commands @query. |
377 | | * |
378 | | * Returns: %TRUE if the query could be successfully parsed. %FALSE if not. |
379 | | */ |
380 | | gboolean |
381 | | gst_navigation_query_parse_commands_length (GstQuery * query, guint * n_cmds) |
382 | 0 | { |
383 | 0 | const GstStructure *structure; |
384 | 0 | const GValue *list; |
385 | |
|
386 | 0 | g_return_val_if_fail (GST_NAVIGATION_QUERY_HAS_TYPE (query, COMMANDS), FALSE); |
387 | | |
388 | 0 | if (n_cmds == NULL) |
389 | 0 | return TRUE; |
390 | | |
391 | 0 | structure = gst_query_get_structure (query); |
392 | 0 | list = gst_structure_get_value (structure, "commands"); |
393 | 0 | if (list == NULL) |
394 | 0 | *n_cmds = 0; |
395 | 0 | else |
396 | 0 | *n_cmds = gst_value_list_get_size (list); |
397 | |
|
398 | 0 | return TRUE; |
399 | 0 | } |
400 | | |
401 | | /** |
402 | | * gst_navigation_query_parse_commands_nth: |
403 | | * @query: a #GstQuery |
404 | | * @nth: the nth command to retrieve. |
405 | | * @cmd: (out) (optional): a pointer to store the nth command into. |
406 | | * |
407 | | * Parse the #GstNavigation command query and retrieve the @nth command from |
408 | | * it into @cmd. If the list contains less elements than @nth, @cmd will be |
409 | | * set to #GST_NAVIGATION_COMMAND_INVALID. |
410 | | * |
411 | | * Returns: %TRUE if the query could be successfully parsed. %FALSE if not. |
412 | | */ |
413 | | gboolean |
414 | | gst_navigation_query_parse_commands_nth (GstQuery * query, guint nth, |
415 | | GstNavigationCommand * cmd) |
416 | 0 | { |
417 | 0 | const GstStructure *structure; |
418 | 0 | const GValue *list; |
419 | |
|
420 | 0 | g_return_val_if_fail (GST_NAVIGATION_QUERY_HAS_TYPE (query, COMMANDS), FALSE); |
421 | | |
422 | 0 | if (cmd == NULL) |
423 | 0 | return TRUE; |
424 | | |
425 | 0 | structure = gst_query_get_structure (query); |
426 | 0 | list = gst_structure_get_value (structure, "commands"); |
427 | 0 | if (list == NULL) { |
428 | 0 | *cmd = GST_NAVIGATION_COMMAND_INVALID; |
429 | 0 | } else { |
430 | 0 | if (nth < gst_value_list_get_size (list)) { |
431 | 0 | *cmd = (GstNavigationCommand) |
432 | 0 | g_value_get_enum (gst_value_list_get_value (list, nth)); |
433 | 0 | } else |
434 | 0 | *cmd = GST_NAVIGATION_COMMAND_INVALID; |
435 | 0 | } |
436 | |
|
437 | 0 | return TRUE; |
438 | 0 | } |
439 | | |
440 | | /** |
441 | | * gst_navigation_query_new_angles: |
442 | | * |
443 | | * Create a new #GstNavigation angles query. When executed, it will |
444 | | * query the pipeline for the set of currently available angles, which may be |
445 | | * greater than one in a multiangle video. |
446 | | * |
447 | | * Returns: The new query. |
448 | | */ |
449 | | GstQuery * |
450 | | gst_navigation_query_new_angles (void) |
451 | 0 | { |
452 | 0 | GstQuery *query; |
453 | 0 | GstStructure *structure; |
454 | |
|
455 | 0 | structure = gst_structure_new (GST_NAVIGATION_QUERY_NAME, |
456 | 0 | "type", G_TYPE_STRING, "angles", NULL); |
457 | 0 | query = gst_query_new_custom (GST_QUERY_CUSTOM, structure); |
458 | |
|
459 | 0 | return query; |
460 | 0 | } |
461 | | |
462 | | /** |
463 | | * gst_navigation_query_set_angles: |
464 | | * @query: a #GstQuery |
465 | | * @cur_angle: the current viewing angle to set. |
466 | | * @n_angles: the number of viewing angles to set. |
467 | | * |
468 | | * Set the #GstNavigation angles query result field in @query. |
469 | | */ |
470 | | void |
471 | | gst_navigation_query_set_angles (GstQuery * query, guint cur_angle, |
472 | | guint n_angles) |
473 | 0 | { |
474 | 0 | GstStructure *structure; |
475 | |
|
476 | 0 | g_return_if_fail (GST_NAVIGATION_QUERY_HAS_TYPE (query, ANGLES)); |
477 | | |
478 | 0 | structure = gst_query_writable_structure (query); |
479 | 0 | gst_structure_set (structure, |
480 | 0 | "angle", G_TYPE_UINT, cur_angle, "angles", G_TYPE_UINT, n_angles, NULL); |
481 | 0 | } |
482 | | |
483 | | /** |
484 | | * gst_navigation_query_parse_angles: |
485 | | * @query: a #GstQuery |
486 | | * @cur_angle: (out) (optional): Pointer to a #guint into which to store the |
487 | | * currently selected angle value from the query, or NULL |
488 | | * @n_angles: (out) (optional): Pointer to a #guint into which to store the |
489 | | * number of angles value from the query, or NULL |
490 | | * |
491 | | * Parse the current angle number in the #GstNavigation angles @query into the |
492 | | * #guint pointed to by the @cur_angle variable, and the number of available |
493 | | * angles into the #guint pointed to by the @n_angles variable. |
494 | | * |
495 | | * Returns: %TRUE if the query could be successfully parsed. %FALSE if not. |
496 | | */ |
497 | | gboolean |
498 | | gst_navigation_query_parse_angles (GstQuery * query, guint * cur_angle, |
499 | | guint * n_angles) |
500 | 0 | { |
501 | 0 | const GstStructure *structure; |
502 | 0 | gboolean ret = TRUE; |
503 | |
|
504 | 0 | g_return_val_if_fail (GST_NAVIGATION_QUERY_HAS_TYPE (query, ANGLES), FALSE); |
505 | | |
506 | 0 | structure = gst_query_get_structure (query); |
507 | |
|
508 | 0 | if (cur_angle) |
509 | 0 | ret &= gst_structure_get_uint (structure, "angle", cur_angle); |
510 | |
|
511 | 0 | if (n_angles) |
512 | 0 | ret &= gst_structure_get_uint (structure, "angles", n_angles); |
513 | |
|
514 | 0 | WARN_IF_FAIL (ret, "Couldn't extract details from angles query"); |
515 | |
|
516 | 0 | return ret; |
517 | 0 | } |
518 | | |
519 | | /* Navigation Messages */ |
520 | | |
521 | 0 | #define GST_NAVIGATION_MESSAGE_HAS_TYPE(msg,msg_type) \ |
522 | 0 | (gst_navigation_message_get_type (msg) == GST_NAVIGATION_MESSAGE_ ## msg_type) |
523 | | |
524 | | /** |
525 | | * gst_navigation_message_get_type: |
526 | | * @message: A #GstMessage to inspect. |
527 | | * |
528 | | * Check a bus message to see if it is a #GstNavigation event, and return |
529 | | * the #GstNavigationMessageType identifying the type of the message if so. |
530 | | * |
531 | | * Returns: The type of the #GstMessage, or |
532 | | * #GST_NAVIGATION_MESSAGE_INVALID if the message is not a #GstNavigation |
533 | | * notification. |
534 | | */ |
535 | | GstNavigationMessageType |
536 | | gst_navigation_message_get_type (GstMessage * message) |
537 | 0 | { |
538 | 0 | const GstStructure *s; |
539 | 0 | const gchar *m_type; |
540 | |
|
541 | 0 | if (message == NULL || GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) |
542 | 0 | return GST_NAVIGATION_MESSAGE_INVALID; |
543 | | |
544 | 0 | s = gst_message_get_structure (message); |
545 | 0 | if (s == NULL || !gst_structure_has_name (s, GST_NAVIGATION_MESSAGE_NAME)) |
546 | 0 | return GST_NAVIGATION_MESSAGE_INVALID; |
547 | | |
548 | 0 | m_type = gst_structure_get_string (s, "type"); |
549 | 0 | if (m_type == NULL) |
550 | 0 | return GST_NAVIGATION_MESSAGE_INVALID; |
551 | | |
552 | 0 | if (g_str_equal (m_type, "mouse-over")) |
553 | 0 | return GST_NAVIGATION_MESSAGE_MOUSE_OVER; |
554 | 0 | else if (g_str_equal (m_type, "commands-changed")) |
555 | 0 | return GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED; |
556 | 0 | else if (g_str_equal (m_type, "angles-changed")) |
557 | 0 | return GST_NAVIGATION_MESSAGE_ANGLES_CHANGED; |
558 | 0 | else if (g_str_equal (m_type, "event")) |
559 | 0 | return GST_NAVIGATION_MESSAGE_EVENT; |
560 | | |
561 | 0 | return GST_NAVIGATION_MESSAGE_INVALID; |
562 | 0 | } |
563 | | |
564 | | /** |
565 | | * gst_navigation_message_new_mouse_over: |
566 | | * @src: A #GstObject to set as source of the new message. |
567 | | * @active: %TRUE if the mouse has entered a clickable area of the display. |
568 | | * %FALSE if it over a non-clickable area. |
569 | | * |
570 | | * Creates a new #GstNavigation message with type |
571 | | * #GST_NAVIGATION_MESSAGE_MOUSE_OVER. |
572 | | * |
573 | | * Returns: The new #GstMessage. |
574 | | */ |
575 | | GstMessage * |
576 | | gst_navigation_message_new_mouse_over (GstObject * src, gboolean active) |
577 | 0 | { |
578 | 0 | GstStructure *s; |
579 | 0 | GstMessage *m; |
580 | |
|
581 | 0 | s = gst_structure_new (GST_NAVIGATION_MESSAGE_NAME, |
582 | 0 | "type", G_TYPE_STRING, "mouse-over", "active", G_TYPE_BOOLEAN, active, |
583 | 0 | NULL); |
584 | |
|
585 | 0 | m = gst_message_new_custom (GST_MESSAGE_ELEMENT, src, s); |
586 | |
|
587 | 0 | return m; |
588 | 0 | } |
589 | | |
590 | | /** |
591 | | * gst_navigation_message_parse_mouse_over: |
592 | | * @message: A #GstMessage to inspect. |
593 | | * @active: (out) (optional): A pointer to a gboolean to receive the |
594 | | * active/inactive state, or NULL. |
595 | | * |
596 | | * Parse a #GstNavigation message of type #GST_NAVIGATION_MESSAGE_MOUSE_OVER |
597 | | * and extract the active/inactive flag. If the mouse over event is marked |
598 | | * active, it indicates that the mouse is over a clickable area. |
599 | | * |
600 | | * Returns: %TRUE if the message could be successfully parsed. %FALSE if not. |
601 | | */ |
602 | | gboolean |
603 | | gst_navigation_message_parse_mouse_over (GstMessage * message, |
604 | | gboolean * active) |
605 | 0 | { |
606 | 0 | if (!GST_NAVIGATION_MESSAGE_HAS_TYPE (message, MOUSE_OVER)) |
607 | 0 | return FALSE; |
608 | | |
609 | 0 | if (active) { |
610 | 0 | const GstStructure *s = gst_message_get_structure (message); |
611 | 0 | if (!gst_structure_get_boolean (s, "active", active)) |
612 | 0 | return FALSE; |
613 | 0 | } |
614 | | |
615 | 0 | return TRUE; |
616 | 0 | } |
617 | | |
618 | | /** |
619 | | * gst_navigation_message_new_event: |
620 | | * @src: A #GstObject to set as source of the new message. |
621 | | * @event: (transfer none): A navigation #GstEvent |
622 | | * |
623 | | * Creates a new #GstNavigation message with type |
624 | | * #GST_NAVIGATION_MESSAGE_EVENT. |
625 | | * |
626 | | * Returns: The new #GstMessage. |
627 | | * |
628 | | * Since: 1.6 |
629 | | */ |
630 | | GstMessage * |
631 | | gst_navigation_message_new_event (GstObject * src, GstEvent * event) |
632 | 0 | { |
633 | 0 | GstStructure *s; |
634 | 0 | GstMessage *m; |
635 | |
|
636 | 0 | s = gst_structure_new (GST_NAVIGATION_MESSAGE_NAME, |
637 | 0 | "type", G_TYPE_STRING, "event", "event", GST_TYPE_EVENT, event, NULL); |
638 | |
|
639 | 0 | m = gst_message_new_custom (GST_MESSAGE_ELEMENT, src, s); |
640 | |
|
641 | 0 | return m; |
642 | 0 | } |
643 | | |
644 | | /** |
645 | | * gst_navigation_message_parse_event: |
646 | | * @message: A #GstMessage to inspect. |
647 | | * @event: (out) (optional) (transfer full): a pointer to a #GstEvent to receive |
648 | | * the contained navigation event. |
649 | | * |
650 | | * Parse a #GstNavigation message of type #GST_NAVIGATION_MESSAGE_EVENT |
651 | | * and extract contained #GstEvent. The caller must unref the @event when done |
652 | | * with it. |
653 | | * |
654 | | * Returns: %TRUE if the message could be successfully parsed. %FALSE if not. |
655 | | * |
656 | | * Since: 1.6 |
657 | | */ |
658 | | gboolean |
659 | | gst_navigation_message_parse_event (GstMessage * message, GstEvent ** event) |
660 | 0 | { |
661 | 0 | if (!GST_NAVIGATION_MESSAGE_HAS_TYPE (message, EVENT)) |
662 | 0 | return FALSE; |
663 | | |
664 | 0 | if (event) { |
665 | 0 | const GstStructure *s = gst_message_get_structure (message); |
666 | 0 | if (!gst_structure_get (s, "event", GST_TYPE_EVENT, event, NULL)) |
667 | 0 | return FALSE; |
668 | 0 | } |
669 | | |
670 | 0 | return TRUE; |
671 | 0 | } |
672 | | |
673 | | /** |
674 | | * gst_navigation_message_new_commands_changed: |
675 | | * @src: A #GstObject to set as source of the new message. |
676 | | * |
677 | | * Creates a new #GstNavigation message with type |
678 | | * #GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED |
679 | | * |
680 | | * Returns: The new #GstMessage. |
681 | | */ |
682 | | GstMessage * |
683 | | gst_navigation_message_new_commands_changed (GstObject * src) |
684 | 0 | { |
685 | 0 | GstStructure *s; |
686 | 0 | GstMessage *m; |
687 | |
|
688 | 0 | s = gst_structure_new (GST_NAVIGATION_MESSAGE_NAME, |
689 | 0 | "type", G_TYPE_STRING, "commands-changed", NULL); |
690 | |
|
691 | 0 | m = gst_message_new_custom (GST_MESSAGE_ELEMENT, src, s); |
692 | |
|
693 | 0 | return m; |
694 | 0 | } |
695 | | |
696 | | /** |
697 | | * gst_navigation_message_new_angles_changed: |
698 | | * @src: A #GstObject to set as source of the new message. |
699 | | * @cur_angle: The currently selected angle. |
700 | | * @n_angles: The number of viewing angles now available. |
701 | | * |
702 | | * Creates a new #GstNavigation message with type |
703 | | * #GST_NAVIGATION_MESSAGE_ANGLES_CHANGED for notifying an application |
704 | | * that the current angle, or current number of angles available in a |
705 | | * multiangle video has changed. |
706 | | * |
707 | | * Returns: The new #GstMessage. |
708 | | */ |
709 | | GstMessage * |
710 | | gst_navigation_message_new_angles_changed (GstObject * src, guint cur_angle, |
711 | | guint n_angles) |
712 | 0 | { |
713 | 0 | GstStructure *s; |
714 | 0 | GstMessage *m; |
715 | |
|
716 | 0 | s = gst_structure_new (GST_NAVIGATION_MESSAGE_NAME, |
717 | 0 | "type", G_TYPE_STRING, "angles-changed", |
718 | 0 | "angle", G_TYPE_UINT, cur_angle, "angles", G_TYPE_UINT, n_angles, NULL); |
719 | |
|
720 | 0 | m = gst_message_new_custom (GST_MESSAGE_ELEMENT, src, s); |
721 | |
|
722 | 0 | return m; |
723 | 0 | } |
724 | | |
725 | | /** |
726 | | * gst_navigation_message_parse_angles_changed: |
727 | | * @message: A #GstMessage to inspect. |
728 | | * @cur_angle: (out) (optional): A pointer to a #guint to receive the new |
729 | | * current angle number, or NULL |
730 | | * @n_angles: (out) (optional): A pointer to a #guint to receive the new angle |
731 | | * count, or NULL. |
732 | | * |
733 | | * Parse a #GstNavigation message of type GST_NAVIGATION_MESSAGE_ANGLES_CHANGED |
734 | | * and extract the @cur_angle and @n_angles parameters. |
735 | | * |
736 | | * Returns: %TRUE if the message could be successfully parsed. %FALSE if not. |
737 | | */ |
738 | | gboolean |
739 | | gst_navigation_message_parse_angles_changed (GstMessage * message, |
740 | | guint * cur_angle, guint * n_angles) |
741 | 0 | { |
742 | 0 | const GstStructure *s; |
743 | 0 | gboolean ret = TRUE; |
744 | |
|
745 | 0 | g_return_val_if_fail (GST_NAVIGATION_MESSAGE_HAS_TYPE (message, |
746 | 0 | ANGLES_CHANGED), FALSE); |
747 | | |
748 | 0 | s = gst_message_get_structure (message); |
749 | 0 | if (cur_angle) |
750 | 0 | ret &= gst_structure_get_uint (s, "angle", cur_angle); |
751 | |
|
752 | 0 | if (n_angles) |
753 | 0 | ret &= gst_structure_get_uint (s, "angles", n_angles); |
754 | |
|
755 | 0 | WARN_IF_FAIL (ret, "Couldn't extract details from angles-changed event"); |
756 | |
|
757 | 0 | return ret; |
758 | 0 | } |
759 | | |
760 | | #define GST_NAVIGATION_EVENT_HAS_TYPE(event,event_type) \ |
761 | | (gst_navigation_event_get_type (event) == GST_NAVIGATION_EVENT_ ## event_type) |
762 | | |
763 | | /** |
764 | | * gst_navigation_event_get_type: |
765 | | * @event: A #GstEvent to inspect. |
766 | | * |
767 | | * Inspect a #GstEvent and return the #GstNavigationEventType of the event, or |
768 | | * #GST_NAVIGATION_EVENT_INVALID if the event is not a #GstNavigation event. |
769 | | */ |
770 | | GstNavigationEventType |
771 | | gst_navigation_event_get_type (GstEvent * event) |
772 | 0 | { |
773 | 0 | const GstStructure *s; |
774 | 0 | const gchar *e_type; |
775 | |
|
776 | 0 | if (event == NULL || GST_EVENT_TYPE (event) != GST_EVENT_NAVIGATION) |
777 | 0 | return GST_NAVIGATION_EVENT_INVALID; |
778 | | |
779 | 0 | s = gst_event_get_structure (event); |
780 | 0 | if (s == NULL || !gst_structure_has_name (s, GST_NAVIGATION_EVENT_NAME)) |
781 | 0 | return GST_NAVIGATION_EVENT_INVALID; |
782 | | |
783 | 0 | e_type = gst_structure_get_string (s, "event"); |
784 | 0 | if (e_type == NULL) |
785 | 0 | return GST_NAVIGATION_EVENT_INVALID; |
786 | | |
787 | 0 | if (g_str_equal (e_type, "mouse-button-press")) |
788 | 0 | return GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS; |
789 | 0 | else if (g_str_equal (e_type, "mouse-button-release")) |
790 | 0 | return GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE; |
791 | 0 | else if (g_str_equal (e_type, "mouse-move")) |
792 | 0 | return GST_NAVIGATION_EVENT_MOUSE_MOVE; |
793 | 0 | else if (g_str_equal (e_type, "mouse-scroll")) |
794 | 0 | return GST_NAVIGATION_EVENT_MOUSE_SCROLL; |
795 | 0 | else if (g_str_equal (e_type, "key-press")) |
796 | 0 | return GST_NAVIGATION_EVENT_KEY_PRESS; |
797 | 0 | else if (g_str_equal (e_type, "key-release")) |
798 | 0 | return GST_NAVIGATION_EVENT_KEY_RELEASE; |
799 | 0 | else if (g_str_equal (e_type, "command")) |
800 | 0 | return GST_NAVIGATION_EVENT_COMMAND; |
801 | 0 | else if (g_str_equal (e_type, "touch-down")) |
802 | 0 | return GST_NAVIGATION_EVENT_TOUCH_DOWN; |
803 | 0 | else if (g_str_equal (e_type, "touch-up")) |
804 | 0 | return GST_NAVIGATION_EVENT_TOUCH_UP; |
805 | 0 | else if (g_str_equal (e_type, "touch-cancel")) |
806 | 0 | return GST_NAVIGATION_EVENT_TOUCH_CANCEL; |
807 | 0 | else if (g_str_equal (e_type, "touch-motion")) |
808 | 0 | return GST_NAVIGATION_EVENT_TOUCH_MOTION; |
809 | 0 | else if (g_str_equal (e_type, "touch-frame")) |
810 | 0 | return GST_NAVIGATION_EVENT_TOUCH_FRAME; |
811 | 0 | else if (g_str_equal (e_type, "mouse-double-click")) |
812 | 0 | return GST_NAVIGATION_EVENT_MOUSE_DOUBLE_CLICK; |
813 | | |
814 | 0 | return GST_NAVIGATION_EVENT_INVALID; |
815 | 0 | } |
816 | | |
817 | | /** |
818 | | * gst_navigation_event_new_key_press: |
819 | | * @key: A string identifying the key press. |
820 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
821 | | * Shift and Alt). |
822 | | * |
823 | | * Create a new navigation event for the given key press. |
824 | | * |
825 | | * Returns: (transfer full): a new #GstEvent |
826 | | * |
827 | | * Since: 1.22 |
828 | | */ |
829 | | GstEvent * |
830 | | gst_navigation_event_new_key_press (const gchar * key, |
831 | | GstNavigationModifierType state) |
832 | 0 | { |
833 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
834 | 0 | "event", G_TYPE_STRING, "key-press", "key", G_TYPE_STRING, key, |
835 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
836 | 0 | } |
837 | | |
838 | | /** |
839 | | * gst_navigation_event_new_key_release: |
840 | | * @key: A string identifying the released key. |
841 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
842 | | * Shift and Alt). |
843 | | * |
844 | | * Create a new navigation event for the given key release. |
845 | | * |
846 | | * Returns: (transfer full): a new #GstEvent |
847 | | * |
848 | | * Since: 1.22 |
849 | | */ |
850 | | GstEvent * |
851 | | gst_navigation_event_new_key_release (const gchar * key, |
852 | | GstNavigationModifierType state) |
853 | 0 | { |
854 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
855 | 0 | "event", G_TYPE_STRING, "key-release", "key", G_TYPE_STRING, key, |
856 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
857 | 0 | } |
858 | | |
859 | | /** |
860 | | * gst_navigation_event_new_mouse_button_press: |
861 | | * @button: The number of the pressed mouse button. |
862 | | * @x: The x coordinate of the mouse cursor. |
863 | | * @y: The y coordinate of the mouse cursor. |
864 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
865 | | * Shift and Alt). |
866 | | * |
867 | | * Create a new navigation event for the given key mouse button press. |
868 | | * |
869 | | * Returns: (transfer full): a new #GstEvent |
870 | | * |
871 | | * Since: 1.22 |
872 | | */ |
873 | | GstEvent * |
874 | | gst_navigation_event_new_mouse_button_press (gint button, gdouble x, gdouble y, |
875 | | GstNavigationModifierType state) |
876 | 0 | { |
877 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
878 | 0 | "event", G_TYPE_STRING, "mouse-button-press", |
879 | 0 | "button", G_TYPE_INT, button, "pointer_x", G_TYPE_DOUBLE, x, |
880 | 0 | "pointer_y", G_TYPE_DOUBLE, y, |
881 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
882 | 0 | } |
883 | | |
884 | | /** |
885 | | * gst_navigation_event_new_mouse_double_click: |
886 | | * @button: The number of the pressed mouse button. |
887 | | * @x: The x coordinate of the mouse cursor. |
888 | | * @y: The y coordinate of the mouse cursor. |
889 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
890 | | * Shift and Alt). |
891 | | * |
892 | | * Create a new navigation event for the given key mouse double click. |
893 | | * |
894 | | * Returns: (transfer full): a new #GstEvent |
895 | | * |
896 | | * Since: 1.26 |
897 | | */ |
898 | | GstEvent * |
899 | | gst_navigation_event_new_mouse_double_click (gint button, gdouble x, gdouble y, |
900 | | GstNavigationModifierType state) |
901 | 0 | { |
902 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
903 | 0 | "event", G_TYPE_STRING, "mouse-double-click", |
904 | 0 | "button", G_TYPE_INT, button, "pointer_x", G_TYPE_DOUBLE, x, |
905 | 0 | "pointer_y", G_TYPE_DOUBLE, y, |
906 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
907 | 0 | } |
908 | | |
909 | | /** |
910 | | * gst_navigation_event_new_mouse_button_release: |
911 | | * @button: The number of the released mouse button. |
912 | | * @x: The x coordinate of the mouse cursor. |
913 | | * @y: The y coordinate of the mouse cursor. |
914 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
915 | | * Shift and Alt). |
916 | | * |
917 | | * Create a new navigation event for the given key mouse button release. |
918 | | * |
919 | | * Returns: (transfer full): a new #GstEvent |
920 | | * |
921 | | * Since: 1.22 |
922 | | */ |
923 | | GstEvent * |
924 | | gst_navigation_event_new_mouse_button_release (gint button, gdouble x, |
925 | | gdouble y, GstNavigationModifierType state) |
926 | 0 | { |
927 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
928 | 0 | "event", G_TYPE_STRING, "mouse-button-release", |
929 | 0 | "button", G_TYPE_INT, button, "pointer_x", G_TYPE_DOUBLE, x, |
930 | 0 | "pointer_y", G_TYPE_DOUBLE, y, |
931 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
932 | 0 | } |
933 | | |
934 | | /** |
935 | | * gst_navigation_event_new_mouse_move: |
936 | | * @x: The x coordinate of the mouse cursor. |
937 | | * @y: The y coordinate of the mouse cursor. |
938 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
939 | | * Shift and Alt). |
940 | | * |
941 | | * Create a new navigation event for the new mouse location. |
942 | | * |
943 | | * Returns: (transfer full): a new #GstEvent |
944 | | * |
945 | | * Since: 1.22 |
946 | | */ |
947 | | GstEvent * |
948 | | gst_navigation_event_new_mouse_move (gdouble x, gdouble y, |
949 | | GstNavigationModifierType state) |
950 | 0 | { |
951 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
952 | 0 | "event", G_TYPE_STRING, "mouse-move", |
953 | 0 | "pointer_x", G_TYPE_DOUBLE, x, |
954 | 0 | "pointer_y", G_TYPE_DOUBLE, y, |
955 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
956 | 0 | } |
957 | | |
958 | | /** |
959 | | * gst_navigation_event_new_mouse_scroll: |
960 | | * @x: The x coordinate of the mouse cursor. |
961 | | * @y: The y coordinate of the mouse cursor. |
962 | | * @delta_x: The x component of the scroll movement. |
963 | | * @delta_y: The y component of the scroll movement. |
964 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
965 | | * Shift and Alt). |
966 | | * |
967 | | * Create a new navigation event for the mouse scroll. |
968 | | * |
969 | | * Returns: (transfer full): a new #GstEvent |
970 | | * |
971 | | * Since: 1.22 |
972 | | */ |
973 | | GstEvent * |
974 | | gst_navigation_event_new_mouse_scroll (gdouble x, gdouble y, gdouble delta_x, |
975 | | gdouble delta_y, GstNavigationModifierType state) |
976 | 0 | { |
977 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
978 | 0 | "event", G_TYPE_STRING, "mouse-scroll", |
979 | 0 | "pointer_x", G_TYPE_DOUBLE, x, "pointer_y", G_TYPE_DOUBLE, y, |
980 | 0 | "delta_pointer_x", G_TYPE_DOUBLE, delta_x, |
981 | 0 | "delta_pointer_y", G_TYPE_DOUBLE, delta_y, |
982 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
983 | 0 | } |
984 | | |
985 | | /** |
986 | | * gst_navigation_event_new_command: |
987 | | * @command: The navigation command to use. |
988 | | * |
989 | | * Create a new navigation event given navigation command.. |
990 | | * |
991 | | * Returns: (transfer full): a new #GstEvent |
992 | | * |
993 | | * Since: 1.22 |
994 | | */ |
995 | | GstEvent * |
996 | | gst_navigation_event_new_command (GstNavigationCommand command) |
997 | 0 | { |
998 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
999 | 0 | "event", G_TYPE_STRING, "command", |
1000 | 0 | "command-code", G_TYPE_UINT, (guint) command, NULL)); |
1001 | 0 | } |
1002 | | |
1003 | | /** |
1004 | | * gst_navigation_event_new_touch_down: |
1005 | | * @identifier: A number uniquely identifying this touch point. It must stay |
1006 | | * unique to this touch point at least until an up event is sent for |
1007 | | * the same identifier, or all touch points are cancelled. |
1008 | | * @x: The x coordinate of the new touch point. |
1009 | | * @y: The y coordinate of the new touch point. |
1010 | | * @pressure: Pressure data of the touch point, from 0.0 to 1.0, or NaN if no |
1011 | | * data is available. |
1012 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
1013 | | * Shift and Alt). |
1014 | | * |
1015 | | * Create a new navigation event for an added touch point. |
1016 | | * |
1017 | | * Returns: (transfer full): a new #GstEvent |
1018 | | * |
1019 | | * Since: 1.22 |
1020 | | */ |
1021 | | GstEvent * |
1022 | | gst_navigation_event_new_touch_down (guint identifier, gdouble x, gdouble y, |
1023 | | gdouble pressure, GstNavigationModifierType state) |
1024 | 0 | { |
1025 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
1026 | 0 | "event", G_TYPE_STRING, "touch-down", |
1027 | 0 | "identifier", G_TYPE_UINT, identifier, |
1028 | 0 | "pointer_x", G_TYPE_DOUBLE, x, |
1029 | 0 | "pointer_y", G_TYPE_DOUBLE, y, |
1030 | 0 | "pressure", G_TYPE_DOUBLE, pressure, |
1031 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
1032 | 0 | } |
1033 | | |
1034 | | /** |
1035 | | * gst_navigation_event_new_touch_motion: |
1036 | | * @identifier: A number uniquely identifying this touch point. It must |
1037 | | * correlate to exactly one previous touch_start event. |
1038 | | * @x: The x coordinate of the touch point. |
1039 | | * @y: The y coordinate of the touch point. |
1040 | | * @pressure: Pressure data of the touch point, from 0.0 to 1.0, or NaN if no |
1041 | | * data is available. |
1042 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
1043 | | * Shift and Alt). |
1044 | | * |
1045 | | * Create a new navigation event for a moved touch point. |
1046 | | * |
1047 | | * Returns: (transfer full): a new #GstEvent |
1048 | | * |
1049 | | * Since: 1.22 |
1050 | | */ |
1051 | | GstEvent * |
1052 | | gst_navigation_event_new_touch_motion (guint identifier, gdouble x, gdouble y, |
1053 | | gdouble pressure, GstNavigationModifierType state) |
1054 | 0 | { |
1055 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
1056 | 0 | "event", G_TYPE_STRING, "touch-motion", |
1057 | 0 | "identifier", G_TYPE_UINT, identifier, |
1058 | 0 | "pointer_x", G_TYPE_DOUBLE, x, |
1059 | 0 | "pointer_y", G_TYPE_DOUBLE, y, |
1060 | 0 | "pressure", G_TYPE_DOUBLE, pressure, |
1061 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
1062 | 0 | } |
1063 | | |
1064 | | /** |
1065 | | * gst_navigation_event_new_touch_up: |
1066 | | * @identifier: A number uniquely identifying this touch point. It must |
1067 | | * correlate to exactly one previous down event, but can be reused |
1068 | | * after sending this event. |
1069 | | * @x: The x coordinate of the touch point. |
1070 | | * @y: The y coordinate of the touch point. |
1071 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
1072 | | * Shift and Alt). |
1073 | | * |
1074 | | * Create a new navigation event for a removed touch point. |
1075 | | * |
1076 | | * Returns: (transfer full): a new #GstEvent |
1077 | | * |
1078 | | * Since: 1.22 |
1079 | | */ |
1080 | | GstEvent * |
1081 | | gst_navigation_event_new_touch_up (guint identifier, gdouble x, gdouble y, |
1082 | | GstNavigationModifierType state) |
1083 | 0 | { |
1084 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
1085 | 0 | "event", G_TYPE_STRING, "touch-up", |
1086 | 0 | "identifier", G_TYPE_UINT, identifier, |
1087 | 0 | "pointer_x", G_TYPE_DOUBLE, x, "pointer_y", G_TYPE_DOUBLE, y, |
1088 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
1089 | 0 | } |
1090 | | |
1091 | | /** |
1092 | | * gst_navigation_event_new_touch_frame: |
1093 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
1094 | | * Shift and Alt). |
1095 | | * |
1096 | | * Create a new navigation event signalling the end of a touch frame. Touch |
1097 | | * frames signal that all previous down, motion and up events not followed by |
1098 | | * another touch frame event already should be considered simultaneous. |
1099 | | * |
1100 | | * Returns: (transfer full): a new #GstEvent |
1101 | | * |
1102 | | * Since: 1.22 |
1103 | | */ |
1104 | | GstEvent * |
1105 | | gst_navigation_event_new_touch_frame (GstNavigationModifierType state) |
1106 | 0 | { |
1107 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
1108 | 0 | "event", G_TYPE_STRING, "touch-frame", |
1109 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
1110 | 0 | } |
1111 | | |
1112 | | |
1113 | | /** |
1114 | | * gst_navigation_event_new_touch_cancel: |
1115 | | * @state: a bit-mask representing the state of the modifier keys (e.g. Control, |
1116 | | * Shift and Alt). |
1117 | | * |
1118 | | * Create a new navigation event signalling that all currently active touch |
1119 | | * points are cancelled and should be discarded. For example, under Wayland |
1120 | | * this event might be sent when a swipe passes the threshold to be recognized |
1121 | | * as a gesture by the compositor. |
1122 | | * |
1123 | | * Returns: (transfer full): a new #GstEvent |
1124 | | * |
1125 | | * Since: 1.22 |
1126 | | */ |
1127 | | GstEvent * |
1128 | | gst_navigation_event_new_touch_cancel (GstNavigationModifierType state) |
1129 | 0 | { |
1130 | 0 | return gst_event_new_navigation (gst_structure_new (GST_NAVIGATION_EVENT_NAME, |
1131 | 0 | "event", G_TYPE_STRING, "touch-cancel", |
1132 | 0 | "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, NULL)); |
1133 | 0 | } |
1134 | | |
1135 | | /** |
1136 | | * gst_navigation_event_parse_key_event: |
1137 | | * @event: A #GstEvent to inspect. |
1138 | | * @key: (out) (optional) (transfer none): A pointer to a location to receive |
1139 | | * the string identifying the key press. The returned string is owned by the |
1140 | | * event, and valid only until the event is unreffed. |
1141 | | * |
1142 | | * Note: Modifier keys (as defined in #GstNavigationModifierType) |
1143 | | * [press](GST_NAVIGATION_EVENT_KEY_PRESS) and |
1144 | | * [release](GST_NAVIGATION_KEY_PRESS) events are generated even if those states are |
1145 | | * present on all other related events |
1146 | | */ |
1147 | | gboolean |
1148 | | gst_navigation_event_parse_key_event (GstEvent * event, const gchar ** key) |
1149 | 0 | { |
1150 | 0 | GstNavigationEventType e_type GST_UNUSED_CHECKS; |
1151 | 0 | const GstStructure *s; |
1152 | |
|
1153 | 0 | #ifndef G_DISABLE_CHECKS |
1154 | 0 | e_type = gst_navigation_event_get_type (event); |
1155 | 0 | g_return_val_if_fail (e_type == GST_NAVIGATION_EVENT_KEY_PRESS || |
1156 | 0 | e_type == GST_NAVIGATION_EVENT_KEY_RELEASE, FALSE); |
1157 | 0 | #endif |
1158 | | |
1159 | 0 | if (key) { |
1160 | 0 | s = gst_event_get_structure (event); |
1161 | 0 | *key = gst_structure_get_string (s, "key"); |
1162 | 0 | if (*key == NULL) |
1163 | 0 | return FALSE; |
1164 | 0 | } |
1165 | | |
1166 | 0 | return TRUE; |
1167 | 0 | } |
1168 | | |
1169 | | /** |
1170 | | * gst_navigation_event_parse_mouse_button_event: |
1171 | | * @event: A #GstEvent to inspect. |
1172 | | * @button: (out) (optional): Pointer to a gint that will receive the button |
1173 | | * number associated with the event. |
1174 | | * @x: (out) (optional): Pointer to a gdouble to receive the x coordinate of the |
1175 | | * mouse button event. |
1176 | | * @y: (out) (optional): Pointer to a gdouble to receive the y coordinate of the |
1177 | | * mouse button event. |
1178 | | * |
1179 | | * Retrieve the details of either a #GstNavigation mouse button press event or |
1180 | | * a mouse button release event. Determine which type the event is using |
1181 | | * gst_navigation_event_get_type() to retrieve the #GstNavigationEventType. |
1182 | | * |
1183 | | * Returns: TRUE if the button number and both coordinates could be extracted, |
1184 | | * otherwise FALSE. |
1185 | | */ |
1186 | | gboolean |
1187 | | gst_navigation_event_parse_mouse_button_event (GstEvent * event, gint * button, |
1188 | | gdouble * x, gdouble * y) |
1189 | 0 | { |
1190 | 0 | GstNavigationEventType e_type GST_UNUSED_CHECKS; |
1191 | 0 | const GstStructure *s; |
1192 | 0 | gboolean ret = TRUE; |
1193 | |
|
1194 | 0 | #ifndef G_DISABLE_CHECKS |
1195 | 0 | e_type = gst_navigation_event_get_type (event); |
1196 | 0 | g_return_val_if_fail (e_type == GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS || |
1197 | 0 | e_type == GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE || |
1198 | 0 | e_type == GST_NAVIGATION_EVENT_MOUSE_DOUBLE_CLICK, FALSE); |
1199 | 0 | #endif |
1200 | | |
1201 | 0 | s = gst_event_get_structure (event); |
1202 | 0 | if (x) |
1203 | 0 | ret &= gst_structure_get_double (s, "pointer_x", x); |
1204 | 0 | if (y) |
1205 | 0 | ret &= gst_structure_get_double (s, "pointer_y", y); |
1206 | 0 | if (button) |
1207 | 0 | ret &= gst_structure_get_int (s, "button", button); |
1208 | |
|
1209 | 0 | WARN_IF_FAIL (ret, "Couldn't extract details from mouse button event"); |
1210 | |
|
1211 | 0 | return ret; |
1212 | 0 | } |
1213 | | |
1214 | | /** |
1215 | | * gst_navigation_event_parse_mouse_move_event: |
1216 | | * @event: A #GstEvent to inspect. |
1217 | | * @x: (out) (optional): Pointer to a gdouble to receive the x coordinate of the |
1218 | | * mouse movement. |
1219 | | * @y: (out) (optional): Pointer to a gdouble to receive the y coordinate of the |
1220 | | * mouse movement. |
1221 | | * |
1222 | | * Inspect a #GstNavigation mouse movement event and extract the coordinates |
1223 | | * of the event. |
1224 | | * |
1225 | | * Returns: TRUE if both coordinates could be extracted, otherwise FALSE. |
1226 | | */ |
1227 | | gboolean |
1228 | | gst_navigation_event_parse_mouse_move_event (GstEvent * event, gdouble * x, |
1229 | | gdouble * y) |
1230 | 0 | { |
1231 | 0 | const GstStructure *s; |
1232 | 0 | gboolean ret = TRUE; |
1233 | |
|
1234 | 0 | g_return_val_if_fail (GST_NAVIGATION_EVENT_HAS_TYPE (event, MOUSE_MOVE), |
1235 | 0 | FALSE); |
1236 | | |
1237 | 0 | s = gst_event_get_structure (event); |
1238 | 0 | if (x) |
1239 | 0 | ret &= gst_structure_get_double (s, "pointer_x", x); |
1240 | 0 | if (y) |
1241 | 0 | ret &= gst_structure_get_double (s, "pointer_y", y); |
1242 | |
|
1243 | 0 | WARN_IF_FAIL (ret, "Couldn't extract positions from mouse move event"); |
1244 | |
|
1245 | 0 | return ret; |
1246 | 0 | } |
1247 | | |
1248 | | /** |
1249 | | * gst_navigation_event_parse_mouse_scroll_event: |
1250 | | * @event: A #GstEvent to inspect. |
1251 | | * @x: (out) (optional): Pointer to a gdouble to receive the x coordinate of the |
1252 | | * mouse movement. |
1253 | | * @y: (out) (optional): Pointer to a gdouble to receive the y coordinate of the |
1254 | | * mouse movement. |
1255 | | * @delta_x: (out) (optional): Pointer to a gdouble to receive the delta_x coordinate of the |
1256 | | * mouse movement. |
1257 | | * @delta_y: (out) (optional): Pointer to a gdouble to receive the delta_y coordinate of the |
1258 | | * mouse movement. |
1259 | | * |
1260 | | * Inspect a #GstNavigation mouse scroll event and extract the coordinates |
1261 | | * of the event. |
1262 | | * |
1263 | | * Returns: TRUE if all coordinates could be extracted, otherwise FALSE. |
1264 | | * |
1265 | | * Since: 1.18 |
1266 | | */ |
1267 | | gboolean |
1268 | | gst_navigation_event_parse_mouse_scroll_event (GstEvent * event, |
1269 | | gdouble * x, gdouble * y, gdouble * delta_x, gdouble * delta_y) |
1270 | 0 | { |
1271 | 0 | const GstStructure *s; |
1272 | 0 | gboolean ret = TRUE; |
1273 | |
|
1274 | 0 | g_return_val_if_fail (GST_NAVIGATION_EVENT_HAS_TYPE (event, MOUSE_SCROLL), |
1275 | 0 | FALSE); |
1276 | | |
1277 | 0 | s = gst_event_get_structure (event); |
1278 | 0 | if (x) |
1279 | 0 | ret &= gst_structure_get_double (s, "pointer_x", x); |
1280 | 0 | if (y) |
1281 | 0 | ret &= gst_structure_get_double (s, "pointer_y", y); |
1282 | 0 | if (delta_x) |
1283 | 0 | ret &= gst_structure_get_double (s, "delta_pointer_x", delta_x); |
1284 | 0 | if (delta_y) |
1285 | 0 | ret &= gst_structure_get_double (s, "delta_pointer_y", delta_y); |
1286 | |
|
1287 | 0 | WARN_IF_FAIL (ret, "Couldn't extract positions from mouse scroll event"); |
1288 | |
|
1289 | 0 | return ret; |
1290 | 0 | } |
1291 | | |
1292 | | /** |
1293 | | * gst_navigation_event_parse_command: |
1294 | | * @event: A #GstEvent to inspect. |
1295 | | * @command: (out) (optional): Pointer to GstNavigationCommand to receive the |
1296 | | * type of the navigation event. |
1297 | | * |
1298 | | * Inspect a #GstNavigation command event and retrieve the enum value of the |
1299 | | * associated command. |
1300 | | * |
1301 | | * Returns: TRUE if the navigation command could be extracted, otherwise FALSE. |
1302 | | */ |
1303 | | gboolean |
1304 | | gst_navigation_event_parse_command (GstEvent * event, |
1305 | | GstNavigationCommand * command) |
1306 | 0 | { |
1307 | 0 | const GstStructure *s; |
1308 | 0 | gboolean ret = TRUE; |
1309 | |
|
1310 | 0 | g_return_val_if_fail (GST_NAVIGATION_EVENT_HAS_TYPE (event, COMMAND), FALSE); |
1311 | | |
1312 | 0 | if (command) { |
1313 | 0 | s = gst_event_get_structure (event); |
1314 | 0 | ret = gst_structure_get_uint (s, "command-code", (guint *) command); |
1315 | 0 | WARN_IF_FAIL (ret, "Couldn't extract command code from command event"); |
1316 | 0 | } |
1317 | |
|
1318 | 0 | return ret; |
1319 | 0 | } |
1320 | | |
1321 | | /** |
1322 | | * gst_navigation_event_parse_touch_event: |
1323 | | * @event: A #GstEvent to inspect. |
1324 | | * @identifier: (out) (optional): Pointer to a guint that will receive the |
1325 | | * identifier unique to this touch point. |
1326 | | * @x: (out) (optional): Pointer to a gdouble that will receive the x |
1327 | | * coordinate of the touch event. |
1328 | | * @y: (out) (optional): Pointer to a gdouble that will receive the y |
1329 | | * coordinate of the touch event. |
1330 | | * @pressure: (out) (optional): Pointer to a gdouble that will receive the |
1331 | | * force of the touch event, in the range from 0.0 to 1.0. If pressure |
1332 | | * data is not available, NaN will be set instead. |
1333 | | * |
1334 | | * Retrieve the details of a #GstNavigation touch-down or touch-motion event. |
1335 | | * Determine which type the event is using gst_navigation_event_get_type() |
1336 | | * to retrieve the #GstNavigationEventType. |
1337 | | * |
1338 | | * Returns: TRUE if all details could be extracted, otherwise FALSE. |
1339 | | * |
1340 | | * Since: 1.22 |
1341 | | */ |
1342 | | gboolean |
1343 | | gst_navigation_event_parse_touch_event (GstEvent * event, guint * identifier, |
1344 | | gdouble * x, gdouble * y, gdouble * pressure) |
1345 | 0 | { |
1346 | 0 | GstNavigationEventType e_type GST_UNUSED_CHECKS; |
1347 | 0 | const GstStructure *s; |
1348 | 0 | gboolean ret = TRUE; |
1349 | |
|
1350 | 0 | #ifndef G_DISABLE_CHECKS |
1351 | 0 | e_type = gst_navigation_event_get_type (event); |
1352 | 0 | g_return_val_if_fail (e_type == GST_NAVIGATION_EVENT_TOUCH_DOWN || |
1353 | 0 | e_type == GST_NAVIGATION_EVENT_TOUCH_MOTION, FALSE); |
1354 | 0 | #endif |
1355 | | |
1356 | 0 | s = gst_event_get_structure (event); |
1357 | 0 | if (identifier) |
1358 | 0 | ret &= gst_structure_get_uint (s, "identifier", identifier); |
1359 | 0 | if (x) |
1360 | 0 | ret &= gst_structure_get_double (s, "pointer_x", x); |
1361 | 0 | if (y) |
1362 | 0 | ret &= gst_structure_get_double (s, "pointer_y", y); |
1363 | 0 | if (pressure) |
1364 | 0 | ret &= gst_structure_get_double (s, "pressure", pressure); |
1365 | |
|
1366 | 0 | WARN_IF_FAIL (ret, "Couldn't extract details from touch event"); |
1367 | |
|
1368 | 0 | return ret; |
1369 | 0 | } |
1370 | | |
1371 | | /** |
1372 | | * gst_navigation_event_parse_touch_up_event: |
1373 | | * @event: A #GstEvent to inspect. |
1374 | | * @identifier: (out) (optional): Pointer to a guint that will receive the |
1375 | | * identifier unique to this touch point. |
1376 | | * @x: (out) (optional): Pointer to a gdouble that will receive the x |
1377 | | * coordinate of the touch event. |
1378 | | * @y: (out) (optional): Pointer to a gdouble that will receive the y |
1379 | | * coordinate of the touch event. |
1380 | | * |
1381 | | * Retrieve the details of a #GstNavigation touch-up event. |
1382 | | * |
1383 | | * Returns: TRUE if all details could be extracted, otherwise FALSE. |
1384 | | * |
1385 | | * Since: 1.22 |
1386 | | */ |
1387 | | gboolean |
1388 | | gst_navigation_event_parse_touch_up_event (GstEvent * event, |
1389 | | guint * identifier, gdouble * x, gdouble * y) |
1390 | 0 | { |
1391 | 0 | const GstStructure *s; |
1392 | 0 | gboolean ret = TRUE; |
1393 | |
|
1394 | 0 | g_return_val_if_fail (GST_NAVIGATION_EVENT_HAS_TYPE (event, TOUCH_UP), FALSE); |
1395 | | |
1396 | 0 | s = gst_event_get_structure (event); |
1397 | 0 | if (identifier) |
1398 | 0 | ret &= gst_structure_get_uint (s, "identifier", identifier); |
1399 | 0 | if (x) |
1400 | 0 | ret &= gst_structure_get_double (s, "pointer_x", x); |
1401 | 0 | if (y) |
1402 | 0 | ret &= gst_structure_get_double (s, "pointer_y", y); |
1403 | |
|
1404 | 0 | WARN_IF_FAIL (ret, "Couldn't extract details from touch-up event"); |
1405 | |
|
1406 | 0 | return ret; |
1407 | 0 | } |
1408 | | |
1409 | | /** |
1410 | | * gst_navigation_event_get_coordinates: |
1411 | | * @event: The #GstEvent to inspect. |
1412 | | * @x: (out) (optional): Pointer to a gdouble to receive the x coordinate of the |
1413 | | * navigation event. |
1414 | | * @y: (out) (optional): Pointer to a gdouble to receive the y coordinate of the |
1415 | | * navigation event. |
1416 | | * |
1417 | | * Try to retrieve x and y coordinates of a #GstNavigation event. |
1418 | | * |
1419 | | * Returns: A boolean indicating success. |
1420 | | * |
1421 | | * Since: 1.22 |
1422 | | */ |
1423 | | gboolean |
1424 | | gst_navigation_event_get_coordinates (GstEvent * event, |
1425 | | gdouble * x, gdouble * y) |
1426 | 0 | { |
1427 | 0 | GstNavigationEventType e_type; |
1428 | 0 | const GstStructure *s; |
1429 | 0 | gboolean ret = TRUE; |
1430 | |
|
1431 | 0 | e_type = gst_navigation_event_get_type (event); |
1432 | 0 | if (e_type != GST_NAVIGATION_EVENT_MOUSE_MOVE |
1433 | 0 | && e_type != GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS |
1434 | 0 | && e_type != GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE |
1435 | 0 | && e_type != GST_NAVIGATION_EVENT_TOUCH_DOWN |
1436 | 0 | && e_type != GST_NAVIGATION_EVENT_TOUCH_MOTION |
1437 | 0 | && e_type != GST_NAVIGATION_EVENT_TOUCH_UP) { |
1438 | 0 | return FALSE; |
1439 | 0 | } |
1440 | | |
1441 | 0 | s = gst_event_get_structure (event); |
1442 | 0 | if (x) |
1443 | 0 | ret &= gst_structure_get_double (s, "pointer_x", x); |
1444 | 0 | if (y) |
1445 | 0 | ret &= gst_structure_get_double (s, "pointer_y", y); |
1446 | |
|
1447 | 0 | WARN_IF_FAIL (ret, "Couldn't extract coordinates from the event"); |
1448 | |
|
1449 | 0 | return ret; |
1450 | 0 | } |
1451 | | |
1452 | | /** |
1453 | | * gst_navigation_event_set_coordinates: |
1454 | | * @event: The #GstEvent to modify. |
1455 | | * @x: The x coordinate to set. |
1456 | | * @y: The y coordinate to set. |
1457 | | * |
1458 | | * Try to set x and y coordinates on a #GstNavigation event. The event must |
1459 | | * be writable. |
1460 | | * |
1461 | | * Returns: A boolean indicating success. |
1462 | | * |
1463 | | * Since: 1.22 |
1464 | | */ |
1465 | | gboolean |
1466 | | gst_navigation_event_set_coordinates (GstEvent * event, gdouble x, gdouble y) |
1467 | 0 | { |
1468 | 0 | GstNavigationEventType e_type; |
1469 | 0 | GstStructure *s; |
1470 | |
|
1471 | 0 | g_return_val_if_fail (gst_event_is_writable (event), FALSE); |
1472 | | |
1473 | 0 | e_type = gst_navigation_event_get_type (event); |
1474 | 0 | if (e_type != GST_NAVIGATION_EVENT_MOUSE_MOVE |
1475 | 0 | && e_type != GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS |
1476 | 0 | && e_type != GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE |
1477 | 0 | && e_type != GST_NAVIGATION_EVENT_TOUCH_DOWN |
1478 | 0 | && e_type != GST_NAVIGATION_EVENT_TOUCH_MOTION |
1479 | 0 | && e_type != GST_NAVIGATION_EVENT_TOUCH_UP) { |
1480 | 0 | return FALSE; |
1481 | 0 | } |
1482 | | |
1483 | 0 | s = gst_event_writable_structure (event); |
1484 | 0 | gst_structure_set (s, "pointer_x", G_TYPE_DOUBLE, x, |
1485 | 0 | "pointer_y", G_TYPE_DOUBLE, y, NULL); |
1486 | |
|
1487 | 0 | return TRUE; |
1488 | 0 | } |
1489 | | |
1490 | | |
1491 | | /** |
1492 | | * gst_navigation_event_parse_modifier_state: |
1493 | | * @event: The #GstEvent to modify. |
1494 | | * @state: (out): a bit-mask representing the state of the modifier keys (e.g. Control, |
1495 | | * Shift and Alt). |
1496 | | * |
1497 | | * Returns: TRUE if the event is a #GstNavigation event with associated |
1498 | | * modifiers state, otherwise FALSE. |
1499 | | * |
1500 | | * Since: 1.22 |
1501 | | */ |
1502 | | gboolean |
1503 | | gst_navigation_event_parse_modifier_state (GstEvent * event, |
1504 | | GstNavigationModifierType * state) |
1505 | 0 | { |
1506 | 0 | GstNavigationEventType e_type; |
1507 | 0 | const GstStructure *s; |
1508 | |
|
1509 | 0 | g_return_val_if_fail (GST_IS_EVENT (event), FALSE); |
1510 | | |
1511 | 0 | e_type = gst_navigation_event_get_type (event); |
1512 | 0 | if (e_type == GST_NAVIGATION_EVENT_COMMAND) { |
1513 | 0 | return FALSE; |
1514 | 0 | } |
1515 | | |
1516 | 0 | s = gst_event_get_structure (event); |
1517 | 0 | if (!gst_structure_get (s, "state", GST_TYPE_NAVIGATION_MODIFIER_TYPE, state, |
1518 | 0 | NULL)) |
1519 | 0 | *state = GST_NAVIGATION_MODIFIER_NONE; |
1520 | |
|
1521 | 0 | return TRUE; |
1522 | 0 | } |