screen_file: removed update() method
Repaint the file screen on demand. No need for the update() method
anymore.
Repaint the file screen on demand. No need for the update() method
anymore.
screen_artist: removed update() method
Repaint the artist screen on demand. No need for the update() method
anymore.
Repaint the artist screen on demand. No need for the update() method
anymore.
screen_playlist: don't repaint in update()
Repaint the playlist window on demand. Don't repaint it
unconditionally in play_update().
Repaint the playlist window on demand. Don't repaint it
unconditionally in play_update().
list_window: removed property "repaint"
The property "repaint" is never read, since all callers repaint the
list window on demand.
The property "repaint" is never read, since all callers repaint the
list window on demand.
screen_lyrics: removed the "update" method
Automatically redraw the screen on demand, whenever data has changed.
Automatically redraw the screen on demand, whenever data has changed.
screen_lyrics: added lyrics_repaint()
lyrics_repaint() or lyrics_repaint_if_active() are called after data
has changed, and the screen needs an update.
lyrics_repaint() or lyrics_repaint_if_active() are called after data
has changed, and the screen needs an update.
screen_keydef: removed the update() method
Automatically redraw the list on demand, whenever data has changed.
Automatically redraw the list on demand, whenever data has changed.
screen: don't pass screen pointer to method paint()
None of the paint() implementations actually use the screen pointer -
remove it from the method signature.
None of the paint() implementations actually use the screen pointer -
remove it from the method signature.
screen: don't call wrefresh() in methods paint() and update()
screen_paint() and screen_update() are responsible for refreshing the
screen. We can remove all wrefresh() and wnoutrefresh() invocations
from all paint() and update() method implementations.
screen_paint() and screen_update() are responsible for refreshing the
screen. We can remove all wrefresh() and wnoutrefresh() invocations
from all paint() and update() method implementations.
list_window: removed property "clear"
Without clearing previous screen contents, there may be corruptions,
make this mandatory and optimize screen clearing.
Without clearing previous screen contents, there may be corruptions,
make this mandatory and optimize screen clearing.
code style, indent with tabs X
Follow the same code style als MPD itself.
Follow the same code style als MPD itself.
Makefile: don't install disabled lyrics plugins
Don't install the lyrics plugins if the lyrics screen is disabled.
Don't install the lyrics plugins if the lyrics screen is disabled.
configure: fix default lyrics plugin directory
When the user does not specify "--prefix", ${prefix} is "NONE". This
breaks the default lyrics plugin directory, which was
"${prefix}/lib/ncmpc/lyrics". Fall back to ${ac_default_prefix} if
${prefix} is NONE.
When the user does not specify "--prefix", ${prefix} is "NONE". This
breaks the default lyrics plugin directory, which was
"${prefix}/lib/ncmpc/lyrics". Fall back to ${ac_default_prefix} if
${prefix} is NONE.
Makefile: honor DESTDIR
When installing lyrics plugins, I forgot to honor $(DESTDIR) if set.
When installing lyrics plugins, I forgot to honor $(DESTDIR) if set.
lyrics: print text in UTF-8
Python defaults to sending ASCII characters, and aborts if there are
non-ASCII characters in the string. Unfortunately, due to "C.UTF-8"
being not defined, we cannot reliably make Python use UTF-8, without
further locale settings. Thus, work around this mess by manually
encoding the result to UTF-8 in the script.
Python defaults to sending ASCII characters, and aborts if there are
non-ASCII characters in the string. Unfortunately, due to "C.UTF-8"
being not defined, we cannot reliably make Python use UTF-8, without
further locale settings. Thus, work around this mess by manually
encoding the result to UTF-8 in the script.
screen_play: use list_window_check_selected()
Instead of manually adjusting the selection, let list_window.c do it.
Instead of manually adjusting the selection, let list_window.c do it.
list_window: converted several public functions to static
There are lots of functions not being used outside of list_window.c.
Make them static to make it easier for gcc to optimize.
There are lots of functions not being used outside of list_window.c.
Make them static to make it easier for gcc to optimize.
lyrics: configurable global plugin directory
The lyrics library loads all plugins from the directory configured
with "--with-lyrics-plugin-dir".
The lyrics library loads all plugins from the directory configured
with "--with-lyrics-plugin-dir".
configure: removed unused lyrics checks
Removed the commented checks for libraries which aren't being used
anymore by the new lyrics code.
Removed the commented checks for libraries which aren't being used
anymore by the new lyrics code.
configure: removed gthread test
Threading has been disabled when I overhauled lyrics support. Remove
all libgthread checks from configure.ac.
Threading has been disabled when I overhauled lyrics support. Remove
all libgthread checks from configure.ac.
lyrics: added callback
Instead of letting our caller poll lyrics_result(), call it back as
soon as we have the result.
Instead of letting our caller poll lyrics_result(), call it back as
soon as we have the result.
lyrics: reimplemented with aynchronous I/O
Instead of creating a thread for handling lyrics plugin data, register
a channel at the glib main loop.
Instead of creating a thread for handling lyrics plugin data, register
a channel at the glib main loop.
screen_lyrics: set current.song
The variable current.song was never set, thus the cache did not work.
Don't reset it in screen_lyrics_clear() (which is called from
screen_lyrics_set()).
The variable current.song was never set, thus the cache did not work.
Don't reset it in screen_lyrics_clear() (which is called from
screen_lyrics_set()).
autogen.sh: don't ignore errors
Set the shell option "-e" to abort when one of the tools fails.
Set the shell option "-e" to abort when one of the tools fails.
options: added constant option_table_size
Instead of checking for the sentinel at the end of the option table,
check the option_table_size constant.
Instead of checking for the sentinel at the end of the option table,
check the option_table_size constant.
options: constant options_table
Make the options_table constant, since it is never modified.
Make the options_table constant, since it is never modified.
screen_utils: simplified call to wreadln_masked()
If prompt is NULL, do not add a second call to wreadln_masked() with a
literal string, but assign this literal string to the variable
"prompt". This saves several bytes in the compiled binary.
If prompt is NULL, do not add a second call to wreadln_masked() with a
literal string, but assign this literal string to the variable
"prompt". This saves several bytes in the compiled binary.
screen_utils: hide cursor after screen_read_password()
The call to curs_set(0) in screen_read_password() was dead code,
because it was after the function return. Repair that.
The call to curs_set(0) in screen_read_password() was dead code,
because it was after the function return. Repair that.
screen: unsigned integers for screen dimensions
Store screen width and height as unsigned integer.
Store screen width and height as unsigned integer.
code style, indent with tabs IX
Follow the same code style als MPD itself.
Follow the same code style als MPD itself.
screen: simplified CMD_SCREEN_UPDATE handlers
Since screen.c has default code for CMD_SCREEN_UPDATE, return 0 from
the command handlers and let screen.c do the rest.
Since screen.c has default code for CMD_SCREEN_UPDATE, return 0 from
the command handlers and let screen.c do the rest.
screen: don't set list_window->repaint
Several screens ignore the attribute list_window->repaint. Don't set
it there. It will be replaced with a more intelligent repaint
algorithm later.
Several screens ignore the attribute list_window->repaint. Don't set
it there. It will be replaced with a more intelligent repaint
algorithm later.
screen: removed window.cur_action_id
The variable cur_action_id is not used at all.
The variable cur_action_id is not used at all.
screen: last_cmd should be a command_t
last_cmd stores the previous command sent to the screen. It is not a
timestamp, and its type should be command_t.
last_cmd stores the previous command sent to the screen. It is not a
timestamp, and its type should be command_t.
screen: moved input_timestamp to screen_play.c
Since the input_timestamp is only used by screen_play, move it there.
Since the input_timestamp is only used by screen_play, move it there.
screen: moved list_window mouse code to list_window.c
Move the portion of screen_get_mouse_event() which handles list_window
clicks to list_window.c. The code contained a NULL pointer
dereference, which is now fixed.
Move the portion of screen_get_mouse_event() which handles list_window
clicks to list_window.c. The code contained a NULL pointer
dereference, which is now fixed.
screen: moved code to ncu.c
Moved basic libncurses initialization to ncu.c and ncu.h. Keep
generic code out of screen.c.
Moved basic libncurses initialization to ncu.c and ncu.h. Keep
generic code out of screen.c.
main: free keyboard IO channel
Before terminating ncmpc, free the keyboard GIOChannel object.
Before terminating ncmpc, free the keyboard GIOChannel object.
configure: modern AC_INIT and AM_INIT_AUTOMAKE invocation
Provide program name and version in AC_INIT. Add the option
"dist-bzip2" to AM_INIT_AUTOMAKE.
Provide program name and version in AC_INIT. Add the option
"dist-bzip2" to AM_INIT_AUTOMAKE.
added option "welcome-screen-list"
"welcome-screen-list" shows the screen list in the top row shortly
after startup, and is enabled by default.
"welcome-screen-list" shows the screen list in the top row shortly
after startup, and is enabled by default.
browse: ensure that filelist!=NULL
There are several places where browser.filelist can become NULL.
Catch that everywhere and generate an empty filelist in this case.
There are several places where browser.filelist can become NULL.
Catch that everywhere and generate an empty filelist in this case.
browser: check if the selection is valid
Don't call filelist_get() with an invalid index.
Don't call filelist_get() with an invalid index.
support: added assertions
Check the function parameters.
Check the function parameters.
screen_artist: check if anything is selected
Don't try to call add_query() with no valid selection, this causes a
segfault. This usually happens when ncmpc isn't connected.
Don't try to call add_query() with no valid selection, this causes a
segfault. This usually happens when ncmpc isn't connected.
libmpdclient: added another connection->sock check
Check if connection->sock is valid in mpd_executeCommand().
Check if connection->sock is valid in mpd_executeCommand().
mpdclient: check errorCode only if MPD_ERROR_ACK is set
connection->errorCode has an undefined value when connection->error is
not MPD_ERROR_ACK. Read it only if MPD_ERROR_ACK is set, to make
valgrind happy.
connection->errorCode has an undefined value when connection->error is
not MPD_ERROR_ACK. Read it only if MPD_ERROR_ACK is set, to make
valgrind happy.
mpdclient: fix memory leak in mpdclient_finish_command()
During authentication, the message pointer was allocated, but never
freed. Allocate it only if it is really used (and freed).
During authentication, the message pointer was allocated, but never
freed. Allocate it only if it is really used (and freed).
code style, indent with tabs VIII
Follow the same code style als MPD itself.
Follow the same code style als MPD itself.
libmpdclient: check connection->sock >= 0
mpd_wait() must not be called when the socket is dead; add an
assertion there. In mpd_recv(), add a run-time check.
mpd_wait() must not be called when the socket is dead; add an
assertion there. In mpd_recv(), add a run-time check.
added optional bitrate display to status bar
If visible-bitrate is enabled, then the current bitrate will be drawn next
to the song time in the status bar. By default it will not be displayed.
If visible-bitrate is enabled, then the current bitrate will be drawn next
to the song time in the status bar. By default it will not be displayed.
wreadln: adding additional line editing binds
Adding some GNU readline-style binds. These are ^B/^F to move the cursor
back/forward, and ^N/^P to go to the next/previous line.
Adding some GNU readline-style binds. These are ^B/^F to move the cursor
back/forward, and ^N/^P to go to the next/previous line.
ncmpc.1: -k is the short version of --key-file, not -P
generate po/Makefile.in instead of bundling it
The previously bundled po/Makefile.in would use predefined variables that
should be set by the configure script. f.e., $prefix was defined as
/usr/local, and caused po files to always be installed there instead of in
the prefix given to ./configure.
The previously bundled po/Makefile.in would use predefined variables that
should be set by the configure script. f.e., $prefix was defined as
/usr/local, and caused po files to always be installed there instead of in
the prefix given to ./configure.
configure.ac: don't enable the lyrics screen by default
The configure help text already said the lyrics screen was disabled by
default. Now it actually will be.
The configure help text already said the lyrics screen was disabled by
default. Now it actually will be.
autogen: don't run ./configure if $NOCONFIGURE is set
mpdclient: don't call screen_status_message()
The caller should decide how to display error messages.
The caller should decide how to display error messages.
Adding crop feature in ncmpc
The "crop" command deletes all songs from the playlist, except the one
currently being played.
The "crop" command deletes all songs from the playlist, except the one
currently being played.
screen_help: removed update() method
Why redraw the help screen when nothing has changed? Redraw it only
after help_cmd(), and when explicitly requested (help_paint()).
Why redraw the help screen when nothing has changed? Redraw it only
after help_cmd(), and when explicitly requested (help_paint()).
filelist: fix segfault during filelist_sort()
When I converted the filelist from GList to GPtrArray, I missed that
the GCompareFunc does not actually get the pointers from
g_ptr_array_sort(), but pointers to the pointers... run
g_ptr_array_sort_with_data() instead with a wrapper function.
When I converted the filelist from GList to GPtrArray, I missed that
the GCompareFunc does not actually get the pointers from
g_ptr_array_sort(), but pointers to the pointers... run
g_ptr_array_sort_with_data() instead with a wrapper function.
filelist: free entries with g_slice_free()
Somehow I forgot about changing free() to g_slice_free() in the
previous patch...
Somehow I forgot about changing free() to g_slice_free() in the
previous patch...
filelist: allocate entries with g_slice_alloc()
In this case, slices are faster. Also fix a memory leak in
filelist_prepend() which I simply forgot about in the last patch set.
In this case, slices are faster. Also fix a memory leak in
filelist_prepend() which I simply forgot about in the last patch set.
properly configure M4 macro dir
Add information about the M4 macro dir ./m4/ to both configure.ac and
Makefile.am.
Add information about the M4 macro dir ./m4/ to both configure.ac and
Makefile.am.
filelist: use GPtrArray instead of GList
Since we do a lot of indexed accesses to the filelist, a linked list
doesn't seem appropriate. Use GPtrArray instead.
Since we do a lot of indexed accesses to the filelist, a linked list
doesn't seem appropriate. Use GPtrArray instead.
browser: added function browser_get_selected()
browser_get_selected() checks if there is a file list and a valid
selection, and returns the selected entry.
browser_get_selected() checks if there is a file list and a valid
selection, and returns the selected entry.
screen_search: free second file list
Fix a memory leak: the concatened list was never freed.
Fix a memory leak: the concatened list was never freed.
filelist: provide more functions for working with a filelist
Avoid direct accesses to the filelist struct, provide an API for that.
Avoid direct accesses to the filelist struct, provide an API for that.
filelist: drop "mpdclient" prefix
The separate filelist library does not depend on mpdclient, so the
prefix is superfluous.
The separate filelist library does not depend on mpdclient, so the
prefix is superfluous.
browser: use mpdclient_filelist_find_song() in set_highlight()
A song should not be twice in the browser. Simplify set_highlight()
by finding the entry with mpdclient_filelist_find_song().
A song should not be twice in the browser. Simplify set_highlight()
by finding the entry with mpdclient_filelist_find_song().
browser: song must not be NULL in set_highlight()
The caller must not pass NULL to set_highlight(). Replaced check with
assertion.
The caller must not pass NULL to set_highlight(). Replaced check with
assertion.
filelist: song must not be NULL
A caller must not pass NULL to mpdclient_filelist_find_song().
Replace the check with an assertion.
A caller must not pass NULL to mpdclient_filelist_find_song().
Replace the check with an assertion.
mpdclient: moved code to filelist.c
Move everything which is solely filelist related to filelist.c and
filelist.h. Fix the indentation of that file, and provide the struct
name "filelist". Don't clear data in mpdclient_filelist_free() before
calling g_free(). Constify the "song" parameter to
mpdclient_filelist_find_song().
Move everything which is solely filelist related to filelist.c and
filelist.h. Fix the indentation of that file, and provide the struct
name "filelist". Don't clear data in mpdclient_filelist_free() before
calling g_free(). Constify the "song" parameter to
mpdclient_filelist_find_song().
code style, indent with tabs VII
Follow the same code style als MPD itself.
Follow the same code style als MPD itself.
fix terminal resizing (SIGWINCH)
When I replaced ncmpc's old main loop with g_main_loop from libglib,
SIGWINCH (i.e. window resizing) stopped working. This regression was
caused by the fact that ncurses' wgetch() function was only called
when there was actually data on STDIN. wgetch() has several side
effects besides reading data from STDIN, for example it checks whether
there has been a window resize.
Fix this with a custom SIGWINCH handler.
When I replaced ncmpc's old main loop with g_main_loop from libglib,
SIGWINCH (i.e. window resizing) stopped working. This regression was
caused by the fact that ncurses' wgetch() function was only called
when there was actually data on STDIN. wgetch() has several side
effects besides reading data from STDIN, for example it checks whether
there has been a window resize.
Fix this with a custom SIGWINCH handler.
removed the clock screen
Why should an audio player display a large clock?
Why should an audio player display a large clock?
screen_browser: removed entity.song!=NULL check
It is guaranteed that the "song" attribute is not NULL, remove the
check.
It is guaranteed that the "song" attribute is not NULL, remove the
check.
screen_browser: removed redundant highlight check
browser_select_entry() checked the entry's "highlight" flag twice: the
first time, it was toggled, and the second time, action was performed
based on the flag. Merge the two checks.
browser_select_entry() checked the entry's "highlight" flag twice: the
first time, it was toggled, and the second time, action was performed
based on the flag. Merge the two checks.
screen_browser: removed redundant entity type checks
The function browser_select_entry() returns early when the entity type
is not "SONG". No need to double check that.
The function browser_select_entry() returns early when the entity type
is not "SONG". No need to double check that.
screen_browser: moved code to browser_select_entry()
Moved code from browser_handle_select(). Call this new function also
from browser_handle_select_all(). This fixes a bug in select_all():
it actually did not select all, but stopped after the first song.
Moved code from browser_handle_select(). Call this new function also
from browser_handle_select_all(). This fixes a bug in select_all():
it actually did not select all, but stopped after the first song.
screen_browser: removed commented code
screen_browser: moved code to browser_playlist_changed()
Merge code from all 3 browser screens into one generic browser
function.
Merge code from all 3 browser screens into one generic browser
function.
screen_browser: moved code to screen_browser.c
Isolate the generic browser code from the directory browser.
Isolate the generic browser code from the directory browser.
screen_browser: added struct screen_browser
We are going to separate the browser functions from screen_file.c.
Move all variables which are going to be needed by this code.
We are going to separate the browser functions from screen_file.c.
Move all variables which are going to be needed by this code.
renamed screen_browse.h to screen_browser.h
code style, indent with tabs VI
Follow the same code style als MPD itself.
Follow the same code style als MPD itself.
added support for wide characters
This patch was taken from bug 476, author unknown
(http://www.musicpd.org/mantis/view.php?id=476). It changes the
definition of my_strlen(): instead of returning the number of UTF-8
characters, it counts the number of terminal cells occupied by a
string.
This patch was taken from bug 476, author unknown
(http://www.musicpd.org/mantis/view.php?id=476). It changes the
definition of my_strlen(): instead of returning the number of UTF-8
characters, it counts the number of terminal cells occupied by a
string.
code style, indent with tabs V
Follow the same code style als MPD itself.
Follow the same code style als MPD itself.
screen: don't handle CMD_PLAY
CMD_PLAY is mapped to the Enter key by default. Some screens
(mis-)use it for navigation, for entering a directory. The playlist
screen actually plays the file under the cursor. On all other
screens, pressing Enter may be confusing, since it is more of a
"confirmation" key instead of "play". We should probaby add
CMD_CONFIRM later, but for now, disable the general CMD_PLAY handler
in screen.c. This fixes bug 240.
CMD_PLAY is mapped to the Enter key by default. Some screens
(mis-)use it for navigation, for entering a directory. The playlist
screen actually plays the file under the cursor. On all other
screens, pressing Enter may be confusing, since it is more of a
"confirmation" key instead of "play". We should probaby add
CMD_CONFIRM later, but for now, disable the general CMD_PLAY handler
in screen.c. This fixes bug 240.
libmpdclient: added resolver library
The resolver library provides unified access to all resolvers
(getaddrinfo(), gethostbyname(), Unix domain sockets). Like
getaddrinfo(), it can return more than one address for a host name.
This fixes bug 1517 (http://www.musicpd.org/mantis/view.php?id=1517).
The resolver library provides unified access to all resolvers
(getaddrinfo(), gethostbyname(), Unix domain sockets). Like
getaddrinfo(), it can return more than one address for a host name.
This fixes bug 1517 (http://www.musicpd.org/mantis/view.php?id=1517).
quit with g_main_loop_quit()
Call g_main_loop_quit() on CMD_QUIT, instead of exit() with an
atexit() handler.
Call g_main_loop_quit() on CMD_QUIT, instead of exit() with an
atexit() handler.
playlist: reset id in playlist_clear()
The playlist is reset when the connection to the MPD server is
closed. After a successful reconnect, we have to reload the full
playlist. To remember this, also reset the id attribute.
The playlist is reset when the connection to the MPD server is
closed. After a successful reconnect, we have to reload the full
playlist. To remember this, also reset the id attribute.
playlist: removed "updated" flag
The caller may check the playlist.id instead of checking the old
"updated" flag.
The caller may check the playlist.id instead of checking the old
"updated" flag.
use the glib main event loop
This big patch replaces our custom main loop with the event based glib
main loop. This has several advantages: we can make all the tiny code
bits in the main loop independent from each others, we can add
additional file descriptors for polling (e.g. the mpdclient socket).
We don't need the ncurses timeout() anymore, because glib will poll
stdin for us.
This big patch replaces our custom main loop with the event based glib
main loop. This has several advantages: we can make all the tiny code
bits in the main loop independent from each others, we can add
additional file descriptors for polling (e.g. the mpdclient socket).
We don't need the ncurses timeout() anymore, because glib will poll
stdin for us.
screen: check MPD status only if connected
Fix several segmentation faults: when the connection to the MPD server
is lost, there were NULL pointer dereferences because
client->status==NULL. Check before accessing it.
Fix several segmentation faults: when the connection to the MPD server
is lost, there were NULL pointer dereferences because
client->status==NULL. Check before accessing it.
screen: moved code to screen_client_cmd()
Move all command handlers which need a connection to the MPD server to
screen_client_cmd(). This will allow us to unify error handling
later.
Move all command handlers which need a connection to the MPD server to
screen_client_cmd(). This will allow us to unify error handling
later.
main: connect while UI is displayed
Display the UI always, and show connection errors there. This fixes a
lot of consistency problems: error messages used to be printed to
stderr, but afterwards, the atexit() handlers deinitialized ncurses
and the screen was cleared. This patch is still problematic, but
constitutes a good step forward.
Display the UI always, and show connection errors there. This fixes a
lot of consistency problems: error messages used to be printed to
stderr, but afterwards, the atexit() handlers deinitialized ncurses
and the screen was cleared. This patch is still problematic, but
constitutes a good step forward.
libmpdclient: moved code to mpd_recv(), mpd_wait()
Create generic utility functions for doint I/O: two wait functions,
and mpd_recv() fills the input buffer. These functions are used in
mpd_newConnection() and mpd_getNextReturnElement().
Create generic utility functions for doint I/O: two wait functions,
and mpd_recv() fills the input buffer. These functions are used in
mpd_newConnection() and mpd_getNextReturnElement().
libmpdclient: smaller input buffer
Even for large responses, 16kB should be enough. There is no
performance gain for larger buffers, even if MPD is local.
Even for large responses, 16kB should be enough. There is no
performance gain for larger buffers, even if MPD is local.
libmpdclient: smaller error buffer
512 characters should be well enough for error messages which are
actually being displayed somewhere. Use sizeof(errorStr) instead of
MPD_BUFFER_MAX_LENGTH everywhere. Do proper length checking when
copying the output buffer to errorStr.
512 characters should be well enough for error messages which are
actually being displayed somewhere. Use sizeof(errorStr) instead of
MPD_BUFFER_MAX_LENGTH everywhere. Do proper length checking when
copying the output buffer to errorStr.
libmpdclient: use memmove() instead of strcpy() for moving the buffer
In general, don't treat the input buffer as a null-terminated string:
don't append '\0', don't use strchr() and strtok(). To delete
consumed portions of the buffer, strcpy() is bad anyway, because it
does not allow overlapping buffers.
In general, don't treat the input buffer as a null-terminated string:
don't append '\0', don't use strchr() and strtok(). To delete
consumed portions of the buffer, strcpy() is bad anyway, because it
does not allow overlapping buffers.
libmpdclient: don't strdup() MPD's welcome message
Why bother duplicating the buffer, when we can simply parse the
response directly from the input buffer?
Why bother duplicating the buffer, when we can simply parse the
response directly from the input buffer?