/* Python bindings for the libbeep library -- internal control module. Copyright (c) 2005 Scott Grayban This file is part of PyBMP. PyBMP 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; version 2 dated June, 1991. PyBMP 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 PyBMP; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. $Id: _bmpcontrolmodule.c 3 2006-03-28 11:52:53Z sgrayban $ */ #include /* Must come first */ #include #include #include /* Small caveat: bmp uses glib. Some functions of the libbmp require glib types such as GList. We have to use glib functions like g_list_append to build them. The problem is that these functions don't report possible (though quite rare) errors like memory exhaustion, so we have no way to raise a Python exception in those cases. */ /* For Python pre-2.3 compatibility * * Note: this could go in a common include file for _bmpcon{trol,fig}module.c * but distutils doesn't handle dependencies, so it is duplicated in the two * modules for now... */ #ifndef PyDoc_STRVAR /* Define macros for inline documentation. */ #define PyDoc_VAR(name) static char name[] #define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) #ifndef WITHOUT_DOC_STRINGS #define PyDoc_STR(str) str #else #define PyDoc_STR(str) "" #endif /* WITHOUT_DOC_STRINGS */ #endif /* PyDoc_STRVAR */ /* Small BMP 1.2.6-1.2.8 (at least) bug */ void xmms_remote_show_about_box(gint session); static PyObject *func_void_glist(void (*func)(gint, GList *), PyObject *self, PyObject *args, PyObject *warning_category, char *warning_msg); #define PYBMP_GBOOL(val) ((val) ? TRUE : FALSE) #define PYBMP_FUNC_GINT(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ \ if (!PyArg_ParseTuple(args, "|i", &session)) \ return NULL; \ \ return Py_BuildValue("i", (int) func(session)); \ } #define PYBMP_FUNC_GFLOAT(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ \ if (!PyArg_ParseTuple(args, "|i", &session)) \ return NULL; \ \ return Py_BuildValue("f", (float) func(session)); \ } #define PYBMP_FUNC_VOID_GFLOAT(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ float float_arg; \ \ if (!PyArg_ParseTuple(args, "f|i", &float_arg, &session)) \ return NULL; \ \ func(session, (gfloat) float_arg); \ \ Py_INCREF(Py_None); \ return Py_None; \ } #define PYBMP_FUNC_VOID_GINT_GFLOAT(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ int int_arg; \ float float_arg; \ \ if (!PyArg_ParseTuple(args, "if|i", &int_arg, &float_arg, &session)) \ return NULL; \ \ func(session, (gint) int_arg, (gfloat) float_arg); \ \ Py_INCREF(Py_None); \ return Py_None; \ } #define PYBMP_FUNC_GFLOAT_GINT(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ int int_arg; \ \ if (!PyArg_ParseTuple(args, "i|i", &int_arg, &session)) \ return NULL; \ \ return Py_BuildValue("f", (float) func(session, int_arg)); \ } #define PYBMP_FUNC_GINT_GINT(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ int int_arg; \ \ if (!PyArg_ParseTuple(args, "i|i", &int_arg, &session)) \ return NULL; \ \ return Py_BuildValue("i", (int) func(session, int_arg)); \ } #define PYBMP_FUNC_VOID_GLIST(wrap, func, warning_category, warning_msg) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ return func_void_glist(func, self, args, warning_category, warning_msg); \ } #define PYBMP_FUNC_VOID_GINT(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ int int_arg; \ \ if (!PyArg_ParseTuple(args, "i|i", &int_arg, &session)) \ return NULL; \ \ func(session, (gint) int_arg); \ \ Py_INCREF(Py_None); \ return Py_None; \ } #define PYBMP_FUNC_VOID_GCHARP(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ char *str; \ \ if (!PyArg_ParseTuple(args, "s|i", &str, &session)) \ return NULL; \ \ func(session, (gchar *) str); \ \ Py_INCREF(Py_None); \ return Py_None; \ } #define PYBMP_FUNC_VOID_GCHARP_GINT(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ char *str; \ int int_arg; \ \ if (!PyArg_ParseTuple(args, "si|i", &str, &int_arg, &session)) \ return NULL; \ \ func(session, (gchar *) str, (int) int_arg); \ \ Py_INCREF(Py_None); \ return Py_None; \ } #define PYBMP_FUNC_VOID_GINT_GINT(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ int int_arg1; \ int int_arg2; \ \ if (!PyArg_ParseTuple(args, "ii|i", &int_arg1, &int_arg2, &session)) \ return NULL; \ \ func(session, (gint) int_arg1, (gint) int_arg2); \ \ Py_INCREF(Py_None); \ return Py_None; \ } #define PYBMP_FUNC_VOID(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ \ if (!PyArg_ParseTuple(args, "|i", &session)) \ return NULL; \ \ func(session); \ \ Py_INCREF(Py_None); \ return Py_None; \ } #define PYBMP_FUNC_VOID_GBOOLEAN(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ int bool; \ \ if (!PyArg_ParseTuple(args, "i|i", &bool, &session)) \ return NULL; \ \ func(session, PYBMP_GBOOL(bool)); \ \ Py_INCREF(Py_None); \ return Py_None; \ } #define PYBMP_FUNC_GBOOLEAN(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ \ if (!PyArg_ParseTuple(args, "|i", &session)) \ return NULL; \ \ return Py_BuildValue("i", (func(session) == TRUE) ? 1 : 0); \ } #define PYBMP_FUNC_GCHARP(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ PyObject *res; \ gchar *str; \ \ if (!PyArg_ParseTuple(args, "|i", &session)) \ return NULL; \ \ res = Py_BuildValue("s", (char *) (str = func(session))); \ g_free(str); \ return res; \ } #define PYBMP_FUNC_GCHARP_GINT(wrap, func) \ static PyObject *wrap(PyObject *self, PyObject *args) \ { \ int session = 0; \ int int_arg; \ PyObject *res; \ gchar *str; \ \ if (!PyArg_ParseTuple(args, "i|i", &int_arg, &session)) \ return NULL; \ \ res = Py_BuildValue("s", (char *) (str = func(session, int_arg))); \ g_free(str); \ return res; \ } /* Function for local use */ static PyObject *func_void_glist(void (*func)(gint, GList *), PyObject *self, PyObject *args, PyObject *warning_category, char *warning_msg) { int session = 0; PyObject *seq, *py_str; PyObject *item = NULL; int seq_len; guint i; char *py_internal_str; gchar *string; GList *strings = NULL; GList *listelt; if (warning_category != NULL && warning_msg != NULL) if (PyErr_Warn(warning_category, warning_msg) < 0) return NULL; if (!PyArg_ParseTuple(args, "O|i", &seq, &session)) return NULL; if ((seq_len = PySequence_Size(seq)) == -1) return NULL; for (i=0; i < seq_len; i++) { /* Retreive an element from the sequence */ if ((item = PySequence_GetItem(seq, i)) == NULL) return NULL; /* Is it an Unicode object? */ if (PyUnicode_Check(item)) { /* Yes -> encode it to a regular string */ if ((py_str = PyUnicode_AsEncodedString( item, Py_FileSystemDefaultEncoding, "strict")) == NULL) goto error; Py_DECREF(item); /* We don't need the Unicode object * anymore. */ item = py_str; /* item becomes a simple string */ } if ((py_internal_str = PyString_AsString(item)) == NULL) goto error; /* In case bmp would write to py_internal_str ... */ if ((string = strdup(py_internal_str)) == NULL) { PyErr_SetFromErrno(PyExc_MemoryError); goto error; } Py_DECREF(item); strings = g_list_append(strings, string); } /* And now, the call you've been all waiting for... */ (*func)(session, strings); /* Free the strings */ for (listelt = strings; listelt != NULL; listelt = g_list_next(listelt)) free(listelt->data); /* Free the list */ g_list_free(strings); Py_INCREF(Py_None); return Py_None; error: Py_XDECREF(item); /* The exception must be set at this point */ return NULL; } /* Here follow the libbmp bindings */ PyDoc_STRVAR(playlist_doc, "Set the playlist contents and start playing, or enqueue files/URLs.\n\ \n\ playlist(seq, enqueue, session=0) -> None\n\ \n\ seq -- a sequence of files/URLs\n\ enqueue -- boolean (0 = false, 1 = true)\n\ session -- the BMP session to act on\n\ \n\ If `enqueue' is false, the playlist is set according to `seq' and\n\ BMP starts playing from the first entry. If true, the files or\n\ URLs are simply added to the playlist and the playing/not playing\n\ status is left unchanged."); static PyObject *pywrap_xmms_remote_playlist(PyObject *self, PyObject *args) { int session = 0; int enqueue; PyObject *seq, *py_str; PyObject *item = NULL; int seq_len; char **str_list; guint i; char *py_internal_str; if (!PyArg_ParseTuple(args, "Oi|i", &seq, &enqueue, &session)) return NULL; if ((seq_len = PySequence_Size(seq)) == -1) return NULL; if ((str_list = malloc(seq_len * sizeof(char *))) == NULL) { PyErr_SetFromErrno(PyExc_MemoryError); return NULL; } for (i=0; i < seq_len; i++) { /* Retreive an element from the sequence */ if ((item = PySequence_GetItem(seq, i)) == NULL) return NULL; /* Is it an Unicode object? */ if (PyUnicode_Check(item)) { /* Yes -> encode it to a regular string */ if ((py_str = PyUnicode_AsEncodedString( item, Py_FileSystemDefaultEncoding, "strict")) == NULL) goto error; Py_DECREF(item); /* We don't need the Unicode object * anymore. */ item = py_str; /* item becomes a simple string */ } if ((py_internal_str = PyString_AsString(item)) == NULL) goto error; /* In case bmp would write to the string... */ if ((str_list[i] = strdup(py_internal_str)) == NULL) { PyErr_SetFromErrno(PyExc_MemoryError); goto error; } Py_DECREF(item); } xmms_remote_playlist(session, str_list, seq_len, PYBMP_GBOOL(enqueue)); for (i=0; i < seq_len; i++) free(str_list[i]); free(str_list); Py_INCREF(Py_None); return Py_None; error: Py_XDECREF(item); /* The exception must be set at this point */ return NULL; } /* XXX Is it really the version of the protocol in use through the BMP control socket? */ PyDoc_STRVAR(get_version_doc, "Get version (of what?).\n\ \n\ get_version(session=0) -> version of what? (integer)\n\ \n\ The code fragment that answers to this request in BMP 1.2.6 is:\n\ \n\ case CMD_GET_VERSION:\n\ ctrl_write_gint(pkt->fd, 0x09a3);\n\ ...\n\ \n\ I suspect it is the version of the protocol in use through the\n\ BMP control socket (which is how libbmp talks to BMP, by the\n\ way).\n\ \n\ If you understand this better than I, please let me know."); PYBMP_FUNC_GINT(pywrap_xmms_remote_get_version, xmms_remote_get_version) PyDoc_STRVAR(play_files_doc, "Set the playlist and play.\n\ \n\ Warning: this function is deprecated in libbmp.\n\ \n\ play_files(seq, session=0) -> None\n\ \n\ Clear the playlist, add the specified files/URLs to it and start\n\ playing.\n\ \n\ seq -- a sequence of files/URLs\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GLIST(pywrap_xmms_remote_play_files, xmms_remote_play_files, PyExc_DeprecationWarning, "play_files is deprecated in libbmp") PyDoc_STRVAR(playlist_add_doc, "Add files/URLs to the playlist.\n\ \n\ playlist_add(seq, session=0) -> None\n\ \n\ seq -- a sequence of files/URLs\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GLIST(pywrap_xmms_remote_playlist_add, xmms_remote_playlist_add, NULL, NULL) PyDoc_STRVAR(playlist_delete_doc, "Delete one element of the playlist.\n\ \n\ playlist_delete(index, session=0) -> None\n\ \n\ index -- the index (starting at 0) of the playlist entry to\n\ delete\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GINT(pywrap_xmms_remote_playlist_delete, xmms_remote_playlist_delete) PyDoc_STRVAR(play_doc, "Play the current playlist entry.\n\ \n\ play(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_play, xmms_remote_play) PyDoc_STRVAR(pause_doc, "Pause.\n\ \n\ pause(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_pause, xmms_remote_pause) PyDoc_STRVAR(stop_doc, "Stop.\n\ \n\ stop(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_stop, xmms_remote_stop) PyDoc_STRVAR(play_pause_doc, "Play or pause (toggle).\n\ \n\ play_pause(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_play_pause, xmms_remote_play_pause) PyDoc_STRVAR(is_playing_doc, "Tell whether BMP is playing (= not stopped).\n\ \n\ is_playing(session=0) -> boolean (0 = false, 1 = true)\n\ \n\ When in pause, BMP is considered to be playing for this\n\ function.\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GBOOLEAN(pywrap_xmms_remote_is_playing, xmms_remote_is_playing) PyDoc_STRVAR(is_paused_doc, "Tell whether BMP is paused.\n\ \n\ is_paused(session=0) -> boolean (0 = false, 1 = true)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GBOOLEAN(pywrap_xmms_remote_is_paused, xmms_remote_is_paused) PyDoc_STRVAR(get_playlist_pos_doc, "Get the current playlist position.\n\ \n\ get_playlist_pos(session=0) -> position (integer)\n\ \n\ The count starts at 0 (first playlist entry).\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GINT(pywrap_xmms_remote_get_playlist_pos, xmms_remote_get_playlist_pos) PyDoc_STRVAR(set_playlist_pos_doc, "Set the current playlist position.\n\ \n\ set_playlist_pos(position, session=0) -> None\n\ \n\ pos -- the target playlist index (counting from 0)\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GINT(pywrap_xmms_remote_set_playlist_pos, xmms_remote_set_playlist_pos) PyDoc_STRVAR(get_playlist_length_doc, "Get the playlist length (number of files/URLs).\n\ \n\ get_playlist_length(session=0) -> length (integer)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GINT(pywrap_xmms_remote_get_playlist_length, xmms_remote_get_playlist_length) PyDoc_STRVAR(playlist_clear_doc, "Clear the playlist.\n\ \n\ playlist_clear(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_playlist_clear, xmms_remote_playlist_clear) PyDoc_STRVAR(get_output_time_doc, "Get the time since the beginning of the current playlist entry.\n\ \n\ get_output_time(session=0) -> integer value in ms\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GINT(pywrap_xmms_remote_get_output_time, xmms_remote_get_output_time) PyDoc_STRVAR(jump_to_time_doc, "Jump to a given time since the beginning of the current playlist entry.\n\ \n\ jump_to_time(time, session=0) -> None\n\ \n\ time -- time to jump to, in ms (integer)\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GINT(pywrap_xmms_remote_jump_to_time, xmms_remote_jump_to_time) PyDoc_STRVAR(get_volume_doc, "Get left and right volumes.\n\ \n\ get_volume(session=0) -> (left volume, right volume)\n\ \n\ The volumes are integers.\n\ \n\ session -- the BMP session to contact"); static PyObject *pywrap_xmms_remote_get_volume(PyObject *self, PyObject *args) { int session = 0; int vl, vr; if (!PyArg_ParseTuple(args, "|i", &session)) return NULL; xmms_remote_get_volume(session, &vl, &vr); return Py_BuildValue("(ii)", vl, vr); } PyDoc_STRVAR(get_main_volume_doc, "Get the greater of left and right volumes.\n\ \n\ get_main_volume(session=0) -> volume (integer)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GINT(pywrap_xmms_remote_get_main_volume, xmms_remote_get_main_volume) PyDoc_STRVAR(get_balance_doc, "Get the balance value.\n\ \n\ get_balance(session=0) -> balance (integer)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GINT(pywrap_xmms_remote_get_balance, xmms_remote_get_balance) PyDoc_STRVAR(set_volume_doc, "Set left and right volumes.\n\ \n\ set_volume(left_volume, right_volume, session=0) -> None\n\ \n\ left_volume -- left volume (integer)\n\ right_volume -- right volume (integer)\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GINT_GINT(pywrap_xmms_remote_set_volume, xmms_remote_set_volume) PyDoc_STRVAR(set_main_volume_doc, "Set the \"main\" volume.\n\ \n\ set_main_volume(volume, session=0) -> None\n\ \n\ The left and right volumes are calculated (and set) from the\n\ supplied `volume' argument and the current balance.\n\ \n\ volume -- \"main\" volume (integer)\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GINT(pywrap_xmms_remote_set_main_volume, xmms_remote_set_main_volume) PyDoc_STRVAR(set_balance_doc, "Set the balance.\n\ \n\ set_balance(balance, session=0) -> None\n\ \n\ balance -- balance value (integer)\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GINT(pywrap_xmms_remote_set_balance, xmms_remote_set_balance) PyDoc_STRVAR(get_skin_doc, "Get the current skin file.\n\ \n\ get_skin(session=0) -> absolute file name for the skin (string)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GCHARP(pywrap_xmms_remote_get_skin, xmms_remote_get_skin) PyDoc_STRVAR(set_skin_doc, "Set the skin from a specified file.\n\ \n\ set_skin(skin_file, session=0) -> None\n\ \n\ skin_file -- the target skin file\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GCHARP(pywrap_xmms_remote_set_skin, xmms_remote_set_skin) PyDoc_STRVAR(get_playlist_file_doc, "Get the file name corresponding to a given entry in the playlist.\n\ \n\ get_playlist_file(index, session=0) -> absolute filename (string)\n\ \n\ index -- index (starting at 0) of the playlist entry\n\ session -- the BMP session to contact"); PYBMP_FUNC_GCHARP_GINT(pywrap_xmms_remote_get_playlist_file, xmms_remote_get_playlist_file) PyDoc_STRVAR(get_playlist_title_doc, "Get the title of a given entry in the playlist.\n\ \n\ get_playlist_title(index, session=0) -> title (string)\n\ \n\ index -- index (starting at 0) of the playlist entry\n\ session -- the BMP session to contact"); PYBMP_FUNC_GCHARP_GINT(pywrap_xmms_remote_get_playlist_title, xmms_remote_get_playlist_title) PyDoc_STRVAR(get_playlist_time_doc, "Get the duration of a given entry in the playlist.\n\ \n\ get_playlist_time(index, session=0) -> duration in ms (integer)\n\ \n\ index -- index (starting at 0) of the playlist entry\n\ session -- the BMP session to contact"); PYBMP_FUNC_GINT_GINT(pywrap_xmms_remote_get_playlist_time, xmms_remote_get_playlist_time) PyDoc_STRVAR(get_info_doc, "Get information about the current playlist entry.\n\ \n\ get_info(session=0) -> (rate, frequency, number_of_channels)\n\ \n\ The elements of the returned tuple are all integers.\n\ \n\ session -- the BMP session to contact"); static PyObject *pywrap_xmms_remote_get_info(PyObject *self, PyObject *args) { int session = 0; int rate, freq, nch; if (!PyArg_ParseTuple(args, "|i", &session)) return NULL; xmms_remote_get_info(session, &rate, &freq, &nch); return Py_BuildValue("(iii)", rate, freq, nch); } PyDoc_STRVAR(pl_win_toggle_doc, "Hide or show the playlist window.\n\ \n\ pl_win_toggle(display, session=0) -> None\n\ \n\ This is not a real toggle function: you have to specify the\n\ `display' argument.\n\ \n\ display -- 1 to display the window, 0 to hide it\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GBOOLEAN(pywrap_xmms_remote_pl_win_toggle, xmms_remote_pl_win_toggle) PyDoc_STRVAR(eq_win_toggle_doc, "Hide or show the equalizer window.\n\ \n\ eq_win_toggle(display, session=0) -> None\n\ \n\ This is not a real toggle function: you have to specify the\n\ `display' argument.\n\ \n\ display -- 1 to display the window, 0 to hide it\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GBOOLEAN(pywrap_xmms_remote_eq_win_toggle, xmms_remote_eq_win_toggle) PyDoc_STRVAR(main_win_toggle_doc, "Hide or show the main window.\n\ \n\ main_win_toggle(display, session=0) -> None\n\ \n\ This is not a real toggle function: you have to specify the\n\ `display' argument.\n\ \n\ display -- 1 to display the window, 0 to hide it\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GBOOLEAN(pywrap_xmms_remote_main_win_toggle, xmms_remote_main_win_toggle) PyDoc_STRVAR(is_main_win_doc, "Tell whether the main window is visible.\n\ \n\ is_main_win(session=0) -> boolean (0 = false, 1 = true)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GBOOLEAN(pywrap_xmms_remote_is_main_win, xmms_remote_is_main_win) PyDoc_STRVAR(is_pl_win_doc, "Tell whether the playlist window is visible.\n\ \n\ is_pl_win(session=0) -> boolean (0 = false, 1 = true)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GBOOLEAN(pywrap_xmms_remote_is_pl_win, xmms_remote_is_pl_win) PyDoc_STRVAR(is_eq_win_doc, "Tell whether the equalizer window is visible.\n\ \n\ is_eq_win(session=0) -> boolean (0 = false, 1 = true)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GBOOLEAN(pywrap_xmms_remote_is_eq_win, xmms_remote_is_eq_win) PyDoc_STRVAR(show_prefs_box_doc, "Show the preferences dialog box.\n\ \n\ show_prefs_box(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_show_prefs_box, xmms_remote_show_prefs_box) /* XXX BMP weird code here */ PyDoc_STRVAR(toggle_aot_doc, "Set the always-on-top flag for the main window.\n\ \n\ toggle_aot(always, session=0) -> None\n\ \n\ The implementation of this function in BMP 1.2.6 is weird,\n\ I cannot tell you more about `always' than \"it seems not\n\ to be used\".\n\ \n\ always -- should be a boolean (0 or 1)\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GBOOLEAN(pywrap_xmms_remote_toggle_aot, xmms_remote_toggle_aot) PyDoc_STRVAR(show_about_box_doc, "Show about box.\n\ \n\ show_about_box(session=0) -> None\n\ \n\ Does not to work in BMP 1.2.6.\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_show_about_box, xmms_remote_show_about_box) PyDoc_STRVAR(eject_doc, "Show the eject dialog box.\n\ \n\ eject(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_eject, xmms_remote_eject) PyDoc_STRVAR(playlist_prev_doc, "Jump to the previous entry in the playlist.\n\ \n\ playlist_prev(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_playlist_prev, xmms_remote_playlist_prev) PyDoc_STRVAR(playlist_next_doc, "Jump to the next entry in the playlist.\n\ \n\ playlist_next(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_playlist_next, xmms_remote_playlist_next) PyDoc_STRVAR(playlist_add_url_string_doc, "Append a file/URL to the playlist.\n\ \n\ playlist_add_url_string(string, session=0) -> None\n\ \n\ string -- an absolute file name or a URL\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GCHARP(pywrap_xmms_remote_playlist_add_url_string, xmms_remote_playlist_add_url_string) PyDoc_STRVAR(playlist_ins_url_string_doc, "Insert a file/URL at a given position in the playlist.\n\ \n\ playlist_ins_url_string(string, pos, session=0) -> None\n\ \n\ string -- an absolute file name or a URL\n\ pos -- index (starting at 0) of the playlist entry before\n\ which the entry for `string' will be inserted\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GCHARP_GINT(pywrap_xmms_remote_playlist_ins_url_string, xmms_remote_playlist_ins_url_string) PyDoc_STRVAR(is_running_doc, "Tell whether the specified BMP session is running.\n\ \n\ is_running(session=0) -> boolean (0 = false, 1 = true)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GBOOLEAN(pywrap_xmms_remote_is_running, xmms_remote_is_running) PyDoc_STRVAR(toggle_repeat_doc, "Toggle repeat mode.\n\ \n\ toggle_repeat(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_toggle_repeat, xmms_remote_toggle_repeat) PyDoc_STRVAR(toggle_shuffle_doc, "Toggle shuffle mode.\n\ \n\ toggle_shuffle(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_toggle_shuffle, xmms_remote_toggle_shuffle) PyDoc_STRVAR(is_repeat_doc, "Tell whether repeat mode is active.\n\ \n\ is_repeat(session=0) -> boolean (0 = false, 1 = true)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GBOOLEAN(pywrap_xmms_remote_is_repeat, xmms_remote_is_repeat) PyDoc_STRVAR(is_shuffle_doc, "Tell whether shuffle mode is active.\n\ \n\ is_shuffle(session=0) -> boolean (0 = false, 1 = true)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GBOOLEAN(pywrap_xmms_remote_is_shuffle, xmms_remote_is_shuffle) PyDoc_STRVAR(get_eq_doc, "Get the equalizer settings.\n\ \n\ get_eq(session=0) -> (preamp, (band0, band1, ... band9))\n\ \n\ preamp, band0, ... band9 are all floats (gains in dB).\n\ \n\ session -- the BMP session to contact"); static PyObject *pywrap_xmms_remote_get_eq(PyObject *self, PyObject *args) { int session = 0; float preamp; float *bands; PyObject *res; if (!PyArg_ParseTuple(args, "|i", &session)) return NULL; xmms_remote_get_eq(session, (gfloat *) &preamp, (gfloat **) &bands); res = Py_BuildValue("(f(ffffffffff))", preamp, bands[0], bands[1], bands[2], bands[3], bands[4], bands[5], bands[6], bands[7], bands[8], bands[9]); g_free(bands); return res; } PyDoc_STRVAR(get_eq_preamp_doc, "Get the equalizer preamp value.\n\ \n\ get_eq_preamp(session=0) -> preamp in dB (float)\n\ \n\ session -- the BMP session to contact"); PYBMP_FUNC_GFLOAT(pywrap_xmms_remote_get_eq_preamp, xmms_remote_get_eq_preamp) PyDoc_STRVAR(get_eq_band_doc, "Get the equalizer setting for a given band.\n\ \n\ get_eq_band(band, session=0) -> gain in dB (float)\n\ \n\ band -- integer between 0 and 9 (both inclusive), specifying\n\ the equalizer band from which the setting is to be\n\ retrieved. 0 is for the lowest frequency and 9 for the\n\ highest one.\n\ session -- the BMP session to contact"); PYBMP_FUNC_GFLOAT_GINT(pywrap_xmms_remote_get_eq_band, xmms_remote_get_eq_band) PyDoc_STRVAR(set_eq_doc, "Set all equalizer settings (preamp and all bands).\n\ \n\ set_eq(preamp, seq, session=0) -> None\n\ \n\ preamp -- gain in dB (float)\n\ seq -- a sequence of 10 floats, which are the gains in dB of\n\ for the 10 frequency bands predefined in BMP\n\ (first = lowest frequency, last = highest frequency)\n\ session -- the BMP session to act on"); static PyObject *pywrap_xmms_remote_set_eq(PyObject *self, PyObject *args) { int session = 0; PyObject *seq, *item; PyObject *fast_seq = NULL; int seq_len; float preamp; float *bands; guint i; if (!PyArg_ParseTuple(args, "fO|i", &preamp, &seq, &session)) return NULL; if ((fast_seq = PySequence_Fast(seq, "first argument of set_eq is not a " "sequence")) == NULL) return NULL; if ((seq_len = PySequence_Size(seq)) == -1) goto error; if ((bands = malloc(seq_len * sizeof(float))) == NULL) { PyErr_SetFromErrno(PyExc_MemoryError); goto error; } for (i=0; i < seq_len; i++) { item = PySequence_Fast_GET_ITEM(fast_seq, i); bands[i] = (float) PyFloat_AsDouble(item); if (PyErr_Occurred()) goto error; } xmms_remote_set_eq(session, (gfloat) preamp, (gfloat *) bands); free(bands); Py_DECREF(fast_seq); Py_INCREF(Py_None); return Py_None; error: Py_XDECREF(fast_seq); /* The exception must be set at this point */ return NULL; } PyDoc_STRVAR(set_eq_preamp_doc, "Set the equalizer preamp value.\n\ \n\ set_eq_preamp(preamp, session=0) -> None\n\ \n\ preamp -- gain in dB (float)\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GFLOAT(pywrap_xmms_remote_set_eq_preamp, xmms_remote_set_eq_preamp) PyDoc_STRVAR(set_eq_band_doc, "Set the equalizer setting for a given band.\n\ \n\ set_eq_band(band, gain, session=0) -> None\n\ \n\ band -- number of the band (integer between 0 and 9, both\n\ inclusive, specifying the equalizer band from which\n\ the setting is to be set; 0 is for the lowest\n\ frequency and 9 for the highest one).\n\ gain -- value of the gain to set (float)\n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID_GINT_GFLOAT(pywrap_xmms_remote_set_eq_band, xmms_remote_set_eq_band) PyDoc_STRVAR(quit_doc, "Quit the specified BMP session.\n\ \n\ quit(session=0) -> None\n\ \n\ session -- the BMP session to act on"); PYBMP_FUNC_VOID(pywrap_xmms_remote_quit, xmms_remote_quit) /* (defun flo-insert-python-method-def (func doc) */ /* (interactive "sFunction: \nsDoc string: ") */ /* (insert (format " {\"%s\", pywrap_xmms_remote_%s, */ /* METH_VARARGS, \"%s.\"},\n" func func doc))) */ /* (global-set-key [f1] 'flo-insert-python-method-def) */ static PyMethodDef module_methods[] = { {"playlist", pywrap_xmms_remote_playlist, METH_VARARGS, playlist_doc}, {"get_version", pywrap_xmms_remote_get_version, METH_VARARGS, get_version_doc}, {"play_files", pywrap_xmms_remote_play_files, METH_VARARGS, play_files_doc}, {"playlist_add", pywrap_xmms_remote_playlist_add, METH_VARARGS, playlist_add_doc}, {"playlist_delete", pywrap_xmms_remote_playlist_delete, METH_VARARGS, playlist_delete_doc}, {"play", pywrap_xmms_remote_play, METH_VARARGS, play_doc}, {"pause", pywrap_xmms_remote_pause, METH_VARARGS, pause_doc}, {"stop", pywrap_xmms_remote_stop, METH_VARARGS, stop_doc}, {"play_pause", pywrap_xmms_remote_play_pause, METH_VARARGS, play_pause_doc}, {"is_playing", pywrap_xmms_remote_is_playing, METH_VARARGS, is_playing_doc}, {"is_paused", pywrap_xmms_remote_is_paused, METH_VARARGS, is_paused_doc}, {"get_playlist_pos", pywrap_xmms_remote_get_playlist_pos, METH_VARARGS, get_playlist_pos_doc}, {"set_playlist_pos", pywrap_xmms_remote_set_playlist_pos, METH_VARARGS, set_playlist_pos_doc}, {"get_playlist_length", pywrap_xmms_remote_get_playlist_length, METH_VARARGS, get_playlist_length_doc}, {"playlist_clear", pywrap_xmms_remote_playlist_clear, METH_VARARGS, playlist_clear_doc}, {"get_output_time", pywrap_xmms_remote_get_output_time, METH_VARARGS, get_output_time_doc}, {"jump_to_time", pywrap_xmms_remote_jump_to_time, METH_VARARGS, jump_to_time_doc}, {"get_volume", pywrap_xmms_remote_get_volume, METH_VARARGS, get_volume_doc}, {"get_main_volume", pywrap_xmms_remote_get_main_volume, METH_VARARGS, get_main_volume_doc}, {"get_balance", pywrap_xmms_remote_get_balance, METH_VARARGS, get_balance_doc}, {"set_volume", pywrap_xmms_remote_set_volume, METH_VARARGS, set_volume_doc}, {"set_main_volume", pywrap_xmms_remote_set_main_volume, METH_VARARGS, set_main_volume_doc}, {"set_balance", pywrap_xmms_remote_set_balance, METH_VARARGS, set_balance_doc}, {"get_skin", pywrap_xmms_remote_get_skin, METH_VARARGS, get_skin_doc}, {"set_skin", pywrap_xmms_remote_set_skin, METH_VARARGS, set_skin_doc}, {"get_playlist_file", pywrap_xmms_remote_get_playlist_file, METH_VARARGS, get_playlist_file_doc}, {"get_playlist_title", pywrap_xmms_remote_get_playlist_title, METH_VARARGS, get_playlist_title_doc}, {"get_playlist_time", pywrap_xmms_remote_get_playlist_time, METH_VARARGS, get_playlist_time_doc}, {"get_info", pywrap_xmms_remote_get_info, METH_VARARGS, get_info_doc}, {"pl_win_toggle", pywrap_xmms_remote_pl_win_toggle, METH_VARARGS, pl_win_toggle_doc}, {"eq_win_toggle", pywrap_xmms_remote_eq_win_toggle, METH_VARARGS, eq_win_toggle_doc}, {"main_win_toggle", pywrap_xmms_remote_main_win_toggle, METH_VARARGS, main_win_toggle_doc}, {"is_main_win", pywrap_xmms_remote_is_main_win, METH_VARARGS, is_main_win_doc}, {"is_pl_win", pywrap_xmms_remote_is_pl_win, METH_VARARGS, is_pl_win_doc}, {"is_eq_win", pywrap_xmms_remote_is_eq_win, METH_VARARGS, is_eq_win_doc}, {"show_prefs_box", pywrap_xmms_remote_show_prefs_box, METH_VARARGS, show_prefs_box_doc}, {"toggle_aot", pywrap_xmms_remote_toggle_aot, METH_VARARGS, toggle_aot_doc}, {"show_about_box", pywrap_xmms_remote_show_about_box, METH_VARARGS, show_about_box_doc}, {"eject", pywrap_xmms_remote_eject, METH_VARARGS, eject_doc}, {"playlist_prev", pywrap_xmms_remote_playlist_prev, METH_VARARGS, playlist_prev_doc}, {"playlist_next", pywrap_xmms_remote_playlist_next, METH_VARARGS, playlist_next_doc}, {"playlist_add_url_string", pywrap_xmms_remote_playlist_add_url_string, METH_VARARGS, playlist_add_url_string_doc}, {"playlist_ins_url_string", pywrap_xmms_remote_playlist_ins_url_string, METH_VARARGS, playlist_ins_url_string_doc}, {"is_running", pywrap_xmms_remote_is_running, METH_VARARGS, is_running_doc}, {"toggle_repeat", pywrap_xmms_remote_toggle_repeat, METH_VARARGS, toggle_repeat_doc}, {"toggle_shuffle", pywrap_xmms_remote_toggle_shuffle, METH_VARARGS, toggle_shuffle_doc}, {"is_repeat", pywrap_xmms_remote_is_repeat, METH_VARARGS, is_repeat_doc}, {"is_shuffle", pywrap_xmms_remote_is_shuffle, METH_VARARGS, is_shuffle_doc}, {"get_eq", pywrap_xmms_remote_get_eq, METH_VARARGS, get_eq_doc}, {"get_eq_preamp", pywrap_xmms_remote_get_eq_preamp, METH_VARARGS, get_eq_preamp_doc}, {"get_eq_band", pywrap_xmms_remote_get_eq_band, METH_VARARGS, get_eq_band_doc}, {"set_eq", pywrap_xmms_remote_set_eq, METH_VARARGS, set_eq_doc}, {"set_eq_preamp", pywrap_xmms_remote_set_eq_preamp, METH_VARARGS, set_eq_preamp_doc}, {"set_eq_band", pywrap_xmms_remote_set_eq_band, METH_VARARGS, set_eq_band_doc}, {"quit", pywrap_xmms_remote_quit, METH_VARARGS, quit_doc}, {NULL, NULL, 0, NULL} /* Sentinel */ }; PyDoc_STRVAR(module_doc, "Python interface to BMP --- internal module for BMP control.\n\ \n\ This module is an internal part of PyBMP and should not be used\n\ directly by \"user\" modules. It contains the direct interface to\n\ libbmp with respect to control functions.\n\ \n\ \"User\" modules should use the bmp.control module instead."); #ifndef PyMODINIT_FUNC #define PyMODINIT_FUNC void #endif PyMODINIT_FUNC init_bmpcontrol(void) /* Executed on the first import */ { Py_InitModule3("_bmpcontrol", module_methods, module_doc); return; }