diff options
author | Benjamin Otte <otte@gnome.org> | 2008-01-30 17:04:17 +0100 |
---|---|---|
committer | Benjamin Otte <otte@gnome.org> | 2008-01-30 17:04:17 +0100 |
commit | c20db2b19391459a4bbabb9dec4b9095189c321e (patch) | |
tree | 94d5d352caa515eedde09358bb5aea7bccd13e61 | |
parent | b4c537e44dd3673d09c89af456ecf161443aceb8 (diff) |
add initial input handling support
mouse works pretty well, keyboard is not implemented yet
-rw-r--r-- | player/main.c | 3 | ||||
-rw-r--r-- | swfdec-directfb/swfdec_directfb_player.c | 141 | ||||
-rw-r--r-- | swfdec-directfb/swfdec_directfb_player.h | 10 |
3 files changed, 150 insertions, 4 deletions
diff --git a/player/main.c b/player/main.c index e01d7fa..d3e321a 100644 --- a/player/main.c +++ b/player/main.c @@ -102,7 +102,8 @@ main (int argc, char *argv[]) ERROR_CHECK (DirectFBCreate (&dfb)); player = swfdec_dfb_player_new (dfb, NULL); g_object_set (player, "cache-size", (gulong) cache_size * 1024, - "memory-until-gc", (gulong) garbage_size * 1024, NULL); + "memory-until-gc", (gulong) garbage_size * 1024, "handle-events", TRUE, + NULL); if (no_background) g_object_set (player, "background-color", 0, NULL); diff --git a/swfdec-directfb/swfdec_directfb_player.c b/swfdec-directfb/swfdec_directfb_player.c index 9a76133..6e09b98 100644 --- a/swfdec-directfb/swfdec_directfb_player.c +++ b/swfdec-directfb/swfdec_directfb_player.c @@ -77,6 +77,9 @@ swfdec_dfb_player_get_property (GObject *object, guint param_id, GValue *value, case PROP_DFB: g_value_set_pointer (value, player->dfb); break; + case PROP_HANDLE_EVENTS: + g_value_set_boolean (value, swfdec_dfb_player_get_handle_events (player)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -104,6 +107,9 @@ swfdec_dfb_player_set_property (GObject *object, guint param_id, const GValue *v g_return_if_fail (player->dfb); player->dfb->AddRef (player->dfb); break; + case PROP_HANDLE_EVENTS: + swfdec_dfb_player_set_handle_events ((player), g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -116,6 +122,7 @@ swfdec_dfb_player_dispose (GObject *object) SwfdecDfbPlayer *player = SWFDEC_DFB_PLAYER (object); swfdec_dfb_player_set_playing (player, FALSE); + swfdec_dfb_player_set_handle_events (player, FALSE); if (player->dfb) { player->dfb->Release (player->dfb); player->dfb = NULL; @@ -145,6 +152,9 @@ swfdec_dfb_player_class_init (SwfdecDfbPlayerClass * g_class) g_object_class_install_property (object_class, PROP_DFB, g_param_spec_pointer ("directfb", "directfb", "The directfb object this player operates on", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_HANDLE_EVENTS, + g_param_spec_boolean ("handle-events", "handle events", "wether player has a global event handler installed", + FALSE, G_PARAM_READWRITE)); } static void @@ -290,8 +300,137 @@ swfdec_dfb_player_set_speed (SwfdecDfbPlayer *player, double speed) double swfdec_dfb_player_get_speed (SwfdecDfbPlayer *player) { - g_return_val_if_fail (SWFDEC_IS_DFB_PLAYER (player), FALSE); + g_return_val_if_fail (SWFDEC_IS_DFB_PLAYER (player), 0.0); return player->speed; } +/** + * swfdec_dfb_player_handle_input_event: + * @player: the player that receives the event + * @event: the event to handle + * + * Provides an input event to the @player. The player handles keyboard and mouse + * events in a generic way. If you want to use a more complex mechanism, you + * have to write your own event handling code. + * + * Returns: %TRUE if the event was handled, %FALSE otherwise. + **/ +gboolean +swfdec_dfb_player_handle_input_event (SwfdecDfbPlayer *player, const DFBInputEvent *event) +{ + g_return_val_if_fail (SWFDEC_IS_DFB_PLAYER (player), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + switch (event->type) { + case DIET_KEYPRESS: + case DIET_KEYRELEASE: + /* FIXME! */ + break; + case DIET_BUTTONPRESS: + swfdec_player_mouse_press (SWFDEC_PLAYER (player), + player->x, player->y, event->button + 1); + break; + case DIET_BUTTONRELEASE: + swfdec_player_mouse_release (SWFDEC_PLAYER (player), + player->x, player->y, event->button + 1); + break; + case DIET_AXISMOTION: + if (event->axis == DIAI_X) { + player->x = event->axisabs; + } else if (event->axis == DIAI_Y) { + player->y = event->axisabs; + } else { + return FALSE; + } + /* only emit mouse movements if no new mouse move event follows */ + if ((event->flags & DIEF_FOLLOW) == 0) + swfdec_player_mouse_move (SWFDEC_PLAYER (player), player->x, player->y); + break; + case DIET_UNKNOWN: + default: + return FALSE; + } + return TRUE; +} + +static gboolean +swfdec_dfb_player_event_io (GIOChannel *channel, GIOCondition condition, gpointer player) +{ + gsize i, n; + DFBEvent events[32]; + + if (g_io_channel_read_chars (channel, (gchar *) events, sizeof (events), &n, NULL) != G_IO_STATUS_NORMAL) + return TRUE; + + n /= sizeof (DFBEvent); + + for (i = 0; i < n; i++) { + if (events[i].clazz != DFEC_INPUT) + continue; + + swfdec_dfb_player_handle_input_event (player, (DFBInputEvent *) &events[i]); + } + + /* FIXME: need to reset here? */ + return TRUE; +} + +gboolean +swfdec_dfb_player_set_handle_events (SwfdecDfbPlayer *player, gboolean handle_events) +{ + g_return_val_if_fail (SWFDEC_IS_DFB_PLAYER (player), FALSE); + + if (swfdec_dfb_player_get_handle_events (player) == handle_events) + return TRUE; + + if (handle_events) { + GIOChannel *channel; + int fd; + + if (player->dfb->CreateInputEventBuffer (player->dfb, DICAPS_ALL, DFB_FALSE, &player->events)) + return FALSE; + if (player->events->CreateFileDescriptor (player->events, &fd)) { + player->events->Release (player->events); + player->events = NULL; + return FALSE; + } + + channel = g_io_channel_unix_new (fd); + g_io_channel_set_encoding (channel, NULL, NULL); + g_io_channel_set_buffered (channel, FALSE); + + player->event_source = g_io_create_watch (channel, G_IO_IN); + g_source_set_priority (player->event_source, G_PRIORITY_DEFAULT); + g_source_set_can_recurse (player->event_source, TRUE); + g_source_set_callback (player->event_source, (GSourceFunc) swfdec_dfb_player_event_io, player, NULL); + g_source_attach (player->event_source, NULL); + g_io_channel_unref (channel); + } else { + g_source_destroy (player->event_source); + g_source_unref (player->event_source); + player->event_source = NULL; + player->events->Release (player->events); + player->events = NULL; + } + g_object_notify (G_OBJECT (player), "handle-events"); + return TRUE; +} + +/** + * swfdec_dfb_player_get_handle_events: + * @player: the player to query + * + * Queries if the given @player has a global event handler installed. See + * swfdec_dfb_player_set_handle_events() for what that means. + * + * Returns: %TRUE if a global event handler is installed + **/ +gboolean +swfdec_dfb_player_get_handle_events (SwfdecDfbPlayer *player) +{ + g_return_val_if_fail (SWFDEC_IS_DFB_PLAYER (player), FALSE); + + return player->events != NULL; +} + diff --git a/swfdec-directfb/swfdec_directfb_player.h b/swfdec-directfb/swfdec_directfb_player.h index 247544b..4233d8e 100644 --- a/swfdec-directfb/swfdec_directfb_player.h +++ b/swfdec-directfb/swfdec_directfb_player.h @@ -45,6 +45,12 @@ struct _SwfdecDfbPlayer GSource * source; /* source if playing, NULL otherwise */ gboolean audio_enabled; /* TRUE if audio should be played */ double speed; /* desired playback speed */ + + /* input handling */ + IDirectFBEventBuffer *events; /* where we get our events from or NULL */ + GSource * event_source; /* the source getting those events or NULL */ + int x; /* last known X coordinate */ + int y; /* last known Y coordinate */ }; struct _SwfdecDfbPlayerClass @@ -67,9 +73,9 @@ void swfdec_dfb_player_set_speed (SwfdecDfbPlayer * player, double speed); double swfdec_dfb_player_get_speed (SwfdecDfbPlayer * player); -gboolean swfdec_dfb_player_handle_event (SwfdecDfbPlayer * player, +gboolean swfdec_dfb_player_handle_input_event (SwfdecDfbPlayer * player, const DFBInputEvent * event); -void swfdec_dfb_player_set_handle_events (SwfdecDfbPlayer * player, +gboolean swfdec_dfb_player_set_handle_events (SwfdecDfbPlayer * player, gboolean handle_events); gboolean swfdec_dfb_player_get_handle_events (SwfdecDfbPlayer * player); |