Commit 033e6541 authored by Jan Schmidt's avatar Jan Schmidt

navigation: Extend the navigation interface

Add support for a set of standard commands that can be queried and executed to
support applications like DVD. Add query construction and parsing functions.
Add new messages that can be sent on the bus to provide notifications related
to commands, multiangle changes, and button highlight activity.
Add some helper functions to parse the existing GstNavigation events that
elements might receive.
Document it all and add unit tests.
parent c2a56e31
......@@ -506,16 +506,50 @@ gst_mixer_track_get_type
<INCLUDE>gst/interfaces/navigation.h</INCLUDE>
GstNavigation
GstNavigationInterface
GstNavigationCommand
GstNavigationMessageType
GstNavigationQueryType
gst_navigation_send_event
gst_navigation_send_key_event
gst_navigation_send_mouse_event
gst_navigation_send_command
gst_navigation_message_get_type
gst_navigation_message_new_angles_changed
gst_navigation_message_new_commands_changed
gst_navigation_message_new_mouse_over
gst_navigation_message_parse_mouse_over
gst_navigation_query_new_angles
gst_navigation_query_get_type
gst_navigation_query_new_commands
gst_navigation_query_parse_angles
gst_navigation_query_parse_commands_length
gst_navigation_query_parse_commands_nth
gst_navigation_query_set_angles
gst_navigation_query_set_commands
gst_navigation_query_set_commandsv
GST_NAVIGATION_COMMAND_DVD_ANGLE_MENU
GST_NAVIGATION_COMMAND_DVD_AUDIO_MENU
GST_NAVIGATION_COMMAND_DVD_CHAPTER_MENU
GST_NAVIGATION_COMMAND_DVD_MENU
GST_NAVIGATION_COMMAND_DVD_ROOT_MENU
GST_NAVIGATION_COMMAND_DVD_SUBPICTURE_MENU
GST_NAVIGATION_COMMAND_DVD_TITLE_MENU
<SUBSECTION Standard>
GST_TYPE_NAVIGATION
GST_NAVIGATION
GST_NAVIGATION_GET_IFACE
GST_TYPE_NAVIGATION_COMMAND
GST_TYPE_NAVIGATION_MESSAGE_TYPE
GST_TYPE_NAVIGATION_QUERY_TYPE
GST_IS_NAVIGATION
gst_navigation_get_type
gst_navigation_message_type_get_type
gst_navigation_query_type_get_type
gst_navigation_command_get_type
</SECTION>
<SECTION>
......
This diff is collapsed.
......@@ -49,13 +49,207 @@ typedef struct _GstNavigationInterface {
GType gst_navigation_get_type (void);
/* virtual class function wrappers */
void gst_navigation_send_event (GstNavigation *navigation, GstStructure *structure);
/* Navigation commands */
/**
* GstNavigationCommand:
* @GST_NAVIGATION_COMMAND_INVALID: An invalid command entry
* @GST_NAVIGATION_COMMAND_MENU1: Execute navigation menu command 1. For DVD,
* this enters the DVD root menu, or exits back to the title from the menu.
* @GST_NAVIGATION_COMMAND_MENU2: Execute navigation menu command 2. For DVD,
* this jumps to the DVD title menu.
* @GST_NAVIGATION_COMMAND_MENU3: Execute navigation menu command 3. For DVD,
* this jumps into the DVD root menu.
* @GST_NAVIGATION_COMMAND_MENU4: Execute navigation menu command 4. For DVD,
* this jumps to the Subpicture menu.
* @GST_NAVIGATION_COMMAND_MENU5: Execute navigation menu command 5. For DVD,
* the jumps to the audio menu.
* @GST_NAVIGATION_COMMAND_MENU6: Execute navigation menu command 6. For DVD,
* this jumps to the angles menu.
* @GST_NAVIGATION_COMMAND_MENU7: Execute navigation menu command 7. For DVD,
* this jumps to the chapter menu.
* @GST_NAVIGATION_COMMAND_LEFT: Select the next button to the left in a menu,
* if such a button exists.
* @GST_NAVIGATION_COMMAND_RIGHT: Select the next button to the right in a menu,
* if such a button exists.
* @GST_NAVIGATION_COMMAND_UP: Select the button above the current one in a
* menu, if such a button exists.
* @GST_NAVIGATION_COMMAND_DOWN: Select the button below the current one in a
* menu, if such a button exists.
* @GST_NAVIGATION_COMMAND_ACTIVATE: Activate (click) the currently selected
* button in a menu, if such a button exists.
* @GST_NAVIGATION_COMMAND_PREV_ANGLE: Switch to the previous angle in a
* multiangle feature.
* @GST_NAVIGATION_COMMAND_NEXT_ANGLE: Switch to the next angle in a multiangle
* feature.
*
* A set of commands that may be issued to an element providing the
* #GstNavigation interface. The available commands can be queried via
* the gst_navigation_query_new_commands() query.
*
* For convenience in handling DVD navigation, the MENU commands are aliased as:
* GST_NAVIGATION_COMMAND_DVD_MENU = @GST_NAVIGATION_COMMAND_MENU1
* GST_NAVIGATION_COMMAND_DVD_TITLE_MENU = @GST_NAVIGATION_COMMAND_MENU2
* GST_NAVIGATION_COMMAND_DVD_ROOT_MENU = @GST_NAVIGATION_COMMAND_MENU3
* GST_NAVIGATION_COMMAND_DVD_SUBPICTURE_MENU = @GST_NAVIGATION_COMMAND_MENU4
* GST_NAVIGATION_COMMAND_DVD_AUDIO_MENU = @GST_NAVIGATION_COMMAND_MENU5
* GST_NAVIGATION_COMMAND_DVD_ANGLE_MENU = @GST_NAVIGATION_COMMAND_MENU6
* GST_NAVIGATION_COMMAND_DVD_CHAPTER_MENU = @GST_NAVIGATION_COMMAND_MENU7
*
* Since: 0.10.23
*/
typedef enum {
GST_NAVIGATION_COMMAND_INVALID = 0,
GST_NAVIGATION_COMMAND_MENU1 = 1,
GST_NAVIGATION_COMMAND_MENU2 = 2,
GST_NAVIGATION_COMMAND_MENU3 = 3,
GST_NAVIGATION_COMMAND_MENU4 = 4,
GST_NAVIGATION_COMMAND_MENU5 = 5,
GST_NAVIGATION_COMMAND_MENU6 = 6,
GST_NAVIGATION_COMMAND_MENU7 = 7,
GST_NAVIGATION_COMMAND_LEFT = 20,
GST_NAVIGATION_COMMAND_RIGHT = 21,
GST_NAVIGATION_COMMAND_UP = 22,
GST_NAVIGATION_COMMAND_DOWN = 23,
GST_NAVIGATION_COMMAND_ACTIVATE = 24,
GST_NAVIGATION_COMMAND_PREV_ANGLE = 30,
GST_NAVIGATION_COMMAND_NEXT_ANGLE = 31
} GstNavigationCommand;
/* Some aliases for the menu command types */
#define GST_NAVIGATION_COMMAND_DVD_MENU GST_NAVIGATION_COMMAND_MENU1
#define GST_NAVIGATION_COMMAND_DVD_TITLE_MENU GST_NAVIGATION_COMMAND_MENU2
#define GST_NAVIGATION_COMMAND_DVD_ROOT_MENU GST_NAVIGATION_COMMAND_MENU3
#define GST_NAVIGATION_COMMAND_DVD_SUBPICTURE_MENU GST_NAVIGATION_COMMAND_MENU4
#define GST_NAVIGATION_COMMAND_DVD_AUDIO_MENU GST_NAVIGATION_COMMAND_MENU5
#define GST_NAVIGATION_COMMAND_DVD_ANGLE_MENU GST_NAVIGATION_COMMAND_MENU6
#define GST_NAVIGATION_COMMAND_DVD_CHAPTER_MENU GST_NAVIGATION_COMMAND_MENU7
/* Queries */
typedef enum
{
GST_NAVIGATION_QUERY_INVALID = 0,
GST_NAVIGATION_QUERY_COMMANDS = 1,
GST_NAVIGATION_QUERY_ANGLES = 2
} GstNavigationQueryType;
GstNavigationQueryType gst_navigation_query_get_type (GstQuery *query);
GstQuery *gst_navigation_query_new_commands (void);
void gst_navigation_query_set_commands (GstQuery *query, gint n_cmds, ...);
void gst_navigation_query_set_commandsv (GstQuery *query, gint n_cmds,
GstNavigationCommand *cmds);
gboolean gst_navigation_query_parse_commands_length (GstQuery *query,
guint *n_cmds);
gboolean gst_navigation_query_parse_commands_nth (GstQuery *query, guint nth,
GstNavigationCommand *cmd);
GstQuery *gst_navigation_query_new_angles (void);
void gst_navigation_query_set_angles (GstQuery *query, guint cur_angle,
guint n_angles);
gboolean gst_navigation_query_parse_angles (GstQuery *query, guint *cur_angle,
guint *n_angles);
/* Element messages */
/**
* GstNavigationMessageType:
* @GST_NAVIGATION_MESSAGE_INVALID: Returned from
* gst_navigation_message_get_type() when the passed message is not a
* navigation message.
* @GST_NAVIGATION_MESSAGE_MOUSE_OVER: Sent when the mouse moves over or leaves a
* clickable region of the output, such as a DVD menu button.
* @GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED: Sent when the set of available commands
* changes and should re-queried by interested applications.
* @GST_NAVIGATION_MESSAGE_ANGLES_CHANGED: Sent when display angles in a multi-angle
* feature (such as a multiangle DVD) change - either angles have appeared or
* disappeared.
*
* A set of notifications that may be received on the bus when navigation
* related status changes.
*
* Since: 0.10.23
*/
typedef enum {
GST_NAVIGATION_MESSAGE_INVALID,
GST_NAVIGATION_MESSAGE_MOUSE_OVER,
GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED,
GST_NAVIGATION_MESSAGE_ANGLES_CHANGED
} GstNavigationMessageType;
GstNavigationMessageType gst_navigation_message_get_type (GstMessage *message);
GstMessage *gst_navigation_message_new_mouse_over (GstObject *src,
gboolean active);
gboolean gst_navigation_message_parse_mouse_over (GstMessage *message,
gboolean *active);
GstMessage *gst_navigation_message_new_commands_changed (GstObject *src);
GstMessage *gst_navigation_message_new_angles_changed (GstObject *src,
guint cur_angle,
guint n_angles);
gboolean gst_navigation_message_parse_angles_changed (GstMessage *message,
guint *cur_angle,
guint *n_angles);
/* event parsing functions */
/**
* GstNavigationEventType:
* @GST_NAVIGATION_EVENT_INVALID: Returned from
* gst_navigation_event_get_type() when the passed event is not a navigation event.
* @GST_NAVIGATION_EVENT_KEY_PRESS: A key press event. Use
* gst_navigation_event_parse_key_event() to extract the details from the event.
* @GST_NAVIGATION_EVENT_KEY_RELEASE: A key release event. Use
* gst_navigation_event_parse_key_event() to extract the details from the event.
* @GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS: A mouse button press event. Use
* gst_navigation_event_parse_mouse_button_event() to extract the details from the
* event.
* @GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE: A mouse button release event. Use
* gst_navigation_event_parse_mouse_button_event() to extract the details from the
* event.
* @GST_NAVIGATION_EVENT_MOUSE_MOVE: A mouse movement event. Use
* gst_navigation_event_parse_mouse_move_event() to extract the details from the
* event.
* @GST_NAVIGATION_EVENT_COMMAND: A navigation command event. Use
* gst_navigation_event_parse_command() to extract the details from the event.
*
* Enum values for the various events that an element implementing the
* GstNavigation interface might send up the pipeline.
*
* Since: 0.10.23
*/
typedef enum {
GST_NAVIGATION_EVENT_INVALID = 0,
GST_NAVIGATION_EVENT_KEY_PRESS = 1,
GST_NAVIGATION_EVENT_KEY_RELEASE = 2,
GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS = 3,
GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE = 4,
GST_NAVIGATION_EVENT_MOUSE_MOVE = 5,
GST_NAVIGATION_EVENT_COMMAND = 6
} GstNavigationEventType;
GstNavigationEventType gst_navigation_event_get_type (GstEvent *event);
gboolean gst_navigation_event_parse_key_event (GstEvent *event,
const gchar **key);
gboolean gst_navigation_event_parse_mouse_button_event (GstEvent *event,
gint *button, gdouble *x, gdouble *y);
gboolean gst_navigation_event_parse_mouse_move_event (GstEvent *event,
gdouble *x, gdouble *y);
gboolean gst_navigation_event_parse_command (GstEvent *event,
GstNavigationCommand *command);
/* interface virtual function wrappers */
void gst_navigation_send_event (GstNavigation *navigation,
GstStructure *structure);
void gst_navigation_send_key_event (GstNavigation *navigation,
const char *event, const char *key);
void gst_navigation_send_mouse_event (GstNavigation *navigation,
const char *event, int button, double x, double y);
void gst_navigation_send_command (GstNavigation *navigation,
GstNavigationCommand command);
G_END_DECLS
......
......@@ -112,6 +112,7 @@ check_PROGRAMS = \
libs/cddabasesrc \
libs/fft \
libs/mixer \
libs/navigation \
libs/netbuffer \
libs/pbutils \
libs/rtp \
......@@ -181,6 +182,16 @@ libs_mixer_LDADD = \
$(GST_BASE_LIBS) \
$(LDADD)
libs_navigation_CFLAGS = \
$(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) \
$(AM_CFLAGS)
libs_navigation_LDADD = \
$(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-@GST_MAJORMINOR@.la \
$(GST_BASE_LIBS) \
$(LDADD)
libs_netbuffer_CFLAGS = \
$(GST_PLUGINS_BASE_CFLAGS) \
$(AM_CFLAGS)
......
......@@ -3,6 +3,7 @@ audio
cddabasesrc
fft
mixer
navigation
netbuffer
pbutils
rtp
......
/* GStreamer
*
* unit tests for the navigation interface library
*
* Copyright (C) 2009 Jan Schmidt <thaytan@noraisin.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/check/gstcheck.h>
#include <gst/interfaces/navigation.h>
#include <string.h>
#define TEST_ELEMENT_TYPE (test_element_get_type())
typedef struct TestElement TestElement;
typedef struct TestElementClass TestElementClass;
struct TestElement
{
GstElement parent;
GstNavigationEventType sent_type;
const gchar *sent_key;
gdouble sent_x, sent_y;
gint sent_button;
GstNavigationCommand sent_command;
};
struct TestElementClass
{
GstElementClass parent_class;
};
static void init_interface (GType type);
static void gst_implements_interface_init (GstImplementsInterfaceClass * klass);
static void nav_send_event (GstNavigation * navigation,
GstStructure * structure);
GST_BOILERPLATE_FULL (TestElement, test_element, GstElement, GST_TYPE_ELEMENT,
init_interface);
static void
test_element_navigation_interface_init (GstNavigationInterface * klass)
{
klass->send_event = nav_send_event;
}
static void
init_interface (GType type)
{
static const GInterfaceInfo navigation_iface_info = {
(GInterfaceInitFunc) test_element_navigation_interface_init,
NULL,
NULL,
};
static const GInterfaceInfo implements_iface_info = {
(GInterfaceInitFunc) gst_implements_interface_init,
NULL,
NULL,
};
g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
&implements_iface_info);
g_type_add_interface_static (type, GST_TYPE_NAVIGATION,
&navigation_iface_info);
}
static void
test_element_base_init (gpointer klass)
{
}
static void
test_element_class_init (TestElementClass * klass)
{
}
static gboolean
test_element_interface_supported (GstImplementsInterface * ifacE,
GType interface_type)
{
if (interface_type == GST_TYPE_NAVIGATION)
return TRUE;
return FALSE;
}
static void
gst_implements_interface_init (GstImplementsInterfaceClass * klass)
{
klass->supported = test_element_interface_supported;
}
static void
test_element_init (TestElement * this, TestElementClass * klass)
{
}
static void
nav_send_event (GstNavigation * navigation, GstStructure * structure)
{
GstEvent *event = gst_event_new_navigation (structure);
GstNavigationEventType etype = gst_navigation_event_get_type (event);
TestElement *self = (TestElement *) (navigation);
fail_if (etype == GST_NAVIGATION_EVENT_INVALID,
"Received navigation event could not be parsed");
fail_unless (etype == self->sent_type,
"Received navigation event did not match sent");
switch (etype) {
case GST_NAVIGATION_EVENT_KEY_PRESS:
case GST_NAVIGATION_EVENT_KEY_RELEASE:{
const gchar *key;
fail_unless (gst_navigation_event_parse_key_event (event, &key));
fail_unless (strcmp (key, self->sent_key) == 0);
break;
}
case GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS:
case GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE:{
gint button;
gdouble x, y;
fail_unless (gst_navigation_event_parse_mouse_button_event (event,
&button, &x, &y));
fail_unless (button == self->sent_button);
fail_unless (x == self->sent_x);
fail_unless (y == self->sent_y);
break;
}
case GST_NAVIGATION_EVENT_MOUSE_MOVE:{
gdouble x, y;
fail_unless (gst_navigation_event_parse_mouse_move_event (event, &x, &y));
fail_unless (x == self->sent_x);
fail_unless (y == self->sent_y);
break;
}
case GST_NAVIGATION_EVENT_COMMAND:{
GstNavigationCommand cmd;
fail_unless (gst_navigation_event_parse_command (event, &cmd));
fail_unless (cmd == self->sent_command);
}
default:
break;
}
gst_event_unref (event);
}
GST_START_TEST (test_events)
{
/* Create an empty GstElement that has a GstNavigation interface and then
* send some navigation events and validate them */
TestElement *test_element =
(TestElement *) g_object_new (TEST_ELEMENT_TYPE, NULL);
GstNavigationCommand cmds[] = {
GST_NAVIGATION_COMMAND_MENU1, GST_NAVIGATION_COMMAND_MENU2,
GST_NAVIGATION_COMMAND_MENU3, GST_NAVIGATION_COMMAND_MENU4,
GST_NAVIGATION_COMMAND_MENU5, GST_NAVIGATION_COMMAND_MENU6,
GST_NAVIGATION_COMMAND_MENU7, GST_NAVIGATION_COMMAND_LEFT,
GST_NAVIGATION_COMMAND_RIGHT, GST_NAVIGATION_COMMAND_UP,
GST_NAVIGATION_COMMAND_DOWN, GST_NAVIGATION_COMMAND_ACTIVATE,
GST_NAVIGATION_COMMAND_PREV_ANGLE, GST_NAVIGATION_COMMAND_NEXT_ANGLE
};
gint i;
test_element->sent_type = GST_NAVIGATION_EVENT_KEY_PRESS;
test_element->sent_key = "1";
gst_navigation_send_key_event (GST_NAVIGATION (test_element), "key-press",
"1");
test_element->sent_type = GST_NAVIGATION_EVENT_KEY_RELEASE;
test_element->sent_key = "2";
gst_navigation_send_key_event (GST_NAVIGATION (test_element), "key-release",
"2");
test_element->sent_type = GST_NAVIGATION_EVENT_MOUSE_MOVE;
test_element->sent_x = 50;
test_element->sent_y = 100;
gst_navigation_send_mouse_event (GST_NAVIGATION (test_element), "mouse-move",
0, 50, 100);
test_element->sent_type = GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS;
test_element->sent_x = 10;
test_element->sent_y = 20;
test_element->sent_button = 1;
gst_navigation_send_mouse_event (GST_NAVIGATION (test_element),
"mouse-button-press", 1, 10, 20);
for (i = 0; i < G_N_ELEMENTS (cmds); i++) {
test_element->sent_type = GST_NAVIGATION_EVENT_COMMAND;
test_element->sent_command = cmds[i];
gst_navigation_send_command (GST_NAVIGATION (test_element), cmds[i]);
}
gst_object_unref (test_element);
}
GST_END_TEST;
GST_START_TEST (test_messages)
{
GstMessage *m;
/* GST_NAVIGATION_MESSAGE_MOUSE_OVER */
{
gboolean active;
m = gst_navigation_message_new_mouse_over (NULL, TRUE);
fail_if (m == NULL);
fail_unless (gst_navigation_message_get_type (m) ==
GST_NAVIGATION_MESSAGE_MOUSE_OVER);
fail_unless (GST_MESSAGE_SRC (m) == NULL);
fail_unless (gst_navigation_message_parse_mouse_over (m, &active));
fail_unless (active == TRUE);
gst_message_unref (m);
m = gst_navigation_message_new_mouse_over (NULL, FALSE);
fail_if (m == NULL);
fail_unless (GST_MESSAGE_SRC (m) == NULL);
fail_unless (gst_navigation_message_get_type (m) ==
GST_NAVIGATION_MESSAGE_MOUSE_OVER);
fail_unless (gst_navigation_message_parse_mouse_over (m, &active));
fail_unless (active == FALSE);
gst_message_unref (m);
}
/* GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED */
{
m = gst_navigation_message_new_commands_changed (NULL);
fail_if (m == NULL);
fail_unless (GST_MESSAGE_SRC (m) == NULL);
fail_unless (gst_navigation_message_get_type (m) ==
GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED);
gst_message_unref (m);
}
/* GST_NAVIGATION_MESSAGE_ANGLES_CHANGED */
{
guint angle, angles;
m = gst_navigation_message_new_angles_changed (NULL, 1, 5);
fail_if (m == NULL);
fail_unless (GST_MESSAGE_SRC (m) == NULL);
fail_unless (gst_navigation_message_get_type (m) ==
GST_NAVIGATION_MESSAGE_ANGLES_CHANGED);
fail_unless (gst_navigation_message_parse_angles_changed (m, &angle,
&angles));
fail_unless (angle == 1);
fail_unless (angles == 5);
gst_message_unref (m);
}
}
GST_END_TEST;
GST_START_TEST (test_queries)
{
GstQuery *q;
/* GST_NAVIGATION_QUERY_COMMANDS */
{
guint n;
GstNavigationCommand cmd;
q = gst_navigation_query_new_commands ();
fail_unless (q != NULL);
fail_unless (gst_navigation_query_get_type (q) ==
GST_NAVIGATION_QUERY_COMMANDS);
gst_navigation_query_set_commands (q, 3, GST_NAVIGATION_COMMAND_LEFT,
GST_NAVIGATION_COMMAND_MENU1, GST_NAVIGATION_COMMAND_MENU5);
fail_unless (gst_navigation_query_parse_commands_length (q, &n));
fail_unless (n == 3);
fail_unless (gst_navigation_query_parse_commands_nth (q, 1, &cmd));
fail_unless (cmd == GST_NAVIGATION_COMMAND_MENU1);
fail_unless (gst_navigation_query_parse_commands_length (q, NULL));
fail_unless (gst_navigation_query_parse_commands_nth (q, 2, NULL));
gst_query_unref (q);
}
/* GST_NAVIGATION_QUERY_ANGLES */
{
guint angle, angles;
q = gst_navigation_query_new_angles ();
fail_unless (q != NULL);
fail_unless (gst_navigation_query_get_type (q) ==
GST_NAVIGATION_QUERY_ANGLES);
gst_navigation_query_set_angles (q, 4, 8);
fail_unless (gst_navigation_query_parse_angles (q, &angle, &angles));
fail_unless (angle == 4);
fail_unless (angles == 8);
fail_unless (gst_navigation_query_parse_angles (q, NULL, &angles));
fail_unless (gst_navigation_query_parse_angles (q, &angle, NULL));
fail_unless (gst_navigation_query_parse_angles (q, NULL, NULL));
gst_query_unref (q);
}
}
GST_END_TEST;
static Suite *
navigation_suite (void)
{
Suite *s = suite_create ("navigation interface");
TCase *tc_chain = tcase_create ("notifications");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_events);
tcase_add_test (tc_chain, test_messages);
tcase_add_test (tc_chain, test_queries);
return s;
}
int
main (int argc, char **argv)
{
int nf;
Suite *s = navigation_suite ();
SRunner *sr = srunner_create (s);
gst_check_init (&argc, &argv);
srunner_run_all (sr, CK_NORMAL);
nf = srunner_ntests_failed (sr);