Commit 7da5f011 authored by Rafaël Carré's avatar Rafaël Carré

ncurses: make sure playlist box shows title when available

Also protect concurrent access to p_sys between main thread and libvlc callbacks

fixes: #4827
parent db10beba
/***************************************************************************** /*****************************************************************************
* ncurses.c : NCurses interface for vlc * ncurses.c : NCurses interface for vlc
***************************************************************************** *****************************************************************************
* Copyright © 2001-2010 the VideoLAN team * Copyright © 2001-2011 the VideoLAN team
* $Id$ * $Id$
* *
* Authors: Sam Hocevar <sam@zoy.org> * Authors: Sam Hocevar <sam@zoy.org>
...@@ -214,6 +214,7 @@ struct intf_sys_t ...@@ -214,6 +214,7 @@ struct intf_sys_t
struct pl_item_t **pp_plist; struct pl_item_t **pp_plist;
int i_plist_entries; int i_plist_entries;
bool b_need_update; bool b_need_update;
vlc_mutex_t pl_lock;
bool b_plidx_follow; bool b_plidx_follow;
playlist_item_t *p_node; /* current node */ playlist_item_t *p_node; /* current node */
...@@ -447,18 +448,35 @@ static void PlaylistRebuild(intf_thread_t *p_intf) ...@@ -447,18 +448,35 @@ static void PlaylistRebuild(intf_thread_t *p_intf)
PL_UNLOCK; PL_UNLOCK;
} }
static int PlaylistChanged(vlc_object_t *p_this, const char *psz_variable, static int ItemChanged(vlc_object_t *p_this, const char *psz_variable,
vlc_value_t oval, vlc_value_t nval, void *param) vlc_value_t oval, vlc_value_t nval, void *param)
{ {
VLC_UNUSED(p_this); VLC_UNUSED(psz_variable); VLC_UNUSED(p_this); VLC_UNUSED(psz_variable);
VLC_UNUSED(oval); VLC_UNUSED(nval); VLC_UNUSED(oval); VLC_UNUSED(nval);
intf_thread_t *p_intf = (intf_thread_t *)param;
intf_sys_t *p_sys = p_intf->p_sys;
vlc_mutex_lock(&p_sys->pl_lock);
p_sys->b_need_update = true;
vlc_mutex_unlock(&p_sys->pl_lock);
return VLC_SUCCESS;
}
static int PlaylistChanged(vlc_object_t *p_this, const char *psz_variable,
vlc_value_t oval, vlc_value_t nval, void *param)
{
VLC_UNUSED(p_this); VLC_UNUSED(psz_variable);
VLC_UNUSED(oval); VLC_UNUSED(nval);
intf_thread_t *p_intf = (intf_thread_t *)param; intf_thread_t *p_intf = (intf_thread_t *)param;
intf_sys_t *p_sys = p_intf->p_sys; intf_sys_t *p_sys = p_intf->p_sys;
playlist_item_t *p_node = playlist_CurrentPlayingItem(pl_Get(p_intf)); playlist_item_t *p_node = playlist_CurrentPlayingItem(pl_Get(p_intf));
vlc_mutex_lock(&p_sys->pl_lock);
p_sys->b_need_update = true; p_sys->b_need_update = true;
p_sys->p_node = p_node ? p_node->p_parent : NULL; p_sys->p_node = p_node ? p_node->p_parent : NULL;
vlc_mutex_unlock(&p_sys->pl_lock);
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -506,8 +524,12 @@ static inline bool IsIndex(intf_sys_t *p_sys, playlist_t *p_playlist, int i) ...@@ -506,8 +524,12 @@ static inline bool IsIndex(intf_sys_t *p_sys, playlist_t *p_playlist, int i)
PL_ASSERT_LOCKED; PL_ASSERT_LOCKED;
if (p_item->i_children == 0 && p_item == p_sys->p_node) vlc_mutex_lock(&p_sys->pl_lock);
if (p_item->i_children == 0 && p_item == p_sys->p_node) {
vlc_mutex_unlock(&p_sys->pl_lock);
return true; return true;
}
vlc_mutex_unlock(&p_sys->pl_lock);
p_played_item = playlist_CurrentPlayingItem(p_playlist); p_played_item = playlist_CurrentPlayingItem(p_playlist);
if (p_played_item && p_item->p_input && p_played_item->p_input) if (p_played_item && p_item->p_input && p_played_item->p_input)
...@@ -996,11 +1018,13 @@ static int DrawPlaylist(intf_thread_t *p_intf) ...@@ -996,11 +1018,13 @@ static int DrawPlaylist(intf_thread_t *p_intf)
intf_sys_t *p_sys = p_intf->p_sys; intf_sys_t *p_sys = p_intf->p_sys;
playlist_t *p_playlist = pl_Get(p_intf); playlist_t *p_playlist = pl_Get(p_intf);
vlc_mutex_lock(&p_sys->pl_lock);
if (p_sys->b_need_update) if (p_sys->b_need_update)
{ {
PlaylistRebuild(p_intf); PlaylistRebuild(p_intf);
p_sys->b_need_update = false; p_sys->b_need_update = false;
} }
vlc_mutex_unlock(&p_sys->pl_lock);
if (p_sys->b_plidx_follow) if (p_sys->b_plidx_follow)
FindIndex(p_sys, p_playlist); FindIndex(p_sys, p_playlist);
...@@ -1010,7 +1034,9 @@ static int DrawPlaylist(intf_thread_t *p_intf) ...@@ -1010,7 +1034,9 @@ static int DrawPlaylist(intf_thread_t *p_intf)
char c; char c;
playlist_item_t *p_current_item; playlist_item_t *p_current_item;
playlist_item_t *p_item = p_sys->pp_plist[i]->p_item; playlist_item_t *p_item = p_sys->pp_plist[i]->p_item;
vlc_mutex_lock(&p_sys->pl_lock);
playlist_item_t *p_node = p_sys->p_node; playlist_item_t *p_node = p_sys->p_node;
vlc_mutex_unlock(&p_sys->pl_lock);
PL_LOCK; PL_LOCK;
assert(p_item); assert(p_item);
...@@ -1364,7 +1390,9 @@ static bool HandlePlaylistKey(intf_thread_t *p_intf, int key) ...@@ -1364,7 +1390,9 @@ static bool HandlePlaylistKey(intf_thread_t *p_intf, int key)
playlist_RecursiveNodeSort(p_playlist, p_playlist->p_root_onelevel, playlist_RecursiveNodeSort(p_playlist, p_playlist->p_root_onelevel,
SORT_TITLE_NODES_FIRST, SORT_TITLE_NODES_FIRST,
(key == 'o')? ORDER_NORMAL : ORDER_REVERSE); (key == 'o')? ORDER_NORMAL : ORDER_REVERSE);
vlc_mutex_lock(&p_sys->pl_lock);
p_sys->b_need_update = true; p_sys->b_need_update = true;
vlc_mutex_unlock(&p_sys->pl_lock);
return true; return true;
case 'g': case 'g':
...@@ -1386,7 +1414,9 @@ static bool HandlePlaylistKey(intf_thread_t *p_intf, int key) ...@@ -1386,7 +1414,9 @@ static bool HandlePlaylistKey(intf_thread_t *p_intf, int key)
else else
playlist_NodeDelete(p_playlist, p_item, true , false); playlist_NodeDelete(p_playlist, p_item, true , false);
PL_UNLOCK; PL_UNLOCK;
vlc_mutex_lock(&p_sys->pl_lock);
p_sys->b_need_update = true; p_sys->b_need_update = true;
vlc_mutex_unlock(&p_sys->pl_lock);
return true; return true;
} }
...@@ -1408,7 +1438,9 @@ static bool HandlePlaylistKey(intf_thread_t *p_intf, int key) ...@@ -1408,7 +1438,9 @@ static bool HandlePlaylistKey(intf_thread_t *p_intf, int key)
} }
else else
{ {
vlc_mutex_lock(&p_sys->pl_lock);
p_sys->p_node = p_parent; p_sys->p_node = p_parent;
vlc_mutex_unlock(&p_sys->pl_lock);
p_item = NULL; p_item = NULL;
} }
...@@ -1418,7 +1450,9 @@ static bool HandlePlaylistKey(intf_thread_t *p_intf, int key) ...@@ -1418,7 +1450,9 @@ static bool HandlePlaylistKey(intf_thread_t *p_intf, int key)
else else
{ /* We only want to set the current node */ { /* We only want to set the current node */
playlist_Stop(p_playlist); playlist_Stop(p_playlist);
vlc_mutex_lock(&p_sys->pl_lock);
p_sys->p_node = p_pl_item->p_item; p_sys->p_node = p_pl_item->p_item;
vlc_mutex_unlock(&p_sys->pl_lock);
} }
p_sys->b_plidx_follow = true; p_sys->b_plidx_follow = true;
...@@ -1468,7 +1502,9 @@ static bool HandleBrowseKey(intf_thread_t *p_intf, int key) ...@@ -1468,7 +1502,9 @@ static bool HandleBrowseKey(intf_thread_t *p_intf, int key)
return true; return true;
playlist_t *p_playlist = pl_Get(p_intf); playlist_t *p_playlist = pl_Get(p_intf);
vlc_mutex_lock(&p_sys->pl_lock);
playlist_item_t *p_parent = p_sys->p_node; playlist_item_t *p_parent = p_sys->p_node;
vlc_mutex_unlock(&p_sys->pl_lock);
if (!p_parent) if (!p_parent)
{ {
playlist_item_t *p_item; playlist_item_t *p_item;
...@@ -1529,7 +1565,9 @@ static void HandleEditBoxKey(intf_thread_t *p_intf, int key, int box) ...@@ -1529,7 +1565,9 @@ static void HandleEditBoxKey(intf_thread_t *p_intf, int key, int box)
} }
playlist_t *p_playlist = pl_Get(p_intf); playlist_t *p_playlist = pl_Get(p_intf);
vlc_mutex_lock(&p_sys->pl_lock);
playlist_item_t *p_parent = p_sys->p_node, *p_current; playlist_item_t *p_parent = p_sys->p_node, *p_current;
vlc_mutex_unlock(&p_sys->pl_lock);
PL_LOCK; PL_LOCK;
if (!p_parent) if (!p_parent)
...@@ -1820,6 +1858,7 @@ static void Run(intf_thread_t *p_intf) ...@@ -1820,6 +1858,7 @@ static void Run(intf_thread_t *p_intf)
int canc = vlc_savecancel(); int canc = vlc_savecancel();
var_AddCallback(p_playlist, "intf-change", PlaylistChanged, p_intf); var_AddCallback(p_playlist, "intf-change", PlaylistChanged, p_intf);
var_AddCallback(p_playlist, "item-change", ItemChanged, p_intf);
var_AddCallback(p_playlist, "playlist-item-append", PlaylistChanged, p_intf); var_AddCallback(p_playlist, "playlist-item-append", PlaylistChanged, p_intf);
while (vlc_object_alive(p_intf) && !p_sys->b_exit) while (vlc_object_alive(p_intf) && !p_sys->b_exit)
...@@ -1830,6 +1869,7 @@ static void Run(intf_thread_t *p_intf) ...@@ -1830,6 +1869,7 @@ static void Run(intf_thread_t *p_intf)
} }
var_DelCallback(p_playlist, "intf-change", PlaylistChanged, p_intf); var_DelCallback(p_playlist, "intf-change", PlaylistChanged, p_intf);
var_DelCallback(p_playlist, "item-change", ItemChanged, p_intf);
var_DelCallback(p_playlist, "playlist-item-append", PlaylistChanged, p_intf); var_DelCallback(p_playlist, "playlist-item-append", PlaylistChanged, p_intf);
vlc_restorecancel(canc); vlc_restorecancel(canc);
} }
...@@ -1855,6 +1895,7 @@ static int Open(vlc_object_t *p_this) ...@@ -1855,6 +1895,7 @@ static int Open(vlc_object_t *p_this)
msg_cb_data->p_sys = p_sys; msg_cb_data->p_sys = p_sys;
vlc_mutex_init(&p_sys->msg_lock); vlc_mutex_init(&p_sys->msg_lock);
vlc_mutex_init(&p_sys->pl_lock);
p_sys->i_msgs = 0; p_sys->i_msgs = 0;
memset(p_sys->msgs, 0, sizeof p_sys->msgs); memset(p_sys->msgs, 0, sizeof p_sys->msgs);
p_sys->p_sub = msg_Subscribe(p_intf->p_libvlc, MsgCallback, msg_cb_data); p_sys->p_sub = msg_Subscribe(p_intf->p_libvlc, MsgCallback, msg_cb_data);
...@@ -1916,6 +1957,7 @@ static void Close(vlc_object_t *p_this) ...@@ -1916,6 +1957,7 @@ static void Close(vlc_object_t *p_this)
msg_Unsubscribe(p_sys->p_sub); msg_Unsubscribe(p_sys->p_sub);
vlc_mutex_destroy(&p_sys->msg_lock); vlc_mutex_destroy(&p_sys->msg_lock);
vlc_mutex_destroy(&p_sys->pl_lock);
for(unsigned i = 0; i < sizeof p_sys->msgs / sizeof *p_sys->msgs; i++) for(unsigned i = 0; i < sizeof p_sys->msgs / sizeof *p_sys->msgs; i++)
if (p_sys->msgs[i]) if (p_sys->msgs[i])
msg_Free(p_sys->msgs[i]); msg_Free(p_sys->msgs[i]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment