]> git.sesse.net Git - vlc/commitdiff
Make the maemo interface a bit more useable
authorGildas Bazin <gibalou@videolan.org>
Sun, 7 Feb 2010 23:02:49 +0000 (23:02 +0000)
committerGildas Bazin <gibalou@videolan.org>
Sun, 7 Feb 2010 23:02:49 +0000 (23:02 +0000)
16 files changed:
NEWS
modules/gui/hildon/maemo.c
modules/gui/hildon/maemo.h
modules/gui/hildon/maemo_callbacks.c
modules/gui/hildon/maemo_callbacks.h
modules/gui/hildon/maemo_input.c
modules/gui/hildon/maemo_input.h
modules/gui/hildon/maemo_interface.c
modules/gui/hildon/maemo_interface.h
share/Makefile.am
share/maemo/next.png [new file with mode: 0644]
share/maemo/pause.png [new file with mode: 0644]
share/maemo/play.png [new file with mode: 0644]
share/maemo/playlist.png
share/maemo/previous.png [new file with mode: 0644]
share/maemo/stop.png [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 1686477c701daa4131ec0d281f69d78f2e4e69e3..b88bfc6fb97d0a2e26aad966daa2e04ef6e58597 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -103,6 +103,7 @@ Windows port:
 Maemo port:
  * Multiple improvements for N900 compliance and efficiency
  * Support for HW accelerated video decoding on N900
+ * Improvements to the maemo interface
 
 Misc:
  * new sqlite module
index bcb0f404afc1482aa8573e0948e7f73043fe8a46..6ae8dbf7cd84a2215cfecb61bfdb3016f90f0991 100644 (file)
@@ -1,32 +1,31 @@
-/*****************************************************************************
-* maemo.c : Maemo plugin for VLC
-*****************************************************************************
-* Copyright (C) 2008 the VideoLAN team
-* $Id$
-*
-* Authors: Antoine Lejeune <phytos@videolan.org>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
-*****************************************************************************/
+/****************************************************************************
+ * maemo.c : Maemo plugin for VLC
+ *****************************************************************************
+ * Copyright (C) 2008 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Lejeune <phytos@videolan.org>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
 
-#include <assert.h>
-
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_interface.h>
  *****************************************************************************/
 static int      Open               ( vlc_object_t * );
 static void     Close              ( vlc_object_t * );
-static void     Run                ( intf_thread_t * );
+static void     *Thread            ( void * );
 static gboolean should_die         ( gpointer );
 static int      OpenWindow         ( vlc_object_t * );
 static void     CloseWindow        ( vlc_object_t * );
 static int      ControlWindow      ( vout_window_t *, int, va_list );
-static uint32_t request_video      ( intf_thread_t *, vout_thread_t * );
-static void     release_video      ( intf_thread_t * );
-static gboolean video_widget_ready ( gpointer data );
+static gboolean interface_ready    ( gpointer );
 
 /*****************************************************************************
 * Module descriptor
@@ -75,38 +72,46 @@ vlc_module_begin();
         set_callbacks( OpenWindow, CloseWindow );
 vlc_module_end();
 
-static struct
-{
-    vlc_mutex_t    lock;
-    vlc_cond_t     wait;
-    intf_thread_t *intf;
-    bool           enabled;
-} wnd_req = { VLC_STATIC_MUTEX, PTHREAD_COND_INITIALIZER, NULL, false };
-
 /*****************************************************************************
  * Module callbacks
  *****************************************************************************/
 static int Open( vlc_object_t *p_this )
 {
     intf_thread_t *p_intf = (intf_thread_t *)p_this;
+    intf_sys_t *p_sys;;
+    vlc_value_t val;
 
     /* Allocate instance and initialize some members */
-    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
+    p_intf->p_sys = p_sys = malloc( sizeof( intf_sys_t ) );
     if( p_intf->p_sys == NULL )
         return VLC_ENOMEM;
 
-    p_intf->pf_run = Run;
+    p_sys->p_playlist = pl_Hold( p_intf );
+    p_sys->p_input = NULL;
 
-    p_intf->p_sys->p_playlist = pl_Hold( p_intf );
-    p_intf->p_sys->p_input = NULL;
-    p_intf->p_sys->p_vout = NULL;
+    p_sys->p_main_window = NULL;
+    p_sys->p_video_window = NULL;
+    p_sys->p_control_window = NULL;
+    p_sys->b_fullscreen = false;
 
-    p_intf->p_sys->p_main_window = NULL;
-    p_intf->p_sys->p_video_window = NULL;
+    vlc_spin_init( &p_sys->event_lock );
 
-    wnd_req.enabled = true;
-    /* ^no need to lock, interfacesare started before video outputs */
-    vlc_spin_init( &p_intf->p_sys->event_lock );
+    /* Create separate thread for main interface */
+    vlc_sem_init (&p_sys->ready, 0);
+    if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) )
+    {
+        pl_Release (p_sys->p_playlist);
+        free (p_sys);
+        return VLC_ENOMEM;
+    }
+
+    /* Wait for interface thread to be fully initialised */
+    vlc_sem_wait (&p_sys->ready);
+    vlc_sem_destroy (&p_sys->ready);
+
+    var_Create (p_this->p_libvlc, "hildon-iface", VLC_VAR_ADDRESS);
+    val.p_address = p_this;
+    var_Set (p_this->p_libvlc, "hildon-iface", val);
 
     return VLC_SUCCESS;
 }
@@ -115,34 +120,42 @@ static void Close( vlc_object_t *p_this )
 {
     intf_thread_t *p_intf = (intf_thread_t *)p_this;
 
-    vlc_object_release( p_intf->p_sys->p_playlist );
-
+    var_Destroy (p_this->p_libvlc, "hildon-iface");
+    vlc_join (p_intf->p_sys->thread, NULL);
+    pl_Release ( p_intf->p_sys->p_playlist );
     vlc_spin_destroy( &p_intf->p_sys->event_lock );
-
-    /* Destroy structure */
     free( p_intf->p_sys );
 }
 
+static gint quit_event( GtkWidget *widget, GdkEvent *event, gpointer data )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)data;
+    (void)widget; (void)event;
+    libvlc_Quit( p_intf->p_libvlc );
+    return TRUE;
+}
+
 /*****************************************************************************
 * Initialize and launch the interface
 *****************************************************************************/
-static void Run( intf_thread_t *p_intf )
+static void *Thread( void *obj )
 {
-    char  *p_args[] = { (char *)"vlc", NULL };
-    char **pp_args  = p_args;
-    int    i_args   = 1;
+    intf_thread_t *p_intf = (intf_thread_t *)obj;
+    const char *p_args[] = { "vlc", "--sync" };
+    int i_args = sizeof(p_args)/sizeof(char *);
+    char **pp_args  = (char **)p_args;
 
     HildonProgram *program;
     HildonWindow *window;
     GtkWidget *main_vbox;
 
-    GtkWidget *tabs;
     GtkWidget *video;
     GtkWidget *bottom_hbox;
     GtkWidget *play_button;
     GtkWidget *prev_button;
     GtkWidget *next_button;
     GtkWidget *stop_button;
+    GtkWidget *playlist_button;
     GtkWidget *seekbar;
 
     gtk_init( &i_args, &pp_args );
@@ -152,10 +165,14 @@ static void Run( intf_thread_t *p_intf )
 
     window = HILDON_WINDOW( hildon_window_new() );
     hildon_program_add_window( program, window );
-    gtk_object_set_data( GTK_OBJECT( window ),
-                         "p_intf", p_intf );
+    gtk_object_set_data( GTK_OBJECT( window ), "p_intf", p_intf );
     p_intf->p_sys->p_main_window = window;
 
+    g_signal_connect( GTK_WIDGET(window), "key-press-event",
+                      G_CALLBACK( key_cb ), p_intf );
+    g_signal_connect (GTK_WIDGET(window), "delete_event",
+                      GTK_SIGNAL_FUNC( quit_event), p_intf );
+
     // A little theming
     char *psz_rc_file = NULL;
     char *psz_data = config_GetDataDir( p_intf );
@@ -170,25 +187,18 @@ static void Run( intf_thread_t *p_intf )
     main_vbox = gtk_vbox_new( FALSE, 0 );
     gtk_container_add( GTK_CONTAINER( window ), main_vbox );
 
-    tabs = gtk_notebook_new();
-    p_intf->p_sys->p_tabs = tabs;
-    gtk_notebook_set_tab_pos( GTK_NOTEBOOK( tabs ), GTK_POS_LEFT );
-    gtk_notebook_set_show_border( GTK_NOTEBOOK( tabs ), FALSE );
-    gtk_box_pack_start( GTK_BOX( main_vbox ), tabs, TRUE, TRUE, 0 );
-
     // We put first the embedded video
     video = gtk_event_box_new();
-    gtk_notebook_append_page( GTK_NOTEBOOK( tabs ),
-                video,
-                gtk_image_new_from_stock( "vlc",
-                                          GTK_ICON_SIZE_DIALOG ) );
-    gtk_notebook_set_tab_label_packing( GTK_NOTEBOOK( tabs ),
-                                        video,
-                                        FALSE, FALSE, 0 );
+    GdkColor black = {0,0,0,0};
+    gtk_widget_modify_bg(video, GTK_STATE_NORMAL, &black);
+    p_intf->p_sys->p_video_window = video;
+    gtk_box_pack_start( GTK_BOX( main_vbox ), video, TRUE, TRUE, 0 );
+
     create_playlist( p_intf );
+    gtk_box_pack_start( GTK_BOX( main_vbox ), p_intf->p_sys->p_playlist_window, TRUE, TRUE, 0 );
 
     // We put the horizontal box which contains all the buttons
-    bottom_hbox = gtk_hbox_new( FALSE, 0 );
+    p_intf->p_sys->p_control_window = bottom_hbox = gtk_hbox_new( FALSE, 0 );
 
     // We create the buttons
     play_button = gtk_button_new();
@@ -205,6 +215,9 @@ static void Run( intf_thread_t *p_intf )
     next_button = gtk_button_new();
     gtk_button_set_image( GTK_BUTTON( next_button ),
                       gtk_image_new_from_stock( "vlc-next", GTK_ICON_SIZE_BUTTON ) );
+    playlist_button = gtk_button_new();
+    gtk_button_set_image( GTK_BUTTON( playlist_button ),
+                          gtk_image_new_from_stock( "vlc-playlist", GTK_ICON_SIZE_BUTTON ) );
     seekbar = hildon_seekbar_new();
     p_intf->p_sys->p_seekbar = HILDON_SEEKBAR( seekbar );
 
@@ -213,6 +226,7 @@ static void Run( intf_thread_t *p_intf )
     gtk_box_pack_start( GTK_BOX( bottom_hbox ), stop_button, FALSE, FALSE, 0 );
     gtk_box_pack_start( GTK_BOX( bottom_hbox ), prev_button, FALSE, FALSE, 0 );
     gtk_box_pack_start( GTK_BOX( bottom_hbox ), next_button, FALSE, FALSE, 0 );
+    gtk_box_pack_start( GTK_BOX( bottom_hbox ), playlist_button, FALSE, FALSE, 0 );
     gtk_box_pack_start( GTK_BOX( bottom_hbox ), seekbar    , TRUE , TRUE , 5 );
     // We add the hbox to the main vbox
     gtk_box_pack_start( GTK_BOX( main_vbox ), bottom_hbox, FALSE, FALSE, 0 );
@@ -223,13 +237,28 @@ static void Run( intf_thread_t *p_intf )
     g_signal_connect( stop_button, "clicked", G_CALLBACK( stop_cb ), NULL );
     g_signal_connect( prev_button, "clicked", G_CALLBACK( prev_cb ), NULL );
     g_signal_connect( next_button, "clicked", G_CALLBACK( next_cb ), NULL );
+    g_signal_connect( playlist_button, "clicked", G_CALLBACK( playlist_cb ), NULL );
     g_signal_connect( seekbar, "change-value",
                       G_CALLBACK( seekbar_changed_cb ), NULL );
 
     gtk_widget_show_all( GTK_WIDGET( window ) );
+    gtk_widget_hide_all( p_intf->p_sys->p_playlist_window );
 
     create_menu( p_intf );
 
+#if 1
+    /* HACK: Only one X11 client can subscribe to mouse button press events.
+     * VLC currently handles those in the video display.
+     * Force GTK to unsubscribe from mouse press and release events. */
+    Display *dpy = GDK_WINDOW_XDISPLAY( gtk_widget_get_window(p_intf->p_sys->p_video_window) );
+    Window w = GDK_WINDOW_XID( gtk_widget_get_window(p_intf->p_sys->p_video_window) );
+    XWindowAttributes attr;
+
+    XGetWindowAttributes( dpy, w, &attr );
+    attr.your_event_mask &= ~(ButtonPressMask|ButtonReleaseMask);
+    XSelectInput( dpy, w, attr.your_event_mask );
+#endif
+
     // Set callback with the vlc core
     g_timeout_add( INTF_IDLE_SLEEP / 1000, process_events, p_intf );
     g_timeout_add( 150 /* miliseconds */, should_die, p_intf );
@@ -240,11 +269,8 @@ static void Run( intf_thread_t *p_intf )
     var_AddCallback( p_intf->p_sys->p_playlist, "activity",
                      activity_cb, p_intf );
 
-    // Look if the playlist is already started
-    item_changed_pl( p_intf );
-
     // The embedded video is only ready after gtk_main and windows are shown
-    g_idle_add( video_widget_ready, video );
+    g_idle_add( interface_ready, p_intf );
 
     gtk_main();
 
@@ -256,9 +282,9 @@ static void Run( intf_thread_t *p_intf )
     var_DelCallback( p_intf->p_sys->p_playlist, "activity",
                      activity_cb, p_intf );
 
-    /* FIXME: we need to wait for vout to clean up... */
-    assert( !p_intf->p_sys->p_vout ); /* too late */
     gtk_object_destroy( GTK_OBJECT( window ) );
+
+    return NULL;
 }
 
 static gboolean should_die( gpointer data )
@@ -272,42 +298,39 @@ static gboolean should_die( gpointer data )
 /**
 * Video output window provider
 */
-static int OpenWindow (vlc_object_t *obj)
+static int OpenWindow (vlc_object_t *p_obj)
 {
-    vout_window_t *wnd = (vout_window_t *)obj;
-    intf_thread_t *intf;
+    vout_window_t *p_wnd = (vout_window_t *)p_obj;
+    intf_thread_t *p_intf;
+    vlc_value_t val;
 
-    if (wnd->cfg->is_standalone || !wnd_req.enabled)
+    if (p_wnd->cfg->is_standalone)
         return VLC_EGENERIC;
 
-    /* FIXME it should NOT be needed */
-    vout_thread_t *vout = vlc_object_find (obj, VLC_OBJECT_VOUT, FIND_PARENT);
-    if (!vout)
-        return VLC_EGENERIC;
+    if( var_Get( p_obj->p_libvlc, "hildon-iface", &val ) )
+        val.p_address = NULL;
 
-    vlc_mutex_lock (&wnd_req.lock);
-    while ((intf = wnd_req.intf) == NULL)
-        vlc_cond_wait (&wnd_req.wait, &wnd_req.lock);
-
-    wnd->handle.xid = request_video( intf, vout );
-    vlc_mutex_unlock (&wnd_req.lock);
+    p_intf = (intf_thread_t *)val.p_address;
+    if( !p_intf )
+    {   /* If another interface is used, this plugin cannot work */
+        msg_Dbg( p_obj, "Hildon interface not found" );
+        return VLC_EGENERIC;
+    }
 
-    vlc_object_release( vout );
+    p_wnd->handle.xid = p_intf->p_sys->xid;
 
-    if (!wnd->handle.xid)
+    if (!p_wnd->handle.xid)
         return VLC_EGENERIC;
 
-    msg_Dbg( intf, "Using handle %"PRIu32, wnd->handle.xid );
-
-    wnd->control = ControlWindow;
-    wnd->sys = (vout_window_sys_t*)intf;
+    p_wnd->control = ControlWindow;
+    p_wnd->sys = (vout_window_sys_t*)p_intf;
 
     return VLC_SUCCESS;
 }
 
-static int ControlWindow (vout_window_t *wnd, int query, va_list args)
+static int ControlWindow (vout_window_t *p_wnd, int query, va_list args)
 {
-    intf_thread_t *intf = (intf_thread_t *)wnd->sys;
+    intf_thread_t *p_intf = (intf_thread_t *)p_wnd->sys;
 
     switch( query )
     {
@@ -317,69 +340,48 @@ static int ControlWindow (vout_window_t *wnd, int query, va_list args)
         int i_height = (int)va_arg( args, int );
 
         int i_current_w, i_current_h;
-        gdk_drawable_get_size( GDK_DRAWABLE( intf->p_sys->p_video_window->window ),
+        gdk_drawable_get_size( GDK_DRAWABLE( p_intf->p_sys->p_video_window ),
                                &i_current_w, &i_current_h );
         if( i_width != i_current_w || i_height != i_current_h )
             return VLC_EGENERIC;
         return VLC_SUCCESS;
     }
+    case VOUT_WINDOW_SET_FULLSCREEN:
+    {
+        bool b_fs = va_arg( args, int );
+        p_intf->p_sys->b_fullscreen = b_fs;
+        g_idle_add( fullscreen_cb, p_intf );
+        return VLC_SUCCESS;
+    }
     default:
         return VLC_EGENERIC;
     }
 }
 
-static void CloseWindow (vlc_object_t *obj)
+static void CloseWindow (vlc_object_t *p_obj)
 {
-    vout_window_t *wnd = (vout_window_t *)obj;
-    intf_thread_t *intf = (intf_thread_t *)wnd->sys;
-
-    vlc_mutex_lock( &wnd_req.lock );
-    release_video( intf );
-    vlc_mutex_unlock( &wnd_req.lock );
-}
+    vout_window_t *p_wnd = (vout_window_t *)p_obj;
+    intf_thread_t *p_intf = (intf_thread_t *)p_wnd->sys;
 
-static uint32_t request_video( intf_thread_t *p_intf, vout_thread_t *p_nvout )
-{
-    if( p_intf->p_sys->p_vout )
+    if( p_intf->p_sys->b_fullscreen )
     {
-        msg_Dbg( p_intf, "Embedded video already in use" );
-        return 0;
+        p_intf->p_sys->b_fullscreen = false;
+        g_idle_add( fullscreen_cb, p_intf );
     }
-
-    p_intf->p_sys->p_vout = vlc_object_hold( p_nvout );
-    return GDK_WINDOW_XID( p_intf->p_sys->p_video_window->window );
-}
-
-static void release_video( intf_thread_t *p_intf )
-{
-    msg_Dbg( p_intf, "Releasing embedded video" );
-
-    vlc_object_release( p_intf->p_sys->p_vout );
-    p_intf->p_sys->p_vout = NULL;
 }
 
-static gboolean video_widget_ready( gpointer data )
+static gboolean interface_ready( gpointer data )
 {
-    intf_thread_t *p_intf = NULL;
-    GtkWidget *top_window = NULL;
-    GtkWidget *video = (GtkWidget *)data;
+    intf_thread_t *p_intf = (intf_thread_t *)data;
 
-    top_window = gtk_widget_get_toplevel( GTK_WIDGET( video ) );
-    p_intf = (intf_thread_t *)gtk_object_get_data( GTK_OBJECT( top_window ),
-                                                   "p_intf" );
-    p_intf->p_sys->p_video_window = video;
-    gtk_widget_grab_focus( video );
+    p_intf->p_sys->xid =
+        GDK_WINDOW_XID( gtk_widget_get_window(p_intf->p_sys->p_video_window) );
 
-    vlc_mutex_lock( &wnd_req.lock );
-    wnd_req.intf = p_intf;
-    vlc_cond_signal( &wnd_req.wait );
-    vlc_mutex_unlock( &wnd_req.lock );
+    // Look if the playlist is already started
+    item_changed_pl( p_intf );
 
-    // We rewind the input
-    if( p_intf->p_sys->p_input )
-    {
-        input_Control( p_intf->p_sys->p_input, INPUT_SET_POSITION, 0.0 );
-    }
+    // Everything is initialised
+    vlc_sem_post (&p_intf->p_sys->ready);
 
     // We want it to be executed only one time
     return FALSE;
index 7814dfcdc37c9274468604122db81b163aafec36..6bf93c9b82479ef489d59245ece761fc5c41abca 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <hildon/hildon-program.h>
 #include <hildon/hildon-seekbar.h>
-#include <hildon/hildon-file-chooser-dialog.h>
 #include <hildon/hildon-banner.h>
 
 #include <vlc_playlist.h>
 
 struct intf_sys_t
 {
+    vlc_thread_t thread;
+
     playlist_t *p_playlist;
     input_thread_t *p_input;
+    vlc_sem_t ready;
 
     HildonWindow  *p_main_window;
     HildonSeekbar *p_seekbar;
-    GtkWidget     *p_tabs;
     GtkWidget     *p_play_button;
 
-    GtkWidget *p_playlist_store;
+    GtkListStore  *p_playlist_store;
+    GtkWidget     *p_playlist_window;
 
     int i_event;
     vlc_spinlock_t event_lock;
 
     GtkWidget *p_video_window;
-    vout_thread_t *p_vout;
+    uint32_t xid; /* X11 windows ID */
+    bool b_fullscreen;
+
+    GtkWidget *p_control_window;
 };
index cf6395171a416da39af41974bed7a7ddf75bd506..3e8568939df2d82d27490e3b4f762463ba858e1d 100644 (file)
@@ -1,31 +1,39 @@
 /*****************************************************************************
-* maemo_callbacks.c : Callbacks for the maemo plugin.
-*****************************************************************************
-* Copyright (C) 2008 the VideoLAN team
-* $Id$
-*
-* Authors: Antoine Lejeune <phytos@videolan.org>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
-*****************************************************************************/
+ * maemo_callbacks.c : Callbacks for the maemo plugin.
+ *****************************************************************************
+ * Copyright (C) 2008 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Lejeune <phytos@videolan.org>
+ *          Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
 
 #include <vlc_common.h>
 
 #include "maemo.h"
 #include "maemo_callbacks.h"
 
+#include <gdk/gdkkeysyms.h>
+#include <vlc_keys.h>
+
+#ifdef HAVE_MAEMO
+# include <hildon/hildon-file-chooser-dialog.h>
+#endif
+
 /*
  * Function used to retrieve an intf_thread_t object from a GtkWidget
  */
@@ -99,6 +107,22 @@ void next_cb( GtkButton *button, gpointer user_data )
     playlist_Next( p_intf->p_sys->p_playlist );
 }
 
+void playlist_cb( GtkButton *button, gpointer user_data )
+{
+    (void)user_data;
+    intf_thread_t *p_intf = get_intf_from_widget( GTK_WIDGET( button ) );
+    if( GTK_WIDGET_VISIBLE(p_intf->p_sys->p_playlist_window) )
+    {
+      gtk_widget_show_all( p_intf->p_sys->p_video_window );
+      gtk_widget_hide_all( p_intf->p_sys->p_playlist_window );
+    }
+    else
+    {
+      gtk_widget_hide_all( p_intf->p_sys->p_video_window );
+      gtk_widget_show_all( p_intf->p_sys->p_playlist_window );
+    }
+}
+
 void seekbar_changed_cb( GtkRange *range, GtkScrollType scroll,
                          gdouble value, gpointer data )
 {
@@ -124,8 +148,6 @@ void pl_row_activated_cb( GtkTreeView *tree_view , GtkTreePath *path,
     gtk_tree_model_get_iter( model, &iter, path );
     gtk_tree_model_get( model, &iter, 0, &filename, -1 );
 
-    gtk_notebook_set_current_page( GTK_NOTEBOOK( p_intf->p_sys->p_tabs ), 0 );
-
     p_input = input_item_New( p_intf, filename, NULL );
     playlist_AddInput( p_intf->p_sys->p_playlist, p_input,
                        PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END, true, false );
@@ -140,8 +162,15 @@ void open_cb( GtkMenuItem *menuitem, gpointer user_data )
     GtkWidget *dialog;
     char *psz_filename = NULL;
 
+#ifdef HAVE_MAEMO
     dialog = hildon_file_chooser_dialog_new( GTK_WINDOW( p_intf->p_sys->p_main_window ),
                                              GTK_FILE_CHOOSER_ACTION_OPEN );
+#else
+    dialog = gtk_file_chooser_dialog_new( "Open File", GTK_WINDOW( p_intf->p_sys->p_main_window ),
+                                          GTK_FILE_CHOOSER_ACTION_OPEN,
+                                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                          GTK_STOCK_OK, GTK_RESPONSE_OK, NULL );
+#endif
     gtk_widget_show_all( GTK_WIDGET( dialog ) );
 
     if( gtk_dialog_run( GTK_DIALOG( dialog ) ) == GTK_RESPONSE_OK )
@@ -217,22 +246,22 @@ void open_webcam_cb( GtkMenuItem *menuitem, gpointer user_data )
 
 void snapshot_cb( GtkMenuItem *menuitem, gpointer user_data )
 {
-    (void)menuitem;
     intf_thread_t *p_intf = (intf_thread_t *)user_data;
+    input_thread_t *p_input = p_intf->p_sys->p_input;
+    vout_thread_t *p_vout = p_input ? input_GetVout( p_input ) : NULL;
+    (void)menuitem;
 
-    if( !p_intf->p_sys->p_vout )
+    if( !p_vout )
     {
         hildon_banner_show_information(
                                 GTK_WIDGET( p_intf->p_sys->p_main_window ),
-                                "gtk-dialog-error",
-                                "There is no video" );
+                                "gtk-dialog-error", "There is no video" );
         return;
     }
 
-    var_TriggerCallback( p_intf->p_sys->p_vout, "video-snapshot" );
+    var_TriggerCallback( p_vout, "video-snapshot" );
     hildon_banner_show_information( GTK_WIDGET( p_intf->p_sys->p_main_window ),
-                                    NULL,
-                                    "Snapshot taken" );
+                                    NULL, "Snapshot taken" );
 }
 
 void dropframe_cb( GtkMenuItem *menuitem, gpointer user_data )
@@ -244,3 +273,105 @@ void dropframe_cb( GtkMenuItem *menuitem, gpointer user_data )
     else
         config_PutInt( p_intf, "ffmpeg-skip-frame", 0 );
 }
+
+static int keyModifiersToVLC( GdkEventKey *event )
+{
+    int i_keyModifiers = 0;
+    if( event->state & GDK_SHIFT_MASK ) i_keyModifiers |= KEY_MODIFIER_SHIFT;
+    if( event->state & GDK_MOD1_MASK ) i_keyModifiers |= KEY_MODIFIER_ALT;
+    if( event->state & GDK_CONTROL_MASK ) i_keyModifiers |= KEY_MODIFIER_CTRL;
+    if( event->state & GDK_META_MASK ) i_keyModifiers |= KEY_MODIFIER_META;
+    return i_keyModifiers;
+}
+
+static int eventToVLCKey( GdkEventKey *event )
+{
+    int i_vlck = 0;
+
+    switch( event->keyval )
+    {
+    case GDK_Left: i_vlck |= KEY_LEFT; break;
+    case GDK_Right: i_vlck |= KEY_RIGHT; break;
+    case GDK_Up: i_vlck |= KEY_UP; break;
+    case GDK_Down: i_vlck |= KEY_DOWN; break;
+    case GDK_Escape: i_vlck |= KEY_ESC; break;
+    case GDK_Return: i_vlck |= KEY_ENTER; break;
+
+    case GDK_F1: i_vlck |= KEY_F1; break;
+    case GDK_F2: i_vlck |= KEY_F2; break;
+    case GDK_F3: i_vlck |= KEY_F3; break;
+    case GDK_F4: i_vlck |= KEY_F4; break;
+    case GDK_F5: i_vlck |= KEY_F5; break;
+    case GDK_F6: i_vlck |= KEY_F6; break;
+    case GDK_F7: i_vlck |= KEY_F7; break;
+    case GDK_F8: i_vlck |= KEY_F8; break;
+    case GDK_F9: i_vlck |= KEY_F9; break;
+    case GDK_F10: i_vlck |= KEY_F10; break;
+    case GDK_F11: i_vlck |= KEY_F11; break;
+    case GDK_F12: i_vlck |= KEY_F12; break;
+
+    case GDK_Page_Up: i_vlck |= KEY_PAGEUP; break;
+    case GDK_Page_Down: i_vlck |= KEY_PAGEDOWN; break;
+    case GDK_Home: i_vlck |= KEY_HOME; break;
+    case GDK_End: i_vlck |= KEY_END; break;
+    case GDK_Insert: i_vlck |= KEY_INSERT; break;
+    case GDK_Delete: i_vlck |= KEY_DELETE; break;
+
+#ifndef HAVE_MAEMO
+    case GDK_AudioLowerVolume: i_vlck |= KEY_VOLUME_DOWN; break;
+    case GDK_AudioRaiseVolume: i_vlck |= KEY_VOLUME_UP; break;
+    case GDK_AudioMute: i_vlck |= KEY_VOLUME_MUTE; break;
+    case GDK_AudioPlay: i_vlck |= KEY_MEDIA_PLAY_PAUSE; break;
+    case GDK_AudioStop: i_vlck |= KEY_MEDIA_STOP; break;
+    case GDK_AudioNext: i_vlck |= KEY_MEDIA_NEXT_TRACK; break;
+    case GDK_AudioPrev: i_vlck |= KEY_MEDIA_PREV_TRACK; break;
+#endif
+    }
+
+    if( !i_vlck )
+    {
+        /* Force lowercase */
+        if( event->keyval >= GDK_A && event->keyval <= GDK_Z )
+            i_vlck = event->keyval + 32;
+        /* Rest of the ascii range */
+        else if( event->keyval >= GDK_space && event->keyval <= GDK_asciitilde )
+            i_vlck = event->keyval;
+    }
+
+    /* Handle modifiers */
+    i_vlck |= keyModifiersToVLC( event );
+
+    return i_vlck;
+}
+
+gboolean key_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
+{
+    intf_thread_t *p_intf = (intf_thread_t *)user_data;
+    widget = widget; /* unused */
+
+    int i_vlck = eventToVLCKey( event );
+    if( i_vlck > 0 )
+    {
+        var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+gboolean fullscreen_cb( gpointer user_data )
+{
+    intf_thread_t *p_intf = (intf_thread_t *)user_data;
+
+    if(p_intf->p_sys->b_fullscreen)
+    {
+        gtk_widget_hide_all( GTK_WIDGET( p_intf->p_sys->p_control_window ) );
+        gtk_window_fullscreen( GTK_WINDOW(p_intf->p_sys->p_main_window) );
+    }
+    else
+    {
+        gtk_window_unfullscreen( GTK_WINDOW(p_intf->p_sys->p_main_window) );
+        gtk_widget_show_all( GTK_WIDGET( p_intf->p_sys->p_control_window ) );
+    }
+    return FALSE;
+}
index 84e7550c99a922cf74af5883d71ffb9ea500d7ab..46c42a7571befc8a24808913f6ad1d3da400df7d 100644 (file)
@@ -34,6 +34,7 @@ void play_cb( GtkButton *button, gpointer user_data );
 void stop_cb( GtkButton *button, gpointer user_data );
 void prev_cb( GtkButton *button, gpointer user_data );
 void next_cb( GtkButton *button, gpointer user_data );
+void playlist_cb( GtkButton *button, gpointer user_data );
 void seekbar_changed_cb( GtkRange *range, GtkScrollType scroll,
                          gdouble value, gpointer data );
 
@@ -46,3 +47,6 @@ void open_webcam_cb( GtkMenuItem *menuitem, gpointer user_data );
 
 void snapshot_cb( GtkMenuItem *menuitem, gpointer user_data );
 void dropframe_cb( GtkMenuItem *menuitem, gpointer user_data );
+
+gboolean key_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data);
+gboolean fullscreen_cb(gpointer user_data);
index de7ba9800d2b966133a546ac6ceb8eabeb3cce13..a4fa3161ddb9af8650852fee6654793ee06bb665 100644 (file)
@@ -1,25 +1,25 @@
 /*****************************************************************************
-* maemo_input.c : Input handling for the maemo plugin
-*****************************************************************************
-* Copyright (C) 2008 the VideoLAN team
-* $Id$
-*
-* Authors: Antoine Lejeune <phytos@videolan.org>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
-*****************************************************************************/
+ * maemo_input.c : Input handling for the maemo plugin
+ *****************************************************************************
+ * Copyright (C) 2008 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Lejeune <phytos@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -194,4 +194,3 @@ static int input_event_cb( vlc_object_t *p_this, const char *psz_var,
     else
         return interface_changed_cb( p_this, psz_var, oldval, newval, param );
 }
-
index 03eae50e5c88a47d190a01b4b1ff941c6992950c..75ac69a3e9a38f828aad097cc1be43e2086812ec 100644 (file)
@@ -1,25 +1,25 @@
 /*****************************************************************************
-* maemo_input.h : Input handling header file for the maemo plugin.
-*****************************************************************************
-* Copyright (C) 2008 the VideoLAN team
-* $Id$
-*
-* Authors: Antoine Lejeune <phytos@videolan.org>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
-*****************************************************************************/
+ * maemo_input.h : Input handling header file for the maemo plugin.
+ *****************************************************************************
+ * Copyright (C) 2008 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Lejeune <phytos@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
 
 #include <gtk/gtk.h>
 
index 16cf8f0927a89c57df1d7426223dba7dd7625b97..2824a82832eec7a2c72de48f8d9b656e1c4cd397 100644 (file)
@@ -1,25 +1,25 @@
 /*****************************************************************************
-* maemo_interface.c : Interface creation of the maemo plugin
-*****************************************************************************
-* Copyright (C) 2008 the VideoLAN team
-* $Id$
-*
-* Authors: Antoine Lejeune <phytos@videolan.org>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
-*****************************************************************************/
+ * maemo_interface.c : Interface creation of the maemo plugin
+ *****************************************************************************
+ * Copyright (C) 2008 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Lejeune <phytos@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
 
 #include <vlc_common.h>
 
@@ -101,7 +101,7 @@ void create_playlist( intf_thread_t *p_intf )
     playlist = gtk_tree_view_new();
 
     playlist_store = gtk_list_store_new( 1, G_TYPE_STRING );
-    p_intf->p_sys->p_playlist_store = GTK_WIDGET( playlist_store );
+    p_intf->p_sys->p_playlist_store = playlist_store;
 
     gtk_tree_view_set_model( GTK_TREE_VIEW( playlist ),
                              GTK_TREE_MODEL( playlist_store ) );
@@ -117,11 +117,7 @@ void create_playlist( intf_thread_t *p_intf )
     scroll = gtk_scrolled_window_new( NULL, NULL );
     gtk_container_add( GTK_CONTAINER( scroll ), playlist );
 
-    gtk_notebook_append_page( GTK_NOTEBOOK( p_intf->p_sys->p_tabs ), scroll,
-                              gtk_image_new_from_stock( "vlc-playlist",
-                                                        GTK_ICON_SIZE_DIALOG ) );
-    gtk_notebook_set_tab_label_packing( GTK_NOTEBOOK( p_intf->p_sys->p_tabs ), scroll,
-                                        FALSE, FALSE, GTK_PACK_START );
+    p_intf->p_sys->p_playlist_window = scroll;
 
     g_signal_connect( playlist, "row-activated",
                       G_CALLBACK( pl_row_activated_cb ), NULL );
index 87b535e4153d98537d3c69771ccef1a2d6c1bd88..2f48462e3a624f628d5bc43be9ab10d96ccb9cc8 100644 (file)
@@ -1,25 +1,25 @@
 /*****************************************************************************
-* maemo_interface.h : Interface creation header file for the maemo plugin.
-*****************************************************************************
-* Copyright (C) 2008 the VideoLAN team
-* $Id$
-*
-* Authors: Antoine Lejeune <phytos@videolan.org>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
-*****************************************************************************/
+ * maemo_interface.h : Interface creation header file for the maemo plugin.
+ *****************************************************************************
+ * Copyright (C) 2008 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Lejeune <phytos@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
 
 #include <gtk/gtk.h>
 
index 3135827045b7a81995f1e3903a8dde2aedd40d37..748008d955a6c13358fef353de9385d747a0ac87 100644 (file)
@@ -308,11 +308,11 @@ DIST_maemo = \
        maemo/vlc_left_tab_active.png \
        maemo/vlc_left_tab_passive.png \
        maemo/playlist.png
+       maemo/play.png \
+       maemo/pause.png \
+       maemo/stop.png \
+       maemo/previous.png \
+       maemo/next.png
 
 maemo_FILES = \
-       ../modules/gui/qt4/pixmaps/play.png \
-       ../modules/gui/qt4/pixmaps/pause.png \
-       ../modules/gui/qt4/pixmaps/stop.png \
-       ../modules/gui/qt4/pixmaps/previous.png \
-       ../modules/gui/qt4/pixmaps/next.png \
        vlc32x32.png
diff --git a/share/maemo/next.png b/share/maemo/next.png
new file mode 100644 (file)
index 0000000..67136ff
Binary files /dev/null and b/share/maemo/next.png differ
diff --git a/share/maemo/pause.png b/share/maemo/pause.png
new file mode 100644 (file)
index 0000000..4c33caf
Binary files /dev/null and b/share/maemo/pause.png differ
diff --git a/share/maemo/play.png b/share/maemo/play.png
new file mode 100644 (file)
index 0000000..7b47c69
Binary files /dev/null and b/share/maemo/play.png differ
index c6c703bab68a973de1e31d48ee8575f3afeb814e..b96e2b0c2d8778ef888d3fe41742dfeeaa37e8a2 100644 (file)
Binary files a/share/maemo/playlist.png and b/share/maemo/playlist.png differ
diff --git a/share/maemo/previous.png b/share/maemo/previous.png
new file mode 100644 (file)
index 0000000..988c08a
Binary files /dev/null and b/share/maemo/previous.png differ
diff --git a/share/maemo/stop.png b/share/maemo/stop.png
new file mode 100644 (file)
index 0000000..d905a49
Binary files /dev/null and b/share/maemo/stop.png differ