From d0c3fa015039e005af658619fd7b4289c9abcd6f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 28 Sep 2012 00:40:00 +0200 Subject: main: use C++ compiler --- src/DatabasePlaylist.cxx | 2 +- src/Main.cxx | 561 +++++++++++++++++++++++++++++++++++++++++++++++ src/Main.hxx | 74 +++++++ src/OtherCommands.cxx | 2 +- src/PlaylistCommands.cxx | 2 +- src/PlaylistFile.cxx | 2 +- src/PlaylistFile.h | 104 --------- src/PlaylistFile.hxx | 94 ++++++++ src/PlaylistMapper.cxx | 2 +- src/PlaylistPrint.cxx | 2 +- src/PlaylistSave.cxx | 2 +- src/Win32Main.cxx | 157 +++++++++++++ src/client_event.c | 2 +- src/listen.c | 2 +- src/main.c | 553 ---------------------------------------------- src/main.h | 74 ------- src/main_win32.c | 154 ------------- src/player_control.c | 2 +- src/player_thread.c | 2 +- src/playlist_global.c | 2 +- src/sig_handlers.c | 2 +- src/update.c | 2 +- src/update_remove.c | 2 +- 23 files changed, 901 insertions(+), 900 deletions(-) create mode 100644 src/Main.cxx create mode 100644 src/Main.hxx delete mode 100644 src/PlaylistFile.h create mode 100644 src/PlaylistFile.hxx create mode 100644 src/Win32Main.cxx delete mode 100644 src/main.c delete mode 100644 src/main.h delete mode 100644 src/main_win32.c (limited to 'src') diff --git a/src/DatabasePlaylist.cxx b/src/DatabasePlaylist.cxx index 3020b3274..fb477e83b 100644 --- a/src/DatabasePlaylist.cxx +++ b/src/DatabasePlaylist.cxx @@ -20,7 +20,7 @@ #include "config.h" #include "DatabasePlaylist.hxx" #include "DatabaseSelection.hxx" -#include "PlaylistFile.h" +#include "PlaylistFile.hxx" #include "DatabaseGlue.hxx" #include "DatabasePlugin.hxx" diff --git a/src/Main.cxx b/src/Main.cxx new file mode 100644 index 000000000..057551391 --- /dev/null +++ b/src/Main.cxx @@ -0,0 +1,561 @@ +/* + * Copyright (C) 2003-2012 The Music Player Daemon Project + * http://www.musicpd.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 "config.h" +#include "Main.hxx" +#include "PlaylistFile.hxx" +#include "chunk.h" + +extern "C" { +#include "daemon.h" +#include "io_thread.h" +#include "client.h" +#include "client_idle.h" +#include "idle.h" +#include "AllCommands.h" +#include "playlist.h" +#include "database.h" +#include "update.h" +#include "player_thread.h" +#include "listen.h" +#include "cmdline.h" +#include "conf.h" +#include "path.h" +#include "mapper.h" +#include "player_control.h" +#include "stats.h" +#include "sig_handlers.h" +#include "audio_config.h" +#include "output_all.h" +#include "volume.h" +#include "log.h" +#include "permission.h" +#include "pcm_resample.h" +#include "replay_gain_config.h" +#include "decoder_list.h" +#include "input_init.h" +#include "playlist_list.h" +#include "state_file.h" +#include "tag.h" +#include "zeroconf.h" +#include "event_pipe.h" +} + +#include "mpd_error.h" + +extern "C" { + +#ifdef ENABLE_INOTIFY +#include "inotify_update.h" +#endif + +#ifdef ENABLE_SQLITE +#include "sticker.h" +#endif + +#ifdef ENABLE_ARCHIVE +#include "archive_list.h" +#endif + +} + +#include + +#include +#include +#include +#include + +#ifdef HAVE_LOCALE_H +#include +#endif + +#ifdef WIN32 +#include +#include +#endif + +enum { + DEFAULT_BUFFER_SIZE = 2048, + DEFAULT_BUFFER_BEFORE_PLAY = 10, +}; + +GThread *main_task; +GMainLoop *main_loop; + +GCond *main_cond; + +struct player_control *global_player_control; + +static bool +glue_daemonize_init(const struct options *options, GError **error_r) +{ + GError *error = NULL; + + char *pid_file = config_dup_path(CONF_PID_FILE, &error); + if (pid_file == NULL && error != NULL) { + g_propagate_error(error_r, error); + return false; + } + + daemonize_init(config_get_string(CONF_USER, NULL), + config_get_string(CONF_GROUP, NULL), + pid_file); + g_free(pid_file); + + if (options->kill) + daemonize_kill(); + + return true; +} + +static bool +glue_mapper_init(GError **error_r) +{ + GError *error = NULL; + char *music_dir = config_dup_path(CONF_MUSIC_DIR, &error); + if (music_dir == NULL && error != NULL) { + g_propagate_error(error_r, error); + return false; + } + + char *playlist_dir = config_dup_path(CONF_PLAYLIST_DIR, &error); + if (playlist_dir == NULL && error != NULL) { + g_propagate_error(error_r, error); + return false; + } + + if (music_dir == NULL) + music_dir = g_strdup(g_get_user_special_dir(G_USER_DIRECTORY_MUSIC)); + + mapper_init(music_dir, playlist_dir); + + g_free(music_dir); + g_free(playlist_dir); + return true; +} + +/** + * Returns the database. If this function returns false, this has not + * succeeded, and the caller should create the database after the + * process has been daemonized. + */ +static bool +glue_db_init_and_load(void) +{ + const struct config_param *param = config_get_param("database"); + const struct config_param *path = config_get_param(CONF_DB_FILE); + + if (param != NULL && path != NULL) + g_message("Found both 'database' and '" CONF_DB_FILE + "' setting - ignoring the latter"); + + GError *error = NULL; + bool ret; + + if (!mapper_has_music_directory()) { + if (param != NULL) + g_message("Found database setting without " + CONF_MUSIC_DIR " - disabling database"); + if (path != NULL) + g_message("Found " CONF_DB_FILE " setting without " + CONF_MUSIC_DIR " - disabling database"); + return true; + } + + struct config_param *allocated = NULL; + + if (param == NULL && path != NULL) { + allocated = config_new_param("database", path->line); + config_add_block_param(allocated, "path", + path->value, path->line); + param = allocated; + } + + if (!db_init(param, &error)) + MPD_ERROR("%s", error->message); + + if (allocated != NULL) + config_param_free(allocated); + + ret = db_load(&error); + if (!ret) + MPD_ERROR("%s", error->message); + + /* run database update after daemonization? */ + return !db_is_simple() || db_exists(); +} + +/** + * Configure and initialize the sticker subsystem. + */ +static void +glue_sticker_init(void) +{ +#ifdef ENABLE_SQLITE + GError *error = NULL; + char *sticker_file = config_dup_path(CONF_STICKER_FILE, &error); + if (sticker_file == NULL && error != NULL) + MPD_ERROR("%s", error->message); + + if (!sticker_global_init(sticker_file, &error)) + MPD_ERROR("%s", error->message); + + g_free(sticker_file); +#endif +} + +static bool +glue_state_file_init(GError **error_r) +{ + GError *error = NULL; + + char *path = config_dup_path(CONF_STATE_FILE, &error); + if (path == NULL && error != NULL) { + g_propagate_error(error_r, error); + return false; + } + + state_file_init(path, global_player_control); + g_free(path); + + return true; +} + +/** + * Windows-only initialization of the Winsock2 library. + */ +static void winsock_init(void) +{ +#ifdef WIN32 + WSADATA sockinfo; + int retval; + + retval = WSAStartup(MAKEWORD(2, 2), &sockinfo); + if(retval != 0) + { + MPD_ERROR("Attempt to open Winsock2 failed; error code %d\n", + retval); + } + + if (LOBYTE(sockinfo.wVersion) != 2) + { + MPD_ERROR("We use Winsock2 but your version is either too new " + "or old; please install Winsock 2.x\n"); + } +#endif +} + +/** + * Initialize the decoder and player core, including the music pipe. + */ +static void +initialize_decoder_and_player(void) +{ + const struct config_param *param; + char *test; + size_t buffer_size; + float perc; + unsigned buffered_chunks; + unsigned buffered_before_play; + + param = config_get_param(CONF_AUDIO_BUFFER_SIZE); + if (param != NULL) { + long tmp = strtol(param->value, &test, 10); + if (*test != '\0' || tmp <= 0 || tmp == LONG_MAX) + MPD_ERROR("buffer size \"%s\" is not a positive integer, " + "line %i\n", param->value, param->line); + buffer_size = tmp; + } else + buffer_size = DEFAULT_BUFFER_SIZE; + + buffer_size *= 1024; + + buffered_chunks = buffer_size / CHUNK_SIZE; + + if (buffered_chunks >= 1 << 15) + MPD_ERROR("buffer size \"%li\" is too big\n", (long)buffer_size); + + param = config_get_param(CONF_BUFFER_BEFORE_PLAY); + if (param != NULL) { + perc = strtod(param->value, &test); + if (*test != '%' || perc < 0 || perc > 100) { + MPD_ERROR("buffered before play \"%s\" is not a positive " + "percentage and less than 100 percent, line %i", + param->value, param->line); + } + } else + perc = DEFAULT_BUFFER_BEFORE_PLAY; + + buffered_before_play = (perc / 100) * buffered_chunks; + if (buffered_before_play > buffered_chunks) + buffered_before_play = buffered_chunks; + + global_player_control = pc_new(buffered_chunks, buffered_before_play); +} + +/** + * event_pipe callback function for PIPE_EVENT_IDLE + */ +static void +idle_event_emitted(void) +{ + /* send "idle" notificaions to all subscribed + clients */ + unsigned flags = idle_get(); + if (flags != 0) + client_manager_idle_add(flags); +} + +/** + * event_pipe callback function for PIPE_EVENT_SHUTDOWN + */ +static void +shutdown_event_emitted(void) +{ + g_main_loop_quit(main_loop); +} + +int main(int argc, char *argv[]) +{ +#ifdef WIN32 + return win32_main(argc, argv); +#else + return mpd_main(argc, argv); +#endif +} + +int mpd_main(int argc, char *argv[]) +{ + struct options options; + clock_t start; + bool create_db; + GError *error = NULL; + bool success; + + daemonize_close_stdin(); + +#ifdef HAVE_LOCALE_H + /* initialize locale */ + setlocale(LC_CTYPE,""); +#endif + + g_set_application_name("Music Player Daemon"); + + /* enable GLib's thread safety code */ + g_thread_init(NULL); + + io_thread_init(); + winsock_init(); + idle_init(); + config_global_init(); + + success = parse_cmdline(argc, argv, &options, &error); + if (!success) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + + if (!glue_daemonize_init(&options, &error)) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + + stats_global_init(); + tag_lib_init(); + + if (!log_init(options.verbose, options.log_stderr, &error)) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + + success = listen_global_init(&error); + if (!success) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + + daemonize_set_user(); + + main_task = g_thread_self(); + main_loop = g_main_loop_new(NULL, FALSE); + main_cond = g_cond_new(); + + event_pipe_init(); + event_pipe_register(PIPE_EVENT_IDLE, idle_event_emitted); + event_pipe_register(PIPE_EVENT_SHUTDOWN, shutdown_event_emitted); + + path_global_init(); + + if (!glue_mapper_init(&error)) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + + initPermissions(); + playlist_global_init(); + spl_global_init(); +#ifdef ENABLE_ARCHIVE + archive_plugin_init_all(); +#endif + + if (!pcm_resample_global_init(&error)) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + + decoder_plugin_init_all(); + update_global_init(); + + create_db = !glue_db_init_and_load(); + + glue_sticker_init(); + + command_init(); + initialize_decoder_and_player(); + volume_init(); + initAudioConfig(); + audio_output_all_init(global_player_control); + client_manager_init(); + replay_gain_global_init(); + + if (!input_stream_global_init(&error)) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + + playlist_list_global_init(); + + daemonize(options.daemon); + + setup_log_output(options.log_stderr); + + initSigHandlers(); + + if (!io_thread_start(&error)) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + + initZeroconf(); + + player_create(global_player_control); + + if (create_db) { + /* the database failed to load: recreate the + database */ + unsigned job = update_enqueue(NULL, true); + if (job == 0) + MPD_ERROR("directory update failed"); + } + + if (!glue_state_file_init(&error)) { + g_warning("%s", error->message); + g_error_free(error); + return EXIT_FAILURE; + } + + success = config_get_bool(CONF_AUTO_UPDATE, false); +#ifdef ENABLE_INOTIFY + if (success && mapper_has_music_directory()) + mpd_inotify_init(config_get_unsigned(CONF_AUTO_UPDATE_DEPTH, + G_MAXUINT)); +#else + if (success) + g_warning("inotify: auto_update was disabled. enable during compilation phase"); +#endif + + config_global_check(); + + /* enable all audio outputs (if not already done by + playlist_state_restore() */ + pc_update_audio(global_player_control); + +#ifdef WIN32 + win32_app_started(); +#endif + + /* run the main loop */ + g_main_loop_run(main_loop); + +#ifdef WIN32 + win32_app_stopping(); +#endif + + /* cleanup */ + + g_main_loop_unref(main_loop); + +#ifdef ENABLE_INOTIFY + mpd_inotify_finish(); +#endif + + state_file_finish(global_player_control); + pc_kill(global_player_control); + finishZeroconf(); + client_manager_deinit(); + listen_global_finish(); + playlist_global_finish(); + + start = clock(); + db_finish(); + g_debug("db_finish took %f seconds", + ((float)(clock()-start))/CLOCKS_PER_SEC); + +#ifdef ENABLE_SQLITE + sticker_global_finish(); +#endif + + g_cond_free(main_cond); + event_pipe_deinit(); + + playlist_list_global_finish(); + input_stream_global_finish(); + audio_output_all_finish(); + volume_finish(); + mapper_finish(); + path_global_finish(); + finishPermissions(); + pc_free(global_player_control); + command_finish(); + update_global_finish(); + decoder_plugin_deinit_all(); +#ifdef ENABLE_ARCHIVE + archive_plugin_deinit_all(); +#endif + config_global_finish(); + idle_deinit(); + stats_global_finish(); + io_thread_deinit(); + daemonize_finish(); +#ifdef WIN32 + WSACleanup(); +#endif + + log_deinit(); + return EXIT_SUCCESS; +} diff --git a/src/Main.hxx b/src/Main.hxx new file mode 100644 index 000000000..54916ff4b --- /dev/null +++ b/src/Main.hxx @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2003-2012 The Music Player Daemon Project + * http://www.musicpd.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. + */ + +#ifndef MPD_MAIN_HXX +#define MPD_MAIN_HXX + +#include + +extern GThread *main_task; + +extern GMainLoop *main_loop; + +extern GCond *main_cond; + +extern struct player_control *global_player_control; + +/** + * A entry point for application. + * On non-Windows platforms this is called directly from main() + * On Windows platform this is called from win32_main() + * after doing some initialization. + */ +int mpd_main(int argc, char *argv[]); + +#ifdef WIN32 + +/** + * If program is run as windows service performs nessesary initialization + * and then calls mpd_main() with specified arguments. + * If program is run as a regular application calls mpd_main() immediately. + */ +int +win32_main(int argc, char *argv[]); + +/** + * When running as a service reports to service control manager + * that our service is started. + * When running as a console application enables console handler that will + * trigger PIPE_EVENT_SHUTDOWN when user closes console window + * or presses Ctrl+C. + * This function should be called just before entering main loop. + */ +void +win32_app_started(void); + +/** + * When running as a service reports to service control manager + * that our service is about to stop. + * When running as a console application enables console handler that will + * catch all shutdown requests and ignore them. + * This function should be called just after leaving main loop. + */ +void +win32_app_stopping(void); + +#endif + +#endif diff --git a/src/OtherCommands.cxx b/src/OtherCommands.cxx index 2c714507e..a703a2ffe 100644 --- a/src/OtherCommands.cxx +++ b/src/OtherCommands.cxx @@ -37,7 +37,7 @@ extern "C" { #include "permission.h" } -#include "PlaylistFile.h" +#include "PlaylistFile.hxx" extern "C" { #include "client.h" diff --git a/src/PlaylistCommands.cxx b/src/PlaylistCommands.cxx index f6f43f652..2b5f0b2cf 100644 --- a/src/PlaylistCommands.cxx +++ b/src/PlaylistCommands.cxx @@ -23,7 +23,7 @@ #include "CommandError.hxx" #include "PlaylistPrint.hxx" #include "PlaylistSave.hxx" -#include "PlaylistFile.h" +#include "PlaylistFile.hxx" extern "C" { #include "protocol/argparser.h" diff --git a/src/PlaylistFile.cxx b/src/PlaylistFile.cxx index 462060f0e..cb86c13ac 100644 --- a/src/PlaylistFile.cxx +++ b/src/PlaylistFile.cxx @@ -18,7 +18,7 @@ */ #include "config.h" -#include "PlaylistFile.h" +#include "PlaylistFile.hxx" #include "PlaylistSave.hxx" #include "song.h" diff --git a/src/PlaylistFile.h b/src/PlaylistFile.h deleted file mode 100644 index ddd2a47ec..000000000 --- a/src/PlaylistFile.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2003-2012 The Music Player Daemon Project - * http://www.musicpd.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. - */ - -#ifndef MPD_STORED_PLAYLIST_H -#define MPD_STORED_PLAYLIST_H - -#ifdef __cplusplus -#include -#include -#include -#endif - -#include -#include -#include - -struct song; - -#ifdef __cplusplus - -struct PlaylistFileInfo { - std::string name; - - time_t mtime; -}; - -typedef std::list PlaylistFileList; - -typedef std::vector PlaylistFileContents; - -#endif - -extern bool playlist_saveAbsolutePaths; - -G_BEGIN_DECLS - -/** - * Perform some global initialization, e.g. load configuration values. - */ -void -spl_global_init(void); - -G_END_DECLS - -#ifdef __cplusplus - -/** - * Determines whether the specified string is a valid name for a - * stored playlist. - */ -bool -spl_valid_name(const char *name_utf8); - -/** - * Returns a list of stored_playlist_info struct pointers. Returns - * NULL if an error occurred. - */ -PlaylistFileList -ListPlaylistFiles(GError **error_r); - -PlaylistFileContents -LoadPlaylistFile(const char *utf8path, GError **error_r); - -bool -spl_move_index(const char *utf8path, unsigned src, unsigned dest, - GError **error_r); - -bool -spl_clear(const char *utf8path, GError **error_r); - -bool -spl_delete(const char *name_utf8, GError **error_r); - -bool -spl_remove_index(const char *utf8path, unsigned pos, GError **error_r); - -bool -spl_append_song(const char *utf8path, struct song *song, GError **error_r); - -bool -spl_append_uri(const char *file, const char *utf8file, GError **error_r); - -bool -spl_rename(const char *utf8from, const char *utf8to, GError **error_r); - -#endif - -#endif diff --git a/src/PlaylistFile.hxx b/src/PlaylistFile.hxx new file mode 100644 index 000000000..b20f0d762 --- /dev/null +++ b/src/PlaylistFile.hxx @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2003-2012 The Music Player Daemon Project + * http://www.musicpd.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. + */ + +#ifndef MPD_PLAYLIST_FILE_HXX +#define MPD_PLAYLIST_FILE_HXX + +#include +#include +#include + +#include +#include +#include + +struct song; + +struct PlaylistFileInfo { + std::string name; + + time_t mtime; +}; + +typedef std::list PlaylistFileList; + +typedef std::vector PlaylistFileContents; + +extern bool playlist_saveAbsolutePaths; + +/** + * Perform some global initialization, e.g. load configuration values. + */ +void +spl_global_init(void); + +#ifdef __cplusplus + +/** + * Determines whether the specified string is a valid name for a + * stored playlist. + */ +bool +spl_valid_name(const char *name_utf8); + +/** + * Returns a list of stored_playlist_info struct pointers. Returns + * NULL if an error occurred. + */ +PlaylistFileList +ListPlaylistFiles(GError **error_r); + +PlaylistFileContents +LoadPlaylistFile(const char *utf8path, GError **error_r); + +bool +spl_move_index(const char *utf8path, unsigned src, unsigned dest, + GError **error_r); + +bool +spl_clear(const char *utf8path, GError **error_r); + +bool +spl_delete(const char *name_utf8, GError **error_r); + +bool +spl_remove_index(const char *utf8path, unsigned pos, GError **error_r); + +bool +spl_append_song(const char *utf8path, struct song *song, GError **error_r); + +bool +spl_append_uri(const char *file, const char *utf8file, GError **error_r); + +bool +spl_rename(const char *utf8from, const char *utf8to, GError **error_r); + +#endif + +#endif diff --git a/src/PlaylistMapper.cxx b/src/PlaylistMapper.cxx index 415f8ba2f..39ac043e4 100644 --- a/src/PlaylistMapper.cxx +++ b/src/PlaylistMapper.cxx @@ -19,7 +19,7 @@ #include "config.h" #include "PlaylistMapper.h" -#include "PlaylistFile.h" +#include "PlaylistFile.hxx" extern "C" { #include "playlist_list.h" diff --git a/src/PlaylistPrint.cxx b/src/PlaylistPrint.cxx index 4f50825be..40b895f80 100644 --- a/src/PlaylistPrint.cxx +++ b/src/PlaylistPrint.cxx @@ -19,7 +19,7 @@ #include "config.h" #include "PlaylistPrint.hxx" -#include "PlaylistFile.h" +#include "PlaylistFile.hxx" #include "QueuePrint.hxx" extern "C" { diff --git a/src/PlaylistSave.cxx b/src/PlaylistSave.cxx index 4c8af627b..8d1908aac 100644 --- a/src/PlaylistSave.cxx +++ b/src/PlaylistSave.cxx @@ -19,7 +19,7 @@ #include "config.h" #include "PlaylistSave.hxx" -#include "PlaylistFile.h" +#include "PlaylistFile.hxx" #include "song.h" extern "C" { diff --git a/src/Win32Main.cxx b/src/Win32Main.cxx new file mode 100644 index 000000000..8543ea108 --- /dev/null +++ b/src/Win32Main.cxx @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2003-2011 The Music Player Daemon Project + * http://www.musicpd.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 "config.h" +#include "Main.hxx" + +#ifdef WIN32 + +#include "mpd_error.h" + +extern "C" { +#include "event_pipe.h" +} + +#include + +#include + +static int service_argc; +static char **service_argv; +static char service_name[] = ""; +static BOOL ignore_console_events; +static SERVICE_STATUS_HANDLE service_handle; + +static void WINAPI +service_main(DWORD argc, CHAR *argv[]); + +static SERVICE_TABLE_ENTRY service_registry[] = { + {service_name, service_main}, + {NULL, NULL} +}; + +static void +service_notify_status(DWORD status_code) +{ + SERVICE_STATUS current_status; + + current_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + current_status.dwControlsAccepted = status_code == SERVICE_START_PENDING + ? 0 + : SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP; + + current_status.dwCurrentState = status_code; + current_status.dwWin32ExitCode = NO_ERROR; + current_status.dwCheckPoint = 0; + current_status.dwWaitHint = 1000; + + SetServiceStatus(service_handle, ¤t_status); +} + +static DWORD WINAPI +service_dispatcher(G_GNUC_UNUSED DWORD control, G_GNUC_UNUSED DWORD event_type, + G_GNUC_UNUSED void *event_data, G_GNUC_UNUSED void *context) +{ + switch (control) { + case SERVICE_CONTROL_SHUTDOWN: + case SERVICE_CONTROL_STOP: + event_pipe_emit(PIPE_EVENT_SHUTDOWN); + return NO_ERROR; + default: + return NO_ERROR; + } +} + +static void WINAPI +service_main(G_GNUC_UNUSED DWORD argc, G_GNUC_UNUSED CHAR *argv[]) +{ + DWORD error_code; + gchar* error_message; + + service_handle = + RegisterServiceCtrlHandlerEx(service_name, + service_dispatcher, NULL); + + if (service_handle == 0) { + error_code = GetLastError(); + error_message = g_win32_error_message(error_code); + MPD_ERROR("RegisterServiceCtrlHandlerEx() failed: %s", + error_message); + } + + service_notify_status(SERVICE_START_PENDING); + mpd_main(service_argc, service_argv); + service_notify_status(SERVICE_STOPPED); +} + +static BOOL WINAPI +console_handler(DWORD event) +{ + switch (event) { + case CTRL_C_EVENT: + case CTRL_CLOSE_EVENT: + if (!ignore_console_events) + event_pipe_emit(PIPE_EVENT_SHUTDOWN); + return TRUE; + default: + return FALSE; + } +} + +int win32_main(int argc, char *argv[]) +{ + DWORD error_code; + gchar* error_message; + + service_argc = argc; + service_argv = argv; + + if (StartServiceCtrlDispatcher(service_registry)) + return 0; /* run as service successefully */ + + error_code = GetLastError(); + if (error_code == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { + /* running as console app */ + SetConsoleTitle("Music Player Daemon"); + ignore_console_events = TRUE; + SetConsoleCtrlHandler(console_handler, TRUE); + return mpd_main(argc, argv); + } + + error_message = g_win32_error_message(error_code); + MPD_ERROR("StartServiceCtrlDispatcher() failed: %s", error_message); +} + +void win32_app_started() +{ + if (service_handle != 0) + service_notify_status(SERVICE_RUNNING); + else + ignore_console_events = FALSE; +} + +void win32_app_stopping() +{ + if (service_handle != 0) + service_notify_status(SERVICE_STOP_PENDING); + else + ignore_console_events = TRUE; +} + +#endif diff --git a/src/client_event.c b/src/client_event.c index dbcd35c44..5680e557b 100644 --- a/src/client_event.c +++ b/src/client_event.c @@ -19,7 +19,7 @@ #include "config.h" #include "client_internal.h" -#include "main.h" +#include "Main.hxx" #include diff --git a/src/listen.c b/src/listen.c index 90e13b9c1..28709a0e1 100644 --- a/src/listen.c +++ b/src/listen.c @@ -22,7 +22,7 @@ #include "server_socket.h" #include "client.h" #include "conf.h" -#include "main.h" +#include "Main.hxx" #include #include diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 39778aad6..000000000 --- a/src/main.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Copyright (C) 2003-2011 The Music Player Daemon Project - * http://www.musicpd.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 "config.h" -#include "main.h" -#include "daemon.h" -#include "io_thread.h" -#include "client.h" -#include "client_idle.h" -#include "idle.h" -#include "AllCommands.h" -#include "playlist.h" -#include "PlaylistFile.h" -#include "database.h" -#include "update.h" -#include "player_thread.h" -#include "listen.h" -#include "cmdline.h" -#include "conf.h" -#include "path.h" -#include "mapper.h" -#include "chunk.h" -#include "player_control.h" -#include "stats.h" -#include "sig_handlers.h" -#include "audio_config.h" -#include "output_all.h" -#include "volume.h" -#include "log.h" -#include "permission.h" -#include "pcm_resample.h" -#include "replay_gain_config.h" -#include "decoder_list.h" -#include "input_init.h" -#include "playlist_list.h" -#include "state_file.h" -#include "tag.h" -#include "zeroconf.h" -#include "event_pipe.h" -#include "mpd_error.h" - -#ifdef ENABLE_INOTIFY -#include "inotify_update.h" -#endif - -#ifdef ENABLE_SQLITE -#include "sticker.h" -#endif - -#ifdef ENABLE_ARCHIVE -#include "archive_list.h" -#endif - -#include - -#include -#include -#include -#include - -#ifdef HAVE_LOCALE_H -#include -#endif - -#ifdef WIN32 -#include -#include -#endif - -enum { - DEFAULT_BUFFER_SIZE = 2048, - DEFAULT_BUFFER_BEFORE_PLAY = 10, -}; - -GThread *main_task; -GMainLoop *main_loop; - -GCond *main_cond; - -struct player_control *global_player_control; - -static bool -glue_daemonize_init(const struct options *options, GError **error_r) -{ - GError *error = NULL; - - char *pid_file = config_dup_path(CONF_PID_FILE, &error); - if (pid_file == NULL && error != NULL) { - g_propagate_error(error_r, error); - return false; - } - - daemonize_init(config_get_string(CONF_USER, NULL), - config_get_string(CONF_GROUP, NULL), - pid_file); - g_free(pid_file); - - if (options->kill) - daemonize_kill(); - - return true; -} - -static bool -glue_mapper_init(GError **error_r) -{ - GError *error = NULL; - char *music_dir = config_dup_path(CONF_MUSIC_DIR, &error); - if (music_dir == NULL && error != NULL) { - g_propagate_error(error_r, error); - return false; - } - - char *playlist_dir = config_dup_path(CONF_PLAYLIST_DIR, &error); - if (playlist_dir == NULL && error != NULL) { - g_propagate_error(error_r, error); - return false; - } - - if (music_dir == NULL) - music_dir = g_strdup(g_get_user_special_dir(G_USER_DIRECTORY_MUSIC)); - - mapper_init(music_dir, playlist_dir); - - g_free(music_dir); - g_free(playlist_dir); - return true; -} - -/** - * Returns the database. If this function returns false, this has not - * succeeded, and the caller should create the database after the - * process has been daemonized. - */ -static bool -glue_db_init_and_load(void) -{ - const struct config_param *param = config_get_param("database"); - const struct config_param *path = config_get_param(CONF_DB_FILE); - - if (param != NULL && path != NULL) - g_message("Found both 'database' and '" CONF_DB_FILE - "' setting - ignoring the latter"); - - GError *error = NULL; - bool ret; - - if (!mapper_has_music_directory()) { - if (param != NULL) - g_message("Found database setting without " - CONF_MUSIC_DIR " - disabling database"); - if (path != NULL) - g_message("Found " CONF_DB_FILE " setting without " - CONF_MUSIC_DIR " - disabling database"); - return true; - } - - struct config_param *allocated = NULL; - - if (param == NULL && path != NULL) { - allocated = config_new_param("database", path->line); - config_add_block_param(allocated, "path", - path->value, path->line); - param = allocated; - } - - if (!db_init(param, &error)) - MPD_ERROR("%s", error->message); - - if (allocated != NULL) - config_param_free(allocated); - - ret = db_load(&error); - if (!ret) - MPD_ERROR("%s", error->message); - - /* run database update after daemonization? */ - return !db_is_simple() || db_exists(); -} - -/** - * Configure and initialize the sticker subsystem. - */ -static void -glue_sticker_init(void) -{ -#ifdef ENABLE_SQLITE - GError *error = NULL; - char *sticker_file = config_dup_path(CONF_STICKER_FILE, &error); - if (sticker_file == NULL && error != NULL) - MPD_ERROR("%s", error->message); - - if (!sticker_global_init(sticker_file, &error)) - MPD_ERROR("%s", error->message); - - g_free(sticker_file); -#endif -} - -static bool -glue_state_file_init(GError **error_r) -{ - GError *error = NULL; - - char *path = config_dup_path(CONF_STATE_FILE, &error); - if (path == NULL && error != NULL) { - g_propagate_error(error_r, error); - return false; - } - - state_file_init(path, global_player_control); - g_free(path); - - return true; -} - -/** - * Windows-only initialization of the Winsock2 library. - */ -static void winsock_init(void) -{ -#ifdef WIN32 - WSADATA sockinfo; - int retval; - - retval = WSAStartup(MAKEWORD(2, 2), &sockinfo); - if(retval != 0) - { - MPD_ERROR("Attempt to open Winsock2 failed; error code %d\n", - retval); - } - - if (LOBYTE(sockinfo.wVersion) != 2) - { - MPD_ERROR("We use Winsock2 but your version is either too new " - "or old; please install Winsock 2.x\n"); - } -#endif -} - -/** - * Initialize the decoder and player core, including the music pipe. - */ -static void -initialize_decoder_and_player(void) -{ - const struct config_param *param; - char *test; - size_t buffer_size; - float perc; - unsigned buffered_chunks; - unsigned buffered_before_play; - - param = config_get_param(CONF_AUDIO_BUFFER_SIZE); - if (param != NULL) { - long tmp = strtol(param->value, &test, 10); - if (*test != '\0' || tmp <= 0 || tmp == LONG_MAX) - MPD_ERROR("buffer size \"%s\" is not a positive integer, " - "line %i\n", param->value, param->line); - buffer_size = tmp; - } else - buffer_size = DEFAULT_BUFFER_SIZE; - - buffer_size *= 1024; - - buffered_chunks = buffer_size / CHUNK_SIZE; - - if (buffered_chunks >= 1 << 15) - MPD_ERROR("buffer size \"%li\" is too big\n", (long)buffer_size); - - param = config_get_param(CONF_BUFFER_BEFORE_PLAY); - if (param != NULL) { - perc = strtod(param->value, &test); - if (*test != '%' || perc < 0 || perc > 100) { - MPD_ERROR("buffered before play \"%s\" is not a positive " - "percentage and less than 100 percent, line %i", - param->value, param->line); - } - } else - perc = DEFAULT_BUFFER_BEFORE_PLAY; - - buffered_before_play = (perc / 100) * buffered_chunks; - if (buffered_before_play > buffered_chunks) - buffered_before_play = buffered_chunks; - - global_player_control = pc_new(buffered_chunks, buffered_before_play); -} - -/** - * event_pipe callback function for PIPE_EVENT_IDLE - */ -static void -idle_event_emitted(void) -{ - /* send "idle" notificaions to all subscribed - clients */ - unsigned flags = idle_get(); - if (flags != 0) - client_manager_idle_add(flags); -} - -/** - * event_pipe callback function for PIPE_EVENT_SHUTDOWN - */ -static void -shutdown_event_emitted(void) -{ - g_main_loop_quit(main_loop); -} - -int main(int argc, char *argv[]) -{ -#ifdef WIN32 - return win32_main(argc, argv); -#else - return mpd_main(argc, argv); -#endif -} - -int mpd_main(int argc, char *argv[]) -{ - struct options options; - clock_t start; - bool create_db; - GError *error = NULL; - bool success; - - daemonize_close_stdin(); - -#ifdef HAVE_LOCALE_H - /* initialize locale */ - setlocale(LC_CTYPE,""); -#endif - - g_set_application_name("Music Player Daemon"); - - /* enable GLib's thread safety code */ - g_thread_init(NULL); - - io_thread_init(); - winsock_init(); - idle_init(); - config_global_init(); - - success = parse_cmdline(argc, argv, &options, &error); - if (!success) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - if (!glue_daemonize_init(&options, &error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - stats_global_init(); - tag_lib_init(); - - if (!log_init(options.verbose, options.log_stderr, &error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - success = listen_global_init(&error); - if (!success) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - daemonize_set_user(); - - main_task = g_thread_self(); - main_loop = g_main_loop_new(NULL, FALSE); - main_cond = g_cond_new(); - - event_pipe_init(); - event_pipe_register(PIPE_EVENT_IDLE, idle_event_emitted); - event_pipe_register(PIPE_EVENT_SHUTDOWN, shutdown_event_emitted); - - path_global_init(); - - if (!glue_mapper_init(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - initPermissions(); - playlist_global_init(); - spl_global_init(); -#ifdef ENABLE_ARCHIVE - archive_plugin_init_all(); -#endif - - if (!pcm_resample_global_init(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - decoder_plugin_init_all(); - update_global_init(); - - create_db = !glue_db_init_and_load(); - - glue_sticker_init(); - - command_init(); - initialize_decoder_and_player(); - volume_init(); - initAudioConfig(); - audio_output_all_init(global_player_control); - client_manager_init(); - replay_gain_global_init(); - - if (!input_stream_global_init(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - playlist_list_global_init(); - - daemonize(options.daemon); - - setup_log_output(options.log_stderr); - - initSigHandlers(); - - if (!io_thread_start(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - initZeroconf(); - - player_create(global_player_control); - - if (create_db) { - /* the database failed to load: recreate the - database */ - unsigned job = update_enqueue(NULL, true); - if (job == 0) - MPD_ERROR("directory update failed"); - } - - if (!glue_state_file_init(&error)) { - g_warning("%s", error->message); - g_error_free(error); - return EXIT_FAILURE; - } - - success = config_get_bool(CONF_AUTO_UPDATE, false); -#ifdef ENABLE_INOTIFY - if (success && mapper_has_music_directory()) - mpd_inotify_init(config_get_unsigned(CONF_AUTO_UPDATE_DEPTH, - G_MAXUINT)); -#else - if (success) - g_warning("inotify: auto_update was disabled. enable during compilation phase"); -#endif - - config_global_check(); - - /* enable all audio outputs (if not already done by - playlist_state_restore() */ - pc_update_audio(global_player_control); - -#ifdef WIN32 - win32_app_started(); -#endif - - /* run the main loop */ - g_main_loop_run(main_loop); - -#ifdef WIN32 - win32_app_stopping(); -#endif - - /* cleanup */ - - g_main_loop_unref(main_loop); - -#ifdef ENABLE_INOTIFY - mpd_inotify_finish(); -#endif - - state_file_finish(global_player_control); - pc_kill(global_player_control); - finishZeroconf(); - client_manager_deinit(); - listen_global_finish(); - playlist_global_finish(); - - start = clock(); - db_finish(); - g_debug("db_finish took %f seconds", - ((float)(clock()-start))/CLOCKS_PER_SEC); - -#ifdef ENABLE_SQLITE - sticker_global_finish(); -#endif - - g_cond_free(main_cond); - event_pipe_deinit(); - - playlist_list_global_finish(); - input_stream_global_finish(); - audio_output_all_finish(); - volume_finish(); - mapper_finish(); - path_global_finish(); - finishPermissions(); - pc_free(global_player_control); - command_finish(); - update_global_finish(); - decoder_plugin_deinit_all(); -#ifdef ENABLE_ARCHIVE - archive_plugin_deinit_all(); -#endif - config_global_finish(); - idle_deinit(); - stats_global_finish(); - io_thread_deinit(); - daemonize_finish(); -#ifdef WIN32 - WSACleanup(); -#endif - - log_deinit(); - return EXIT_SUCCESS; -} diff --git a/src/main.h b/src/main.h deleted file mode 100644 index 2a7d75910..000000000 --- a/src/main.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2003-2011 The Music Player Daemon Project - * http://www.musicpd.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. - */ - -#ifndef MAIN_H -#define MAIN_H - -#include - -extern GThread *main_task; - -extern GMainLoop *main_loop; - -extern GCond *main_cond; - -extern struct player_control *global_player_control; - -/** - * A entry point for application. - * On non-Windows platforms this is called directly from main() - * On Windows platform this is called from win32_main() - * after doing some initialization. - */ -int mpd_main(int argc, char *argv[]); - -#ifdef WIN32 - -/** - * If program is run as windows service performs nessesary initialization - * and then calls mpd_main() with specified arguments. - * If program is run as a regular application calls mpd_main() immediately. - */ -int -win32_main(int argc, char *argv[]); - -/** - * When running as a service reports to service control manager - * that our service is started. - * When running as a console application enables console handler that will - * trigger PIPE_EVENT_SHUTDOWN when user closes console window - * or presses Ctrl+C. - * This function should be called just before entering main loop. - */ -void -win32_app_started(void); - -/** - * When running as a service reports to service control manager - * that our service is about to stop. - * When running as a console application enables console handler that will - * catch all shutdown requests and ignore them. - * This function should be called just after leaving main loop. - */ -void -win32_app_stopping(void); - -#endif - -#endif diff --git a/src/main_win32.c b/src/main_win32.c deleted file mode 100644 index aac7ad886..000000000 --- a/src/main_win32.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2003-2011 The Music Player Daemon Project - * http://www.musicpd.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 "config.h" -#include "main.h" - -#ifdef WIN32 - -#include "mpd_error.h" -#include "event_pipe.h" - -#include - -#include - -static int service_argc; -static char **service_argv; -static char service_name[] = ""; -static BOOL ignore_console_events; -static SERVICE_STATUS_HANDLE service_handle; - -static void WINAPI -service_main(DWORD argc, CHAR *argv[]); - -static SERVICE_TABLE_ENTRY service_registry[] = { - {service_name, service_main}, - {NULL, NULL} -}; - -static void -service_notify_status(DWORD status_code) -{ - SERVICE_STATUS current_status; - - current_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - current_status.dwControlsAccepted = status_code == SERVICE_START_PENDING - ? 0 - : SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP; - - current_status.dwCurrentState = status_code; - current_status.dwWin32ExitCode = NO_ERROR; - current_status.dwCheckPoint = 0; - current_status.dwWaitHint = 1000; - - SetServiceStatus(service_handle, ¤t_status); -} - -static DWORD WINAPI -service_dispatcher(G_GNUC_UNUSED DWORD control, G_GNUC_UNUSED DWORD event_type, - G_GNUC_UNUSED void *event_data, G_GNUC_UNUSED void *context) -{ - switch (control) { - case SERVICE_CONTROL_SHUTDOWN: - case SERVICE_CONTROL_STOP: - event_pipe_emit(PIPE_EVENT_SHUTDOWN); - return NO_ERROR; - default: - return NO_ERROR; - } -} - -static void WINAPI -service_main(G_GNUC_UNUSED DWORD argc, G_GNUC_UNUSED CHAR *argv[]) -{ - DWORD error_code; - gchar* error_message; - - service_handle = - RegisterServiceCtrlHandlerEx(service_name, - service_dispatcher, NULL); - - if (service_handle == 0) { - error_code = GetLastError(); - error_message = g_win32_error_message(error_code); - MPD_ERROR("RegisterServiceCtrlHandlerEx() failed: %s", - error_message); - } - - service_notify_status(SERVICE_START_PENDING); - mpd_main(service_argc, service_argv); - service_notify_status(SERVICE_STOPPED); -} - -static BOOL WINAPI -console_handler(DWORD event) -{ - switch (event) { - case CTRL_C_EVENT: - case CTRL_CLOSE_EVENT: - if (!ignore_console_events) - event_pipe_emit(PIPE_EVENT_SHUTDOWN); - return TRUE; - default: - return FALSE; - } -} - -int win32_main(int argc, char *argv[]) -{ - DWORD error_code; - gchar* error_message; - - service_argc = argc; - service_argv = argv; - - if (StartServiceCtrlDispatcher(service_registry)) - return 0; /* run as service successefully */ - - error_code = GetLastError(); - if (error_code == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { - /* running as console app */ - SetConsoleTitle("Music Player Daemon"); - ignore_console_events = TRUE; - SetConsoleCtrlHandler(console_handler, TRUE); - return mpd_main(argc, argv); - } - - error_message = g_win32_error_message(error_code); - MPD_ERROR("StartServiceCtrlDispatcher() failed: %s", error_message); -} - -void win32_app_started() -{ - if (service_handle != 0) - service_notify_status(SERVICE_RUNNING); - else - ignore_console_events = FALSE; -} - -void win32_app_stopping() -{ - if (service_handle != 0) - service_notify_status(SERVICE_STOP_PENDING); - else - ignore_console_events = TRUE; -} - -#endif diff --git a/src/player_control.c b/src/player_control.c index d9aa2b94c..5a16520c2 100644 --- a/src/player_control.c +++ b/src/player_control.c @@ -26,7 +26,7 @@ #include "song.h" #include "idle.h" #include "pcm_volume.h" -#include "main.h" +#include "Main.hxx" #include #include diff --git a/src/player_thread.c b/src/player_thread.c index d2682f513..561c595eb 100644 --- a/src/player_thread.c +++ b/src/player_thread.c @@ -32,7 +32,7 @@ #include "pipe.h" #include "chunk.h" #include "idle.h" -#include "main.h" +#include "Main.hxx" #include "buffer.h" #include "mpd_error.h" diff --git a/src/playlist_global.c b/src/playlist_global.c index 650b88bb8..43bf26755 100644 --- a/src/playlist_global.c +++ b/src/playlist_global.c @@ -26,7 +26,7 @@ #include "playlist.h" #include "playlist_state.h" #include "event_pipe.h" -#include "main.h" +#include "Main.hxx" struct playlist g_playlist; diff --git a/src/sig_handlers.c b/src/sig_handlers.c index b23f9e778..eabca1997 100644 --- a/src/sig_handlers.c +++ b/src/sig_handlers.c @@ -23,7 +23,7 @@ #ifndef WIN32 #include "log.h" -#include "main.h" +#include "Main.hxx" #include "event_pipe.h" #include "mpd_error.h" diff --git a/src/update.c b/src/update.c index ef4dfe749..e47db8f09 100644 --- a/src/update.c +++ b/src/update.c @@ -30,7 +30,7 @@ #include "update.h" #include "idle.h" #include "stats.h" -#include "main.h" +#include "Main.hxx" #include "mpd_error.h" #include diff --git a/src/update_remove.c b/src/update_remove.c index f443f5eb2..c2e353c63 100644 --- a/src/update_remove.c +++ b/src/update_remove.c @@ -22,7 +22,7 @@ #include "event_pipe.h" #include "song.h" #include "playlist.h" -#include "main.h" +#include "Main.hxx" #ifdef ENABLE_SQLITE #include "sticker.h" -- cgit v1.2.3