XMMS2
main.c
Go to the documentation of this file.
1 /* XMMS2 - X Music Multiplexer System
2  * Copyright (C) 2003-2011 XMMS2 Team
3  *
4  * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  */
16 
17 /**
18  * @mainpage
19  * @image html pixmaps/xmms2-128.png
20  */
21 
22 /** @file
23  * This file controls the XMMS2 main loop.
24  */
25 
26 #include <locale.h>
27 #include <glib.h>
28 
29 #include "xmms_configuration.h"
30 #include "xmmsc/xmmsc_util.h"
31 #include "xmmspriv/xmms_plugin.h"
32 #include "xmmspriv/xmms_config.h"
33 #include "xmmspriv/xmms_playlist.h"
35 #include "xmmspriv/xmms_signal.h"
36 #include "xmmspriv/xmms_symlink.h"
39 #include "xmmspriv/xmms_medialib.h"
40 #include "xmmspriv/xmms_output.h"
41 #include "xmmspriv/xmms_ipc.h"
42 #include "xmmspriv/xmms_log.h"
43 #include "xmmspriv/xmms_sqlite.h"
44 #include "xmmspriv/xmms_xform.h"
45 #include "xmmspriv/xmms_bindata.h"
46 #include "xmmspriv/xmms_utils.h"
48 
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <unistd.h>
53 #include <signal.h>
54 #include <sys/stat.h>
55 #include <fcntl.h>
56 
57 /*
58  * Forward declarations of the methods in the main object
59  */
60 static void xmms_main_client_quit (xmms_object_t *object, xmms_error_t *error);
61 static GTree *xmms_main_client_stats (xmms_object_t *object, xmms_error_t *error);
62 static GList *xmms_main_client_list_plugins (xmms_object_t *main, gint32 type, xmms_error_t *err);
63 static void xmms_main_client_hello (xmms_object_t *object, gint protocolver, const gchar *client, xmms_error_t *error);
64 static void install_scripts (const gchar *into_dir);
65 static void spawn_script_setup (gpointer data);
66 static xmms_xform_object_t *xform_obj;
67 static xmms_bindata_t *bindata_obj;
68 
69 #include "main_ipc.c"
70 
71 /** @defgroup XMMSServer XMMSServer
72  * @brief look at this if you want to code inside the server.
73  * The XMMS2 project is split into a server and a multiple clients.
74  * This documents the server part.
75  */
76 
77 /**
78  * @defgroup Main Main
79  * @ingroup XMMSServer
80  * @brief main object
81  * @{
82  */
83 
84 
85 /**
86  * Main object, when this is unreffed, XMMS2 is quiting.
87  */
88 struct xmms_main_St {
89  xmms_object_t object;
90  xmms_output_t *output;
92  time_t starttime;
93 };
94 
95 typedef struct xmms_main_St xmms_main_t;
96 
97 /** This is the mainloop of the xmms2 server */
98 static GMainLoop *mainloop;
99 
100 /** The path of the configfile */
101 static gchar *conffile = NULL;
102 
103 /**
104  * This returns the main stats for the server
105  */
106 static GTree *
107 xmms_main_client_stats (xmms_object_t *object, xmms_error_t *error)
108 {
109  GTree *ret;
110  gint starttime;
111 
112  ret = g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
113  NULL, (GDestroyNotify) xmmsv_unref);
114 
115  starttime = ((xmms_main_t*)object)->starttime;
116 
117  g_tree_insert (ret, (gpointer) "version",
118  xmmsv_new_string (XMMS_VERSION));
119  g_tree_insert (ret, (gpointer) "uptime",
120  xmmsv_new_int (time (NULL) - starttime));
121 
122  return ret;
123 }
124 
125 static gboolean
126 xmms_main_client_list_foreach (xmms_plugin_t *plugin, gpointer data)
127 {
128  xmmsv_t *dict;
129  GList **list = data;
130 
131  dict = xmmsv_build_dict (
132  XMMSV_DICT_ENTRY_STR ("name", xmms_plugin_name_get (plugin)),
133  XMMSV_DICT_ENTRY_STR ("shortname", xmms_plugin_shortname_get (plugin)),
134  XMMSV_DICT_ENTRY_STR ("version", xmms_plugin_version_get (plugin)),
135  XMMSV_DICT_ENTRY_STR ("description", xmms_plugin_description_get (plugin)),
136  XMMSV_DICT_ENTRY_INT ("type", xmms_plugin_type_get (plugin)),
138 
139  *list = g_list_prepend (*list, dict);
140 
141  return TRUE;
142 }
143 
144 static GList *
145 xmms_main_client_list_plugins (xmms_object_t *main, gint32 type, xmms_error_t *err)
146 {
147  GList *list = NULL;
148  xmms_plugin_foreach (type, xmms_main_client_list_foreach, &list);
149  return list;
150 }
151 
152 
153 /**
154  * @internal Execute all programs or scripts in a directory. Used when starting
155  * up and shutting down the daemon.
156  *
157  * @param[in] scriptdir Directory to search for executable programs/scripts.
158  * started.
159  * @param arg1 value passed to executed scripts as argument 1. This makes
160  * it possible to handle start and stop in one script
161  */
162 static void
163 do_scriptdir (const gchar *scriptdir, const gchar *arg1)
164 {
165  GError *err = NULL;
166  GDir *dir;
167  const gchar *f;
168  gchar *argv[3] = {NULL, NULL, NULL};
169 
170  XMMS_DBG ("Running scripts in %s", scriptdir);
171  if (!g_file_test (scriptdir, G_FILE_TEST_IS_DIR)) {
172  g_mkdir_with_parents (scriptdir, 0755);
173  install_scripts (scriptdir);
174  }
175 
176  dir = g_dir_open (scriptdir, 0, &err);
177  if (!dir) {
178  xmms_log_error ("Could not open script dir '%s' error: %s", scriptdir, err->message);
179  return;
180  }
181 
182  argv[1] = g_strdup (arg1);
183  while ((f = g_dir_read_name (dir))) {
184  argv[0] = g_strdup_printf ("%s/%s", scriptdir, f);
185  if (g_file_test (argv[0], G_FILE_TEST_IS_EXECUTABLE)) {
186  if (!g_spawn_async (g_get_home_dir (), argv, NULL, 0,
187  spawn_script_setup, NULL, NULL, &err)) {
188  xmms_log_error ("Could not run script '%s', error: %s",
189  argv[0], err->message);
190  }
191  }
192  g_free (argv[0]);
193  }
194  g_free (argv[1]);
195 
196  g_dir_close (dir);
197 
198 }
199 
200 /**
201  * @internal Setup function for processes spawned by do_scriptdir
202  */
203 static void
204 spawn_script_setup (gpointer data)
205 {
207 }
208 
209 /**
210  * @internal Load the xmms2d configuration file. Creates the config directory
211  * if needed.
212  */
213 static void
214 load_config (void)
215 {
216  gchar configdir[XMMS_PATH_MAX];
217 
218  if (!conffile) {
219  conffile = XMMS_BUILD_PATH ("xmms2.conf");
220  }
221 
222  g_assert (strlen (conffile) <= XMMS_MAX_CONFIGFILE_LEN);
223 
224  if (!xmms_userconfdir_get (configdir, sizeof (configdir))) {
225  xmms_log_error ("Could not get path to config dir");
226  } else if (!g_file_test (configdir, G_FILE_TEST_IS_DIR)) {
227  g_mkdir_with_parents (configdir, 0755);
228  }
229 
230  xmms_config_init (conffile);
231 }
232 
233 /**
234  * @internal Switch to using another output plugin
235  * @param object An object
236  * @param data The name of the output plugin to switch to
237  * @param userdata The #xmms_main_t object
238  */
239 static void
240 change_output (xmms_object_t *object, xmmsv_t *_data, gpointer userdata)
241 {
242  xmms_output_plugin_t *plugin;
243  xmms_main_t *mainobj = (xmms_main_t*)userdata;
244  const gchar *outname;
245 
246  if (!mainobj->output)
247  return;
248 
250 
251  xmms_log_info ("Switching to output %s", outname);
252 
254  if (!plugin) {
255  xmms_log_error ("Baaaaad output plugin, try to change the output.plugin config variable to something useful");
256  } else {
257  if (!xmms_output_plugin_switch (mainobj->output, plugin)) {
258  xmms_log_error ("Baaaaad output plugin, try to change the output.plugin config variable to something useful");
259  }
260  }
261 }
262 
263 /**
264  * @internal Destroy the main object
265  * @param[in] object The object to destroy
266  */
267 static void
268 xmms_main_destroy (xmms_object_t *object)
269 {
270  xmms_main_t *mainobj = (xmms_main_t *) object;
273 
274  cv = xmms_config_lookup ("core.shutdownpath");
275  do_scriptdir (xmms_config_property_get_string (cv), "stop");
276 
277  /* stop output */
279  arg.args = xmmsv_new_list ();
280  xmms_object_cmd_call (XMMS_OBJECT (mainobj->output),
281  XMMS_IPC_CMD_STOP, &arg);
282  xmmsv_unref (arg.args);
283 
284  g_usleep (G_USEC_PER_SEC); /* wait for the output thread to end */
285 
286  xmms_object_unref (mainobj->vis);
287  xmms_object_unref (mainobj->output);
288 
289  xmms_object_unref (xform_obj);
290 
291  xmms_config_save ();
292 
294 
296 
297  xmms_main_unregister_ipc_commands ();
298 
300 
302 }
303 
304 /**
305  * @internal Function to respond to the 'hello' sent from clients on connect
306  */
307 static void
308 xmms_main_client_hello (xmms_object_t *object, gint protocolver, const gchar *client, xmms_error_t *error)
309 {
310  if (protocolver != XMMS_IPC_PROTOCOL_VERSION) {
311  xmms_log_info ("Client '%s' with bad protocol version (%d, not %d) connected", client, protocolver, XMMS_IPC_PROTOCOL_VERSION);
312  xmms_error_set (error, XMMS_ERROR_INVAL, "Bad protocol version");
313  return;
314  }
315  XMMS_DBG ("Client '%s' connected", client);
316 }
317 
318 static gboolean
319 kill_server (gpointer object) {
323  time (NULL)-((xmms_main_t*)object)->starttime);
324 
325  xmms_object_unref (object);
326 
327  exit (EXIT_SUCCESS);
328 }
329 
330 
331 /**
332  * @internal Function to respond to the 'quit' command sent from a client
333  */
334 static void
335 xmms_main_client_quit (xmms_object_t *object, xmms_error_t *error)
336 {
337  /*
338  * to be able to return from this method
339  * we add a timeout that will kill the server
340  * very "ugly"
341  */
342  g_timeout_add (1, kill_server, object);
343 }
344 
345 static void
346 install_scripts (const gchar *into_dir)
347 {
348  GDir *dir;
349  GError *err = NULL;
350  gchar path[XMMS_PATH_MAX];
351  const gchar *f;
352  gchar *s;
353 
354  s = strrchr (into_dir, G_DIR_SEPARATOR);
355  if (!s)
356  return;
357 
358  s++;
359 
360  g_snprintf (path, XMMS_PATH_MAX, "%s/scripts/%s", SHAREDDIR, s);
361  xmms_log_info ("Installing scripts from %s", path);
362  dir = g_dir_open (path, 0, &err);
363  if (!dir) {
364  xmms_log_error ("Global script directory not found");
365  return;
366  }
367 
368  while ((f = g_dir_read_name (dir))) {
369  gchar *source = g_strdup_printf ("%s/%s", path, f);
370  gchar *dest = g_strdup_printf ("%s/%s", into_dir, f);
371  if (!xmms_symlink_file (source, dest)) {
372  g_free (source);
373  g_free (dest);
374  break;
375  }
376  g_free (source);
377  g_free (dest);
378  }
379 
380  g_dir_close (dir);
381 }
382 
383 /**
384  * Just print version and quit
385  */
386 static void
387 print_version (void)
388 {
389  printf ("XMMS2 version " XMMS_VERSION "\n");
390  printf ("Copyright (C) 2003-2011 XMMS2 Team\n");
391  printf ("This is free software; see the source for copying conditions.\n");
392  printf ("There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n");
393  printf ("PARTICULAR PURPOSE.\n");
394  printf (" Using glib version %d.%d.%d (compiled against "
395  G_STRINGIFY (GLIB_MAJOR_VERSION) "."
396  G_STRINGIFY (GLIB_MINOR_VERSION) "."
397  G_STRINGIFY (GLIB_MICRO_VERSION) ")\n",
398  glib_major_version,
399  glib_minor_version,
400  glib_micro_version);
402 
403  exit (EXIT_SUCCESS);
404 }
405 
406 /**
407  * The xmms2 daemon main initialisation function
408  */
409 int
410 main (int argc, char **argv)
411 {
412  xmms_output_plugin_t *o_plugin;
414  xmms_main_t *mainobj;
415  int loglevel = 1;
416  xmms_playlist_t *playlist;
417  gchar default_path[XMMS_PATH_MAX + 16], *tmp;
418  gboolean verbose = FALSE;
419  gboolean quiet = FALSE;
420  gboolean version = FALSE;
421  gboolean runasroot = FALSE;
422  gboolean showhelp = FALSE;
423  const gchar *outname = NULL;
424  const gchar *ipcpath = NULL;
425  gchar *ppath = NULL;
426  int status_fd = -1;
427  GOptionContext *context = NULL;
428  GError *error = NULL;
429 
430  setlocale (LC_ALL, "");
431 
432  /**
433  * The options that the server accepts.
434  */
435  GOptionEntry opts[] = {
436  {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Increase verbosity", NULL},
437  {"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, "Decrease verbosity", NULL},
438  {"version", 'V', 0, G_OPTION_ARG_NONE, &version, "Print version", NULL},
439  {"output", 'o', 0, G_OPTION_ARG_STRING, &outname, "Use 'x' as output plugin", "<x>"},
440  {"ipc-socket", 'i', 0, G_OPTION_ARG_FILENAME, &ipcpath, "Listen to socket 'url'", "<url>"},
441  {"plugindir", 'p', 0, G_OPTION_ARG_FILENAME, &ppath, "Search for plugins in directory 'foo'", "<foo>"},
442  {"conf", 'c', 0, G_OPTION_ARG_FILENAME, &conffile, "Specify alternate configuration file", "<file>"},
443  {"status-fd", 's', 0, G_OPTION_ARG_INT, &status_fd, "Specify a filedescriptor to write to when started", "fd"},
444  {"yes-run-as-root", 0, 0, G_OPTION_ARG_NONE, &runasroot, "Give me enough rope to shoot myself in the foot", NULL},
445  {"show-help", 'h', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &showhelp, "Use --help or -? instead", NULL},
446  {NULL}
447  };
448 
449  /** Check that we are running against the correct glib version */
450  if (glib_major_version != GLIB_MAJOR_VERSION ||
451  glib_minor_version < GLIB_MINOR_VERSION) {
452  g_print ("xmms2d is build against version %d.%d,\n"
453  "but is (runtime) linked against %d.%d.\n"
454  "Refusing to start.\n",
455  GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
456  glib_major_version, glib_minor_version);
457  exit (EXIT_FAILURE);
458  }
459 
461 
462  context = g_option_context_new ("- XMMS2 Daemon");
463  g_option_context_add_main_entries (context, opts, NULL);
464  if (!g_option_context_parse (context, &argc, &argv, &error) || error) {
465  g_print ("Error parsing options: %s\n", error->message);
466  g_clear_error (&error);
467  exit (EXIT_FAILURE);
468  }
469  if (showhelp) {
470 #if GLIB_CHECK_VERSION(2,14,0)
471  g_print ("%s", g_option_context_get_help (context, TRUE, NULL));
472  exit (EXIT_SUCCESS);
473 #else
474  g_print ("Please use --help or -? for help\n");
475  exit (EXIT_FAILURE);
476 #endif
477  }
478  g_option_context_free (context);
479 
480  if (argc != 1) {
481  g_print ("There were unknown options, aborting!\n");
482  exit (EXIT_FAILURE);
483  }
484 
485  if (xmms_checkroot ()) {
486  if (runasroot) {
487  g_print ("***************************************\n");
488  g_print ("Warning! You are running XMMS2D as root, this is a bad idea!\nBut I'll allow it since you asked nicely.\n");
489  g_print ("***************************************\n\n");
490  } else {
491  g_print ("PLEASE DON'T RUN XMMS2D AS ROOT!\n\n(if you really must, read the help)\n");
492  exit (EXIT_FAILURE);
493  }
494  }
495 
496  if (verbose) {
497  loglevel++;
498  } else if (quiet) {
499  loglevel--;
500  }
501 
502  if (version) {
503  print_version ();
504  }
505 
506  g_thread_init (NULL);
507 
508  g_random_set_seed (time (NULL));
509 
510  xmms_log_init (loglevel);
511  xmms_ipc_init ();
512 
513  load_config ();
514 
515  cv = xmms_config_property_register ("core.logtsfmt",
516  "%H:%M:%S ",
517  NULL, NULL);
518 
520 
521  xmms_fallback_ipcpath_get (default_path, sizeof (default_path));
522 
523  cv = xmms_config_property_register ("core.ipcsocket",
524  default_path,
526  NULL);
527 
528  if (!ipcpath) {
529  /*
530  * if not ipcpath is specifed on the cmd line we
531  * grab it from the config
532  */
533  ipcpath = xmms_config_property_get_string (cv);
534  }
535 
536  if (!xmms_ipc_setup_server (ipcpath)) {
538  xmms_log_fatal ("IPC failed to init!");
539  }
540 
541  if (!xmms_plugin_init (ppath)) {
542  return 1;
543  }
544 
545  playlist = xmms_playlist_init ();
546  xform_obj = xmms_xform_object_init ();
547  bindata_obj = xmms_bindata_init ();
548 
549  mainobj = xmms_object_new (xmms_main_t, xmms_main_destroy);
550 
551  /* find output plugin. */
552  cv = xmms_config_property_register ("output.plugin",
553  XMMS_OUTPUT_DEFAULT,
554  change_output, mainobj);
555 
556  if (outname) {
557  xmms_config_property_set_data (cv, outname);
558  }
559 
560  outname = xmms_config_property_get_string (cv);
561  xmms_log_info ("Using output plugin: %s", outname);
563  if (!o_plugin) {
564  xmms_log_error ("Baaaaad output plugin, try to change the"
565  "output.plugin config variable to something useful");
566  }
567 
568  mainobj->output = xmms_output_new (o_plugin, playlist);
569  if (!mainobj->output) {
570  xmms_log_fatal ("Failed to create output object!");
571  }
572 
573  mainobj->vis = xmms_visualization_new (mainobj->output);
574 
575  if (status_fd != -1) {
576  write (status_fd, "+", 1);
577  }
578 
579  xmms_signal_init (XMMS_OBJECT (mainobj));
580 
581  xmms_main_register_ipc_commands (XMMS_OBJECT (mainobj));
582 
583  /* Save the time we started in order to count uptime */
584  mainobj->starttime = time (NULL);
585 
586  /* Dirty hack to tell XMMS_PATH a valid path */
587  g_strlcpy (default_path, ipcpath, sizeof (default_path));
588 
589  tmp = strchr (default_path, ';');
590  if (tmp) {
591  *tmp = '\0';
592  }
593 
594  g_setenv ("XMMS_PATH", default_path, TRUE);
595 
596  /* Also put the full path for clients that understands */
597  g_setenv("XMMS_PATH_FULL", ipcpath, TRUE);
598 
599  tmp = XMMS_BUILD_PATH ("shutdown.d");
600  cv = xmms_config_property_register ("core.shutdownpath",
601  tmp, NULL, NULL);
602  g_free (tmp);
603 
604  tmp = XMMS_BUILD_PATH ("startup.d");
605  cv = xmms_config_property_register ("core.startuppath",
606  tmp, NULL, NULL);
607  g_free (tmp);
608 
609  /* Startup dir */
610  do_scriptdir (xmms_config_property_get_string (cv), "start");
611 
612  mainloop = g_main_loop_new (NULL, FALSE);
613 
614  g_main_loop_run (mainloop);
615 
616  return 0;
617 }
618 
619 /** @} */
xmms_ipc_t * xmms_ipc_init(void)
Initialize IPC.
Definition: ipc.c:723
#define XMMS_OBJECT(p)
Definition: xmms_object.h:77
void xmms_log_init(gint verbosity)
Definition: log.c:44
void xmmsv_unref(xmmsv_t *val)
Decreases the references for the xmmsv_t When the number of references reaches 0 it will be freed...
Definition: value.c:303
#define xmms_object_unref(obj)
Definition: xmms_object.h:109
#define XMMS_IPC_PROTOCOL_VERSION
xmms_plugin_type_t xmms_plugin_type_get(const xmms_plugin_t *plugin)
Definition: plugin.c:132
void on_config_ipcsocket_change(xmms_object_t *object, xmmsv_t *_data, gpointer udata)
Gets called when the config property "core.ipcsocket" has changed.
Definition: ipc.c:438
gboolean xmms_checkroot()
xmms_xform_object_t * xmms_xform_object_init(void)
Definition: xform.c:331
struct xmmsv_St xmmsv_t
Definition: xmmsv_general.h:48
xmms_config_property_t * xmms_config_lookup(const gchar *path)
Look up a config key from the global config.
Definition: config.c:171
#define XMMSV_DICT_ENTRY_STR(k, v)
Definition: xmmsv_build.h:38
xmmsv_t * xmmsv_new_string(const char *s)
Allocates a new string xmmsv_t.
Definition: value.c:180
gboolean xmms_config_save(void)
Definition: config.c:883
void xmms_signal_block(void)
Definition: signal_dummy.c:27
gboolean xmms_plugin_init(const gchar *path)
Definition: plugin.c:219
void xmms_sqlite_print_version(void)
Definition: sqlite.c:800
const gchar * xmms_plugin_shortname_get(const xmms_plugin_t *plugin)
Definition: plugin.c:158
void xmms_config_init(const gchar *filename)
Definition: config.c:693
gboolean xmms_ipc_setup_server(const gchar *path)
Start the server.
Definition: ipc.c:785
#define XMMS_MAX_CONFIGFILE_LEN
Definition: xmms_config.h:25
#define XMMSV_DICT_END
Definition: xmmsv_build.h:40
xmms_output_t * xmms_output_new(xmms_output_plugin_t *plugin, xmms_playlist_t *playlist)
Allocate a new xmms_output_t.
Definition: output.c:928
void xmms_config_property_set_data(xmms_config_property_t *prop, const gchar *data)
Set the data of the config property to a new value.
Definition: config.c:202
#define xmms_log_error(fmt,...)
Definition: xmms_log.h:35
void xmms_object_cmd_arg_init(xmms_object_cmd_arg_t *arg)
Initialize a command argument.
Definition: object.c:236
gboolean xmms_output_plugin_switch(xmms_output_t *output, xmms_output_plugin_t *new_plugin)
Switch to another output plugin.
Definition: output.c:891
void xmms_object_emit_f(xmms_object_t *object, guint32 signalid, xmmsv_type_t type,...)
Emits a signal on the current object.
Definition: object.c:256
const gchar * xmms_plugin_version_get(const xmms_plugin_t *plugin)
Definition: plugin.c:171
xmmsv_t * xmmsv_new_list(void)
Allocates a new list xmmsv_t.
Definition: value.c:250
void xmms_signal_restore(void)
Definition: signal_dummy.c:32
void xmms_object_cmd_call(xmms_object_t *object, guint cmdid, xmms_object_cmd_arg_t *arg)
Call a command with argument.
Definition: object.c:338
struct xmms_playlist_St xmms_playlist_t
Definition: xmms_playlist.h:41
struct xmms_output_St xmms_output_t
struct xmms_output_plugin_St xmms_output_plugin_t
const gchar * xmms_config_property_get_string(const xmms_config_property_t *prop)
Return the value of a config property as a string.
Definition: config.c:243
const char * xmms_plugin_description_get(const xmms_plugin_t *plugin)
Definition: plugin.c:184
void xmms_plugin_foreach(xmms_plugin_type_t type, xmms_plugin_foreach_func_t func, gpointer user_data)
Definition: plugin.c:406
struct xmms_xform_object_St xmms_xform_object_t
Definition: xmms_xform.h:25
xmms_visualization_t * xmms_visualization_new(xmms_output_t *output)
Initialize the Vis module.
Definition: object.c:113
xmmsv_t * xmmsv_new_int(int32_t i)
Allocates a new integer xmmsv_t.
Definition: value.c:161
xmmsv_t * xmmsv_build_dict(const char *firstkey,...)
Definition: value.c:2221
#define XMMSV_DICT_ENTRY_INT(k, v)
Definition: xmmsv_build.h:39
#define xmms_log_info(fmt,...)
Definition: xmms_log.h:34
int main(int argc, char **argv)
The xmms2 daemon main initialisation function.
Definition: main.c:410
void xmms_signal_init(xmms_object_t *obj)
Definition: signal_dummy.c:37
#define XMMS_PATH_MAX
Definition: xmmsc_util.h:43
void xmms_log_shutdown()
Definition: log.c:53
void xmms_ipc_shutdown(void)
Disable IPC.
Definition: ipc.c:765
#define XMMS_DBG(fmt,...)
Definition: xmms_log.h:32
xmms_playlist_t * xmms_playlist_init(void)
Initializes a new xmms_playlist_t.
Definition: playlist.c:277
void xmms_log_set_format(const gchar *format)
Definition: log.c:35
void xmms_config_shutdown()
Definition: config.c:788
#define xmms_object_new(objtype, destroyfunc)
Definition: xmms_object.h:115
G_BEGIN_DECLS struct xmms_error_St xmms_error_t
struct xmms_main_St xmms_main_t
Definition: main.c:95
xmms_config_property_t * xmms_config_property_register(const gchar *path, const gchar *default_value, xmms_object_handler_t cb, gpointer userdata)
Register a new config property.
Definition: config.c:334
xmms_bindata_t * xmms_bindata_init()
Definition: bindata.c:75
const char * xmms_userconfdir_get(char *buf, int len)
Get the absolute path to the user config dir.
Definition: utils_unix.c:80
struct xmms_config_property_St xmms_config_property_t
Definition: xmms_config.h:26
xmms_plugin_t * xmms_plugin_find(xmms_plugin_type_t type, const gchar *name)
Definition: plugin.c:445
#define xmms_log_fatal(fmt,...)
Definition: xmms_log.h:33
const char * xmms_plugin_name_get(const xmms_plugin_t *plugin)
Definition: plugin.c:145
void xmms_plugin_shutdown()
Definition: plugin.c:235
#define XMMS_BUILD_PATH(...)
Definition: xmms_utils.h:4
const char * xmms_fallback_ipcpath_get(char *buf, int len)
Get the fallback connection path (if XMMS_PATH is not accessible)
Definition: utils_unix.c:93
struct xmms_bindata_St xmms_bindata_t
Definition: xmms_bindata.h:20
The structures for the vis module.
Definition: common.h:78