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?
libmpdclient: use size_t and ssize_t
When working with buffer lengths and recv() results, we should declare
size_t and ssize_t variables, otherwise the code may fail on 64 bit
machines.
When working with buffer lengths and recv() results, we should declare
size_t and ssize_t variables, otherwise the code may fail on 64 bit
machines.
screen: removed empty methods
Declaring empty methods is of no use. If a method is empty, we should
set it to NULL in the screen_functions struct.
Declaring empty methods is of no use. If a method is empty, we should
set it to NULL in the screen_functions struct.
screen: removed NULL check
Since the screen's initialization is guaranteed, we can remove the
NULL check in center_playing_item().
Since the screen's initialization is guaranteed, we can remove the
NULL check in center_playing_item().
screen_artist: fix compilation errors
Unfortunately when I fixed the GCC warnings and refactored lots of the
code, the "artist" screen was disabled. This patch applies all API
changes and fixes all warnings.
Unfortunately when I fixed the GCC warnings and refactored lots of the
code, the "artist" screen was disabled. This patch applies all API
changes and fixes all warnings.
code style, indent with tabs IV
Follow the same code style als MPD itself.
Follow the same code style als MPD itself.
browse: when deselecting, don't search twice
When deselecting a song in the file browser, the local variable "idx"
was initialized and overwritten. Remove the initialization.
When deselecting a song in the file browser, the local variable "idx"
was initialized and overwritten. Remove the initialization.
playlist: added playlist_remove_reuse()
playlist_remove_reuse() removes a song from the playlist, but does not
free it.
Use this function in mpdclient_cmd_delete() to fix a segmentation
fault: the song pointer was still used after it was freed, by passing
it to mpdclient_playlist_callback(). Free the song manually now.
Reorganize and simply some code in mpdclient_cmd_delete().
playlist_remove_reuse() removes a song from the playlist, but does not
free it.
Use this function in mpdclient_cmd_delete() to fix a segmentation
fault: the song pointer was still used after it was freed, by passing
it to mpdclient_playlist_callback(). Free the song manually now.
Reorganize and simply some code in mpdclient_cmd_delete().
make several functions return void
playlist: use playlist_get() instead of playlist_get_song()
list_window: don't reset *highlight to 0
Since the list_window code sets highlight to 0 before it calls the
list_callback, the callback itself doesn't have to reset the flag.
Since the list_window code sets highlight to 0 before it calls the
list_callback, the callback itself doesn't have to reset the flag.
lyrics: don't check current.lines==NULL
current.lines is always initialized, and cannot be NULL, no need to
check it.
current.lines is always initialized, and cannot be NULL, no need to
check it.
help: return early from list_callback()
help: converted help_text_rows to a macro
Why bother counting the elements of help_text[] (with sentinel) at
runtime, when the compiler can do it at compile time?
Why bother counting the elements of help_text[] (with sentinel) at
runtime, when the compiler can do it at compile time?
lyrics: removed lyrics_text_rows, use current.lines->len instead
lyrics_text_rows wasn't set anyway, I somehow removed the code in a
patch some time ago.
lyrics_text_rows wasn't set anyway, I somehow removed the code in a
patch some time ago.
list_window: added list_window_center()
Merge code which used to be duplicated in the screens "play", "help",
"lyrics".
Merge code which used to be duplicated in the screens "play", "help",
"lyrics".
list_window: added list_window_scroll_cmd()
It is similar to list_window_cmd(), but it scrolls the window instead
of moving the selection. It is used by the "lyrics" and the "help"
screen.
It is similar to list_window_cmd(), but it scrolls the window instead
of moving the selection. It is used by the "lyrics" and the "help"
screen.
list_window: set repaint at the end of list_window_cmd()
screen: return early in switch_screen_mode() on error
When the selected screen does not exist, return before calling
close().
When the selected screen does not exist, return before calling
close().
screen: added macro NUM_SCREENS
Since the number of screens is known at compile time, define a macro
which calculates this, instead of having a sentinel element.
Since the number of screens is known at compile time, define a macro
which calculates this, instead of having a sentinel element.
screen: close only current screen in screen_exit()
Screens which are not active have already been closed, or have never
been opened. Don't call close again on them.
Screens which are not active have already been closed, or have never
been opened. Don't call close again on them.
screen: don't store "screen" as a pointer
There can only be onle screen struct instance at a time. Declare it
as a static struct, instead of a pointer to the struct. This
simplifies all accesses, and avoids the dynamic allocation.
There can only be onle screen struct instance at a time. Declare it
as a static struct, instead of a pointer to the struct. This
simplifies all accesses, and avoids the dynamic allocation.
screen: moved code to find_configured_screen()
screen: mode_fn cannot be NULL, removed checks
At startup, mode_fn is initialized with &screen_playlist, and it will
never be reset to NULL. Remove all checks.
At startup, mode_fn is initialized with &screen_playlist, and it will
never be reset to NULL. Remove all checks.
screen: before calling update(), check if it is defined
That seems to be a fn->paint was checked, then the code called
fn->update(). Fix this.
That seems to be a fn->paint was checked, then the code called
fn->update(). Fix this.
screen: removed screen_functions.get_lw()
If it is really important to set the curser, we should think of a
better way, instead of exporting one non-generic method. For now,
just set the cursor to the origin.
If it is really important to set the curser, we should think of a
better way, instead of exporting one non-generic method. For now,
just set the cursor to the origin.
replaced get_screen_X() with static screen_functions variable
Compile time initialization saves resources, compared to run-time
initialization. Declare all screen_function structs as global
variables, and remove all get functions.
Compile time initialization saves resources, compared to run-time
initialization. Declare all screen_function structs as global
variables, and remove all get functions.