/** * The xmms2 daemon main initialisation function */ int main (int argc, char **argv) { xmms_output_plugin_t *o_plugin; xmms_config_property_t *cv; xmms_main_t *mainobj; int loglevel = 1; xmms_playlist_t *playlist; gchar default_path[XMMS_PATH_MAX + 16], *tmp; gboolean verbose = FALSE; gboolean quiet = FALSE; gboolean version = FALSE; gboolean nologging = FALSE; gboolean runasroot = FALSE; gboolean showhelp = FALSE; const gchar *outname = NULL; const gchar *ipcpath = NULL; gchar *ppath = NULL; int status_fd = -1; GOptionContext *context = NULL; GError *error = NULL; setlocale (LC_ALL, ""); /** * The options that the server accepts. */ GOptionEntry opts[] = { {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Increase verbosity", NULL}, {"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, "Decrease verbosity", NULL}, {"version", 'V', 0, G_OPTION_ARG_NONE, &version, "Print version", NULL}, {"no-logging", 'n', 0, G_OPTION_ARG_NONE, &nologging, "Disable logging", NULL}, {"output", 'o', 0, G_OPTION_ARG_STRING, &outname, "Use 'x' as output plugin", "<x>"}, {"ipc-socket", 'i', 0, G_OPTION_ARG_FILENAME, &ipcpath, "Listen to socket 'url'", "<url>"}, {"plugindir", 'p', 0, G_OPTION_ARG_FILENAME, &ppath, "Search for plugins in directory 'foo'", "<foo>"}, {"conf", 'c', 0, G_OPTION_ARG_FILENAME, &conffile, "Specify alternate configuration file", "<file>"}, {"status-fd", 's', 0, G_OPTION_ARG_INT, &status_fd, "Specify a filedescriptor to write to when started", "fd"}, {"yes-run-as-root", 0, 0, G_OPTION_ARG_NONE, &runasroot, "Give me enough rope to shoot myself in the foot", NULL}, {"show-help", 'h', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &showhelp, "Use --help or -? instead", NULL}, {NULL} }; /** Check that we are running against the correct glib version */ if (glib_major_version != GLIB_MAJOR_VERSION || glib_minor_version < GLIB_MINOR_VERSION) { g_print ("xmms2d is build against version %d.%d,\n" "but is (runtime) linked against %d.%d.\n" "Refusing to start.\n", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, glib_major_version, glib_minor_version); exit (EXIT_FAILURE); } xmms_signal_block (); context = g_option_context_new ("- XMMS2 Daemon"); g_option_context_add_main_entries (context, opts, NULL); if (!g_option_context_parse (context, &argc, &argv, &error) || error) { g_print ("Error parsing options: %s\n", error->message); g_clear_error (&error); exit (EXIT_FAILURE); } if (showhelp) { #if GLIB_CHECK_VERSION(2,14,0) g_print ("%s", g_option_context_get_help (context, TRUE, NULL)); exit (EXIT_SUCCESS); #else g_print ("Please use --help or -? for help\n"); exit (EXIT_FAILURE); #endif } g_option_context_free (context); if (argc != 1) { g_print ("There were unknown options, aborting!\n"); exit (EXIT_FAILURE); } if (xmms_checkroot ()) { if (runasroot) { g_print ("***************************************\n"); g_print ("Warning! You are running XMMS2D as root, this is a bad idea!\nBut I'll allow it since you asked nicely.\n"); g_print ("***************************************\n\n"); } else { g_print ("PLEASE DON'T RUN XMMS2D AS ROOT!\n\n(if you really must, read the help)\n"); exit (EXIT_FAILURE); } } if (verbose) { loglevel++; } else if (quiet) { loglevel--; } if (version) { print_version (); } g_thread_init (NULL); g_random_set_seed (time (NULL)); xmms_log_init (loglevel); xmms_ipc_init (); load_config (); cv = xmms_config_property_register ("core.logtsfmt", "%H:%M:%S ", NULL, NULL); xmms_log_set_format (xmms_config_property_get_string (cv)); xmms_fallback_ipcpath_get (default_path, sizeof (default_path)); cv = xmms_config_property_register ("core.ipcsocket", default_path, on_config_ipcsocket_change, NULL); if (!ipcpath) { /* * if not ipcpath is specifed on the cmd line we * grab it from the config */ ipcpath = xmms_config_property_get_string (cv); } if (!xmms_ipc_setup_server (ipcpath)) { xmms_ipc_shutdown (); xmms_log_fatal ("IPC failed to init!"); } if (!xmms_plugin_init (ppath)) { return 1; } playlist = xmms_playlist_init (); xform_obj = xmms_xform_object_init (); bindata_obj = xmms_bindata_init (); mainobj = xmms_object_new (xmms_main_t, xmms_main_destroy); /* find output plugin. */ cv = xmms_config_property_register ("output.plugin", XMMS_OUTPUT_DEFAULT, change_output, mainobj); if (outname) { xmms_config_property_set_data (cv, outname); } outname = xmms_config_property_get_string (cv); xmms_log_info ("Using output plugin: %s", outname); o_plugin = (xmms_output_plugin_t *)xmms_plugin_find (XMMS_PLUGIN_TYPE_OUTPUT, outname); if (!o_plugin) { xmms_log_error ("Baaaaad output plugin, try to change the" "output.plugin config variable to something usefull"); } mainobj->output = xmms_output_new (o_plugin, playlist); if (!mainobj->output) { xmms_log_fatal ("Failed to create output object!"); } mainobj->vis = xmms_visualization_new (mainobj->output); if (status_fd != -1) { write (status_fd, "+", 1); } xmms_signal_init (XMMS_OBJECT (mainobj)); xmms_ipc_object_register (XMMS_IPC_OBJECT_MAIN, XMMS_OBJECT (mainobj)); xmms_ipc_broadcast_register (XMMS_OBJECT (mainobj), XMMS_IPC_SIGNAL_QUIT); xmms_object_cmd_add (XMMS_OBJECT (mainobj), XMMS_IPC_CMD_QUIT, XMMS_CMD_FUNC (quit)); xmms_object_cmd_add (XMMS_OBJECT (mainobj), XMMS_IPC_CMD_HELLO, XMMS_CMD_FUNC (hello)); xmms_object_cmd_add (XMMS_OBJECT (mainobj), XMMS_IPC_CMD_PLUGIN_LIST, XMMS_CMD_FUNC (plugin_list)); xmms_object_cmd_add (XMMS_OBJECT (mainobj), XMMS_IPC_CMD_STATS, XMMS_CMD_FUNC (stats)); /* Save the time we started in order to count uptime */ mainobj->starttime = time (NULL); /* Dirty hack to tell XMMS_PATH a valid path */ g_strlcpy (default_path, ipcpath, sizeof (default_path)); tmp = strchr (default_path, ';'); if (tmp) { *tmp = '\0'; } g_setenv ("XMMS_PATH", default_path, TRUE); /* Also put the full path for clients that understands */ g_setenv("XMMS_PATH_FULL", ipcpath, TRUE); tmp = XMMS_BUILD_PATH ("shutdown.d"); cv = xmms_config_property_register ("core.shutdownpath", tmp, NULL, NULL); g_free (tmp); tmp = XMMS_BUILD_PATH ("startup.d"); cv = xmms_config_property_register ("core.startuppath", tmp, NULL, NULL); g_free (tmp); /* Startup dir */ do_scriptdir (xmms_config_property_get_string (cv), "start"); mainloop = g_main_loop_new (NULL, FALSE); g_main_loop_run (mainloop); return 0; }
/** * Allocate a new #xmms_output_t */ xmms_output_t * xmms_output_new (xmms_output_plugin_t *plugin, xmms_playlist_t *playlist) { xmms_output_t *output; xmms_config_property_t *prop; gint size; g_return_val_if_fail (playlist, NULL); XMMS_DBG ("Trying to open output"); output = xmms_object_new (xmms_output_t, xmms_output_destroy); output->playlist = playlist; output->status_mutex = g_mutex_new (); output->playtime_mutex = g_mutex_new (); prop = xmms_config_property_register ("output.buffersize", "32768", NULL, NULL); size = xmms_config_property_get_int (prop); XMMS_DBG ("Using buffersize %d", size); output->filler_mutex = g_mutex_new (); output->filler_state = FILLER_STOP; output->filler_state_cond = g_cond_new (); output->filler_buffer = xmms_ringbuf_new (size); output->filler_thread = g_thread_create (xmms_output_filler, output, TRUE, NULL); xmms_config_property_register ("output.flush_on_pause", "1", NULL, NULL); xmms_ipc_object_register (XMMS_IPC_OBJECT_OUTPUT, XMMS_OBJECT (output)); /* Broadcasts are always transmitted to the client if he * listens to them. */ xmms_ipc_broadcast_register (XMMS_OBJECT (output), XMMS_IPC_SIGNAL_OUTPUT_VOLUME_CHANGED); xmms_ipc_broadcast_register (XMMS_OBJECT (output), XMMS_IPC_SIGNAL_PLAYBACK_STATUS); xmms_ipc_broadcast_register (XMMS_OBJECT (output), XMMS_IPC_SIGNAL_OUTPUT_CURRENTID); /* Signals are only emitted if the client has a pending question to it * after the client recivies a signal, he must ask for it again */ xmms_ipc_signal_register (XMMS_OBJECT (output), XMMS_IPC_SIGNAL_OUTPUT_PLAYTIME); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_START, XMMS_CMD_FUNC (start)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_STOP, XMMS_CMD_FUNC (stop)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_PAUSE, XMMS_CMD_FUNC (pause)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_DECODER_KILL, XMMS_CMD_FUNC (xform_kill)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_CPLAYTIME, XMMS_CMD_FUNC (playtime)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_SEEKMS, XMMS_CMD_FUNC (seekms)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_SEEKMS_REL, XMMS_CMD_FUNC (seekms_rel)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_SEEKSAMPLES, XMMS_CMD_FUNC (seeksamples)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_SEEKSAMPLES_REL, XMMS_CMD_FUNC (seeksamples_rel)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_OUTPUT_STATUS, XMMS_CMD_FUNC (output_status)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_CURRENTID, XMMS_CMD_FUNC (currentid)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_VOLUME_SET, XMMS_CMD_FUNC (volume_set)); xmms_object_cmd_add (XMMS_OBJECT (output), XMMS_IPC_CMD_VOLUME_GET, XMMS_CMD_FUNC (volume_get)); output->status = XMMS_PLAYBACK_STATUS_STOP; if (plugin) { if (!set_plugin (output, plugin)) { xmms_log_error ("Could not initialize output plugin"); } } else { xmms_log_error ("initalized output without a plugin, please fix!"); } return output; }