/************************************************************************/ /* Copyright (C) 2002 Paul Duncan */ /* */ /* Permission is hereby granted, free of charge, to any person */ /* obtaining a copy of this software and associated documentation files */ /* (the "Software"), to deal in the Software without restriction, */ /* including without limitation the rights to use, copy, modify, merge, */ /* publish, distribute, sublicense, and/or sell copies of the Software, */ /* and to permit persons to whom the Software is furnished to do so, */ /* subject to the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies of the Software, its documentation and */ /* marketing & publicity materials, and acknowledgment shall be given */ /* in the documentation, materials and software packages that this */ /* Software was used. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /************************************************************************/ #include #include #include #define UNUSED(x) ((void) (x)) #define VERSION "0.1.2" #define NUM_BANDS 10 #define BAND_MAX 20.0 #define BAND_MIN -20.0 #define VOL_MAX 100 #define VOL_MIN 0 /****************************/ /* CLASS AND MODULE GLOBALS */ /****************************/ static VALUE mXmms, cRemote, eError; /* * Create a new Xmms::Remote object. * * This method raises an ArgumentError exception if the number of * arguments isn't 0 or 1. * * Examples: * # standard setup (one running copy of XMMS) * remote = Xmms::Remote.new * * # bind to the third instance of XMMS (for you nutcases who run * # multiple instances of XMMS) * session = 2 * remote = Xmms::Remote.new session * */ VALUE xr_new(int argc, VALUE *argv, VALUE klass) { int *session; VALUE xr; session = malloc(sizeof(int)); switch (argc) { case 0: *session = 0; break; case 1: *session = NUM2INT(argv[0]); break; default: rb_raise(rb_eArgError, "invalid argument count (not 0 or 1)"); } xr = Data_Wrap_Struct(klass, 0, free, session); rb_obj_call_init(xr, argc, argv); return xr; } /* * Xmms::Remote constructor. * * This function is currently just a placeholder. * */ static VALUE xr_init(int argc, VALUE *argv, VALUE self) { UNUSED(argc); UNUSED(argv); return self; } #define CHECK_SESSION(session) if (!xmms_remote_is_running(*session)) rb_raise(eError, "XMMS is not running") /* * Get the version of XMMS. * * Note that this is separate from Xmms::Remote::VERSION, which is the * version of Xmms-Ruby. * * Examples: * version = remote.version * version = remote.get_version */ static VALUE xr_version(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return INT2FIX(xmms_remote_get_version(*session)); } /*************************/ /* BASIC CONTROL METHODS */ /*************************/ /* * Play current song. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * remote.play * */ static VALUE xr_play(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_play(*session); return self; } /* * Pause current song. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * remote.pause * */ static VALUE xr_pause(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_pause(*session); return self; } /* * Stop current song. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * remote.stop * */ static VALUE xr_stop(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_stop(*session); return self; } /* * XMMS eject button (toggle add file dialog). * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * remote.eject * */ static VALUE xr_eject(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_eject(*session); return self; } /* * Quit XMMS. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * remote.quit * */ static VALUE xr_quit(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_quit(*session); return self; } /* * Toggle Play/Pause status. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * remote.play_pause * */ static VALUE xr_play_pause(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_play_pause(*session); return self; } /****************************/ /* PLAY/PAUSE QUERY METHODS */ /****************************/ /* * Is XMMS playing? * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * puts 'playing' if remote.is_playing? * puts 'playing' if remote.playing? * */ static VALUE xr_playing(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return xmms_remote_is_playing(*session) ? Qtrue : Qfalse; } /* * Is XMMS paused? * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * puts 'paused' if remote.is_paused? * puts 'paused' if remote.paused? * */ static VALUE xr_paused(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return xmms_remote_is_paused(*session) ? Qtrue : Qfalse; } /********************/ /* PLAYLIST METHODS */ /********************/ /* * Return the current playlist. If a block is given, pass each playlist * element to the block. * * This method raises an Xmms::Error exception if XMMS is not running. * * Note: Returning the full array can be very slow for large playlists; * use the block form instead. * * Example: * # print out info for each element in the playlist * ary = remote.playlist * ary.each do |ary| * title, file, time = ary * puts "'#{title}' (#{time}ms), #{file}" * end * * # print out info for each element in the playlist (using block * # syntax; much faster) * remote.playlist { |e| puts "'#{e[0]}' (#{e[2]}), #{e[1]}" } * */ static VALUE xr_pl(VALUE self) { int i, len, *session; VALUE e, ret; char block_given = 0; Data_Get_Struct(self, int, session); CHECK_SESSION(session); block_given = rb_block_given_p(); ret = block_given ? Qnil : rb_ary_new(); len = xmms_remote_get_playlist_length(*session); e = Qnil; for (i = 0; i < len; i++) { /* if we're yielding to a block, pass the same array each time; this * should speed things up (by saving on allocations) */ if (!block_given || e == Qnil) e = rb_ary_new(); else e = rb_ary_clear(e); /* add info for current playlist element to array */ rb_ary_push(e, rb_str_new2(xmms_remote_get_playlist_title(*session, i))); rb_ary_push(e, rb_str_new2(xmms_remote_get_playlist_file(*session, i))); rb_ary_push(e, INT2FIX(xmms_remote_get_playlist_time(*session, i))); /* if block was given, yield current element; otherwise push it * into the return array */ block_given ? rb_yield(e) : rb_ary_push(ret, e); } return ret; } /* * Add one or more songs to the playlist. * * This method raises an Xmms::Error exception if XMMS is not running, * an ArgumentError exception if the number of arguments is less than 1, * or a TypeError exception if the argument isn't a String, True, or * False. * * Examples: * # replace the current playlist with one song * enqueue = false * remote.add 'path/to/cool_song.mp3', enqueue * * # add several files to the current playlist * files = %w{song01.mp3 song02.mp3 song03.mp3 song04.mp3 song05.mp3} * remote.add *files * */ static VALUE xr_pl_add(int argc, VALUE *argv, VALUE self) { int i, max, *session; VALUE enqueue = Qtrue; gchar **list; if (argc < 1) rb_raise(rb_eArgError, "invalid argument count (must be >= 1)"); list = g_malloc(sizeof(gchar*) * argc); for (i = 0, max = 0; i < argc; i++) { switch (TYPE(argv[i])) { case T_STRING: list[i] = (gchar*) RSTRING(argv[i])->ptr; max++; break; case T_TRUE: case T_FALSE: enqueue = argv[i]; break; default: rb_raise(rb_eTypeError, "invalid argument type (not string or bool)"); } } Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_playlist(*session, list, max, enqueue); /* free the list, but not the elements */ g_free(list); return self; } /* * Add a URL to the current playlist. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.add_url 'http://www.hhmecca.net/cool_song.mp3' * */ static VALUE xr_pl_add_url(VALUE self, VALUE url) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_playlist_add_url_string(*session, RSTRING(url)->ptr); return self; } /* * Insert a URL into the current playlist. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * # add a url after the 45th element in the playlist * remote.ins_url 'http://www.hhmecca.net/cool_song.mp3', 45 * */ static VALUE xr_pl_ins_url(VALUE self, VALUE url, VALUE pos) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_playlist_ins_url_string(*session, RSTRING(url)->ptr, NUM2INT(pos)); return self; } /* * Delete the Nth element of the current playlist. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.delete 26 # delete the 26th playlist element * */ static VALUE xr_pl_del(VALUE self, VALUE pos) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_playlist_delete(*session, NUM2INT(pos)); return self; } /* * Clear the current playlist. * * Examples: * remote.clear * */ static VALUE xr_pl_clear(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_playlist_clear(*session); return self; } /* * Get the current playlist position. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * song_number = remote.position * song_number = remote.get_pos * song_number = remote.pos * */ static VALUE xr_pl_pos(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return INT2FIX(xmms_remote_get_playlist_pos(*session)); } /* * Set the current playlist position. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.pos = 45 * remote.position = 45 * remote.set_pos 45 * */ static VALUE xr_pl_set_pos(VALUE self, VALUE pos) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_set_playlist_pos(*session, NUM2INT(pos)); return self; } /* * Get the file path of a song. * * This method raises an Xmms::Error exception if XMMS is not running, * or an ArgumentError exception if the number of arguments isn't 0 or * 1. * * Examples: * # get the path of the current song * path = remote.file * * # get the path of song 23 in the playlist * path = remote.file 23 * */ static VALUE xr_pl_file(int argc, VALUE *argv, VALUE self) { int pos, *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); switch (argc) { case 0: pos = xmms_remote_get_playlist_pos(*session); break; case 1: pos = NUM2INT(argv[0]); break; default: rb_raise(rb_eArgError, "invalid argument count (not 0 or 1)"); } return rb_str_new2(xmms_remote_get_playlist_file(*session, pos)); } /* * Get the title of a song. * * This method raises an Xmms::Error exception if XMMS is not running, * or an ArgumentError exception if the number of arguments isn't 0 or * 1. * * Examples: * # get the title of the current song * path = remote.file * * # get the title of song 23 in the playlist * path = remote.file 23 * */ static VALUE xr_pl_title(int argc, VALUE *argv, VALUE self) { int pos, *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); switch (argc) { case 0: pos = xmms_remote_get_playlist_pos(*session); break; case 1: pos = NUM2INT(argv[0]); break; default: rb_raise(rb_eArgError, "invalid argument count (not 0 or 1)"); } return rb_str_new2(xmms_remote_get_playlist_title(*session, pos)); } /* * Get the duration of a song, in milliseconds * * This method raises an Xmms::Error exception if XMMS is not running, * or an ArgumentError exception if the number of arguments isn't 0 or * 1. * * Examples: * # get the duration of the current song * time = remote.playlist_time * * # get the duration of song 23 in the playlist * time = remote.playlist_time 23 * */ static VALUE xr_pl_time(int argc, VALUE *argv, VALUE self) { int pos, *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); switch (argc) { case 0: pos = xmms_remote_get_playlist_pos(*session); break; case 1: pos = NUM2INT(argv[0]); break; default: rb_raise(rb_eArgError, "invalid argument count (not 0 or 1)"); } return INT2FIX(xmms_remote_get_playlist_time(*session, pos)); } /* * Return information about a specific song in the playlist. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * title, file, time = remote[45] # get info about the 45th song * info = remote.get_entry 45 # get info about the 45th song * */ static VALUE xr_pl_ary(VALUE self, VALUE pos) { int p, *session; VALUE ary; Data_Get_Struct(self, int, session); CHECK_SESSION(session); p = NUM2INT(pos); ary = rb_ary_new(); rb_ary_push(ary, rb_str_new2(xmms_remote_get_playlist_title(*session, p))); rb_ary_push(ary, rb_str_new2(xmms_remote_get_playlist_file(*session, p))); rb_ary_push(ary, INT2FIX(xmms_remote_get_playlist_time(*session, p))); return ary; } /****************/ /* TIME METHODS */ /****************/ /* * Get the output time of the current song. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * time = remote.time * time = remote.output_time * */ static VALUE xr_time(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return INT2FIX(xmms_remote_get_output_time(*session)); } /* * Jump to a specific time of the current song. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.jump 45 # jump 45 seconds into the current song * remote.time = 45 # jump 45 seconds into the current song * */ static VALUE xr_jump(VALUE self, VALUE pos) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_jump_to_time(*session, NUM2INT(pos)); return self; } /* * Go to the previous song. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * remote.prev * */ static VALUE xr_prev(VALUE self) { int *session; Data_Get_Struct(self, int, session); xmms_remote_playlist_prev(*session); return self; } /* * Go to the next song. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * remote.next * */ static VALUE xr_next(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_playlist_next(*session); return self; } /******************/ /* VOLUME METHODS */ /******************/ /* * Get the stereo volume level. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * left, right = remote.get_stereo_volume * left, right = remote.stereo_volume * */ static VALUE xr_stereo_vol(VALUE self) { int l, r, *session; VALUE ary; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_get_volume(*session, &l, &r); ary = rb_ary_new(); rb_ary_push(ary, INT2FIX(l)); rb_ary_push(ary, INT2FIX(r)); return ary; } /* * Get the main volume level. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * vol = remote.volume * vol = remote.main_volume * vol = remote.get_main_volume * */ static VALUE xr_main_vol(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return INT2FIX(xmms_remote_get_main_volume(*session)); } /* * Set the stereo volume level. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.set_stereo_volume left, right * * stereo_volume = [10, 0] * remote.set_stereo_volume *stereo_volume * */ static VALUE xr_set_stereo_vol(VALUE self, VALUE l, VALUE r) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_set_volume(*session, NUM2INT(l), NUM2INT(r)); return self; } /* * Set the main volume level. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.volume = 23 * remote.main_volume = 23 * remote.set_main_volume 23 * */ static VALUE xr_set_main_vol(VALUE self, VALUE vol) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_set_main_volume(*session, NUM2INT(vol)); return self; } /*******************/ /* BALANCE METHODS */ /*******************/ /* * Get the balance level. * * This method raises an Xmms::Error exception if XMMS is not running. * * Note: as of XMMS 1.2.6 xmms_remote_get_balance() does not appear to * work correctly when XMMS is paused or stopped, so this function doesn't * either. * * Example: * vol = remote.balance * */ static VALUE xr_balance(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return INT2FIX(xmms_remote_get_balance(*session)); } /* * Set the balance level. * * This method raises an Xmms::Error exception if XMMS is not running. * * Note: as of XMMS 1.2.6 xmms_remote_set_balance() does not appear to * work correctly when XMMS is paused or stopped, so this function doesn't * either. * * Example: * remote.balance = 23 * */ static VALUE xr_set_balance(VALUE self, VALUE bal) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_set_balance(*session, NUM2INT(bal)); return self; } /****************/ /* SKIN METHODS */ /****************/ /* * Get the current skin file. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * skin = remote.get_skin * skin = remote.skin * */ static VALUE xr_skin(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return rb_str_new2(xmms_remote_get_skin(*session)); } /* * Set the current skin file. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.set_skin 'path/to/cool_skin.zip' * remote.skin = 'path/to/cool_skin.zip' * */ static VALUE xr_set_skin(VALUE self, VALUE skin) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_set_skin(*session, RSTRING(skin)->ptr); return self; } /******************/ /* WINDOW METHODS */ /******************/ /* * Set the visibility of the main window. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.set_main_toggle true * remote.main_visible = true * remote.main = true * */ static VALUE xr_main_toggle(VALUE self, VALUE vis) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_main_win_toggle(*session, vis); return self; } /* * Get the visibility of the main window. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * puts 'main window visible' if remote.main_visible? * puts 'main window visible' if remote.main? * */ static VALUE xr_is_main(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return xmms_remote_is_main_win(*session) ? Qtrue : Qfalse; } /* * Set the visibility of the playlist window. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.set_playlist_toggle true * remote.playlist_visible = true * remote.pl_visible = true * remote.pl = true * */ static VALUE xr_pl_toggle(VALUE self, VALUE vis) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_pl_win_toggle(*session, vis); return self; } /* * Get the visibility of the playlist window. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * puts 'playlist window visible' if remote.playlist_visible? * puts 'playlist window visible' if remote.pl_visible? * puts 'playlist window visible' if remote.playlist? * puts 'playlist window visible' if remote.pl? * */ static VALUE xr_is_pl(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return xmms_remote_is_pl_win(*session) ? Qtrue : Qfalse; } /* * Set the visibility of the equalizer window. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.set_equalizer_toggle true * remote.equalizer_visible = true * remote.eq_visible = true * remote.eq = true * */ static VALUE xr_eq_toggle(VALUE self, VALUE vis) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_eq_win_toggle(*session, vis); return self; } /* * Get the visibility of the equalizer window. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * puts 'equalizer window visible' if remote.equalizer_visible? * puts 'equalizer window visible' if remote.eq_visible? * puts 'equalizer window visible' if remote.equalizer? * puts 'equalizer window visible' if remote.eq? * */ static VALUE xr_is_eq(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return xmms_remote_is_eq_win(*session) ? Qtrue : Qfalse; } /* * Show the preferences dialog. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.show_prefs * remote.prefs * */ static VALUE xr_prefs(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_show_prefs_box(*session); return self; } /* * Set the "always on top" flag. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.set_always_on_top true * remote.always_on_top = true * remote.aot = true * */ static VALUE xr_set_aot(VALUE self, VALUE aot) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_toggle_aot(*session, aot); return self; } /**************************/ /* REPEAT/SHUFFLE METHODS */ /**************************/ /* * Toggle the repeat flag. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * remote.toggle_repeat * */ static VALUE xr_toggle_repeat(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_toggle_repeat(*session); return self; } /* * Is the repeat flag set? * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * puts 'repeating' if remote.is_repeating? * puts 'repeating' if remote.repeating? * puts 'repeating' if remote.is_repeat? * puts 'repeating' if remote.repeat? * */ static VALUE xr_repeat(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return xmms_remote_is_repeat(*session) ? Qtrue : Qfalse; } /* * Toggle the shuffle flag. * * This method raises an Xmms::Error exception if XMMS is not running. * * Example: * remote.toggle_shuffle * */ static VALUE xr_toggle_shuffle(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_toggle_shuffle(*session); return self; } /* * Is the shuffle flag set? * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * puts 'shuffling' if remote.is_shuffling? * puts 'shuffling' if remote.shuffling? * puts 'shuffling' if remote.is_shuffle? * puts 'shuffling' if remote.shuffle? * */ static VALUE xr_shuffle(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return xmms_remote_is_shuffle(*session) ? Qtrue : Qfalse; } /****************/ /* MISC METHODS */ /****************/ /* * Get various information about the current song. * * This method raises an Xmms::Error exception if XMMS is not running. * * Returns an array of bitrate, frequency, and numchannels, * respectively. * * Examples: * info = remote.info * rate, freq, nch = remote.info * */ static VALUE xr_info(VALUE self) { int rate, freq, nch, *session; VALUE ary; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_get_info(*session, &rate, &freq, &nch); ary = rb_ary_new(); rb_ary_push(ary, INT2FIX(rate)); rb_ary_push(ary, INT2FIX(freq)); rb_ary_push(ary, INT2FIX(nch)); return ary; } /* * Is XMMS running? * * Examples: * puts 'xmms is running' if remote.is_running? * puts 'xmms is running' if remote.running? * */ static VALUE xr_running(VALUE self) { int *session; Data_Get_Struct(self, int, session); return xmms_remote_is_running(*session) ? Qtrue : Qfalse; } /*********************/ /* EQUALIZER METHODS */ /*********************/ /* * Get the equalizer settings. * * This method returns an array. The first element in the array is the * preamp setting, and the second element in the array is an 10 element * array of band settings. So the result would look something like * this: * * [1.0, [0.0, -0.5, 0.9, 0.0, 0.0, 0.0, 0.2, 0.5, -0.1, 0.0]] * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * preamp, bands = remote.get_equalizer * eq = remote.eq * */ static VALUE xr_eq(VALUE self) { int i, *session; VALUE ary, band_ary; gfloat preamp, *bands; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_get_eq(*session, &preamp, &bands); band_ary = rb_ary_new(); for (i = 0; i < NUM_BANDS; i++) rb_ary_push(band_ary, rb_float_new(bands[i])); ary = rb_ary_new(); rb_ary_push(ary, rb_float_new(preamp)); rb_ary_push(ary, band_ary); return ary; } /* * Get the equalizer preamp value. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * preamp = remote.get_preamp * preamp = remote.preamp * */ static VALUE xr_eq_preamp(VALUE self) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); return rb_float_new(xmms_remote_get_eq_preamp(*session)); } /* * Get an equalizer band value. * * Note: Legal band indices range from 0 to 9 instead of 1 to 10. * * This method raises an Xmms::Error exception if XMMS is not running, * and an ArgumentError exception if the band index is out of range. * * Examples: * band = remote.get_band 2 * band = remote.band 8 * */ static VALUE xr_eq_band(VALUE self, VALUE band) { int *session; int b; Data_Get_Struct(self, int, session); CHECK_SESSION(session); b = NUM2INT(band); if (b < 0 || b >= NUM_BANDS) rb_raise(rb_eArgError, "band index out of range (band < 0 or band >= 10)"); return rb_float_new(xmms_remote_get_eq_band(*session, b)); } /* * Set the equalizer values. * * This method takes either a preamp value and 10 band values, or a * preamp value and an array of band values. * * This method raises an Xmms::Error exception if XMMS is not running, * and an ArgumentError exception if the number of arguments isn't 2 or * 11. * * Examples: * bands = [0.0, -0.5, 0.9, 0.0, 0.0, 0.0, 0.2, 0.5, -0.1, 0.0] * remote.set_equalizer 0.0, bands * * remote.set_eq 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 * */ static VALUE xr_set_eq(int argc, VALUE *argv, VALUE self) { int i, *session; gfloat bands[10]; switch (argc) { case 11: for (i = 0; i < NUM_BANDS; i++) bands[i] = NUM2DBL(argv[i + 1]); break; case 2: for (i = 0; i < NUM_BANDS; i++) bands[i] = NUM2DBL(rb_ary_entry(argv[1], 2)); break; default: rb_raise(rb_eArgError,"invalid argument count (not 2 or 11)"); } Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_set_eq(*session, NUM2DBL(argv[0]), bands); return self; } /* * Set the equalizer preamp value. * * This method raises an Xmms::Error exception if XMMS is not running. * * Examples: * remote.set_preamp 0.5 * remote.preamp = 0.5 * */ static VALUE xr_eq_set_preamp(VALUE self, VALUE preamp) { int *session; Data_Get_Struct(self, int, session); CHECK_SESSION(session); xmms_remote_set_eq_preamp(*session, NUM2DBL(preamp)); return self; } /* * Set an equalizer band value. * * Note: legal band indices range from 0 to 9 instead of 1 to 10. * * This method raises an Xmms::Error exception if XMMS is not running, * or an ArgumentError exception if the band index is out of range. * * Example: * remote.set_band 2, 0.5 * */ static VALUE xr_eq_set_band(VALUE self, VALUE band, VALUE val) { int *session; int b; Data_Get_Struct(self, int, session); CHECK_SESSION(session); b = NUM2INT(band); if (b < 0 || b >= NUM_BANDS) rb_raise(rb_eArgError, "band index out of range (band < 0 or band >= 10)"); xmms_remote_set_eq_band(*session, b, NUM2DBL(val)); return self; } void Init_xmms(void) { mXmms = rb_define_module("Xmms"); /***********************/ /* define Remote class */ /***********************/ cRemote = rb_define_class_under(mXmms, "Remote", rb_cObject); rb_define_singleton_method(cRemote, "new", xr_new, -1); rb_define_singleton_method(cRemote, "connect", xr_new, -1); rb_define_method(cRemote, "initialize", xr_init, -1); /* initialize constants */ rb_define_const(cRemote, "VERSION", rb_str_new2(VERSION)); rb_define_const(cRemote, "NUM_BANDS", INT2FIX(NUM_BANDS)); rb_define_const(cRemote, "BAND_MAX", rb_float_new(BAND_MAX)); rb_define_const(cRemote, "BAND_MIN", rb_float_new(BAND_MIN)); rb_define_const(cRemote, "VOL_MAX", rb_float_new(VOL_MAX)); rb_define_const(cRemote, "VOL_MIN", rb_float_new(VOL_MIN)); /* basic control methods */ rb_define_method(cRemote, "play", xr_play, 0); rb_define_method(cRemote, "pause", xr_pause, 0); rb_define_method(cRemote, "stop", xr_stop, 0); rb_define_method(cRemote, "eject", xr_eject, 0); rb_define_method(cRemote, "quit", xr_quit, 0); rb_define_method(cRemote, "play_pause", xr_play_pause, 0); /* play/pause query methods */ rb_define_method(cRemote, "playing?", xr_playing, 0); rb_define_alias(cRemote, "is_playing", "playing?"); rb_define_alias(cRemote, "is_playing?", "playing?"); rb_define_method(cRemote, "paused?", xr_paused, 0); rb_define_alias(cRemote, "is_paused", "paused?"); rb_define_alias(cRemote, "is_paused?", "paused?"); /* playlist methods */ rb_define_method(cRemote, "playlist", xr_pl, 0); rb_define_alias(cRemote, "list", "playlist"); rb_define_alias(cRemote, "pl", "playlist"); rb_define_method(cRemote, "add", xr_pl_add, -1); rb_define_alias(cRemote, "playlist_add", "add"); rb_define_alias(cRemote, "add_files", "add"); rb_define_method(cRemote, "add_url", xr_pl_add_url, 1); rb_define_alias(cRemote, "playlist_add_url", "add_url"); rb_define_method(cRemote, "ins_url", xr_pl_ins_url, 2); rb_define_alias(cRemote, "playlist_ins_url_string", "ins_url"); rb_define_alias(cRemote, "playlist_ins_url", "ins_url"); rb_define_method(cRemote, "delete", xr_pl_del, 1); rb_define_alias(cRemote, "playlist_delete", "delete"); rb_define_alias(cRemote, "playlist_del", "delete"); rb_define_alias(cRemote, "pl_del", "delete"); rb_define_alias(cRemote, "del", "delete"); rb_define_method(cRemote, "clear", xr_pl_clear, 0); rb_define_alias(cRemote, "playlist_clear", "clear"); rb_define_alias(cRemote, "pl_clear", "clear"); rb_define_method(cRemote, "playlist_pos", xr_pl_pos, 0); rb_define_alias(cRemote, "get_playlist_position", "playlist_pos"); rb_define_alias(cRemote, "get_playlist_pos", "playlist_pos"); rb_define_alias(cRemote, "get_position", "playlist_pos"); rb_define_alias(cRemote, "get_pos", "playlist_pos"); rb_define_alias(cRemote, "position", "playlist_pos"); rb_define_alias(cRemote, "pos", "playlist_pos"); rb_define_method(cRemote, "set_playlist_pos", xr_pl_set_pos, 1); rb_define_alias(cRemote, "set_playlist_position", "set_playlist_pos"); rb_define_alias(cRemote, "set_position", "set_playlist_pos"); rb_define_alias(cRemote, "set_pos", "set_playlist_pos"); rb_define_alias(cRemote, "playlist_position=", "set_playlist_pos"); rb_define_alias(cRemote, "playlist_pos=", "set_playlist_pos"); rb_define_alias(cRemote, "position=", "set_playlist_pos"); rb_define_alias(cRemote, "pos=", "set_playlist_pos"); rb_define_method(cRemote, "get_playlist_file", xr_pl_file, -1); rb_define_alias(cRemote, "playlist_file", "get_playlist_file"); rb_define_alias(cRemote, "file", "get_playlist_file"); rb_define_method(cRemote, "get_playlist_title", xr_pl_title, -1); rb_define_alias(cRemote, "playlist_title", "get_playlist_title"); rb_define_alias(cRemote, "title", "get_playlist_title"); rb_define_method(cRemote, "get_playlist_time", xr_pl_time, -1); rb_define_alias(cRemote, "playlist_time", "get_playlist_time"); rb_define_alias(cRemote, "pl_time", "get_playlist_time"); rb_define_method(cRemote, "[]", xr_pl_ary, 1); /* time methods */ rb_define_method(cRemote, "time", xr_time, 0); rb_define_alias(cRemote, "output_time", "time"); rb_define_alias(cRemote, "get_output_time", "time"); rb_define_method(cRemote, "jump_to_time", xr_jump, 1); rb_define_alias(cRemote, "to_time", "jump_to_time"); rb_define_alias(cRemote, "jump", "jump_to_time"); rb_define_method(cRemote, "time=", xr_jump, 1); rb_define_method(cRemote, "playlist_prev", xr_prev, 0); rb_define_alias(cRemote, "prev", "playlist_prev"); rb_define_method(cRemote, "playlist_next", xr_next, 0); rb_define_alias(cRemote, "next", "playlist_next"); /* volume methods */ rb_define_method(cRemote, "get_stereo_volume", xr_stereo_vol, 0); rb_define_alias(cRemote, "stereo_volume", "get_stereo_volume"); rb_define_method(cRemote, "get_main_volume", xr_main_vol, 0); rb_define_alias(cRemote, "main_volume", "get_main_volume"); rb_define_alias(cRemote, "get_volume", "get_main_volume"); rb_define_alias(cRemote, "volume", "get_main_volume"); rb_define_method(cRemote, "set_stereo_volume", xr_set_stereo_vol, 1); rb_define_alias(cRemote, "stereo_volume=", "set_stereo_volume"); rb_define_method(cRemote, "set_main_volume", xr_set_main_vol, 1); rb_define_alias(cRemote, "main_volume=", "set_main_volume"); rb_define_alias(cRemote, "volume=", "set_main_volume"); /* balance methods */ rb_define_method(cRemote, "get_balance", xr_balance, 0); rb_define_alias(cRemote, "balance", "get_balance"); rb_define_method(cRemote, "set_balance", xr_set_balance, 1); rb_define_method(cRemote, "balance=", xr_set_balance, 1); /* skin methods */ rb_define_method(cRemote, "get_skin", xr_skin, 0); rb_define_alias(cRemote, "skin", "get_skin"); rb_define_method(cRemote, "set_skin", xr_set_skin, 1); rb_define_alias(cRemote, "skin=", "set_skin"); /* window methods */ rb_define_method(cRemote, "main_win_toggle", xr_main_toggle, 1); rb_define_alias(cRemote, "main_win=", "main_win_toggle"); rb_define_alias(cRemote, "main_visible=", "main_win_toggle"); rb_define_alias(cRemote, "main=", "main_win_toggle"); rb_define_method(cRemote, "pl_win_toggle", xr_pl_toggle, 1); rb_define_alias(cRemote, "playlist_win_toggle", "pl_win_toggle"); rb_define_alias(cRemote, "playlist_win=", "pl_win_toggle"); rb_define_alias(cRemote, "playlist_visible=", "pl_win_toggle"); rb_define_alias(cRemote, "pl_visible=", "pl_win_toggle"); rb_define_alias(cRemote, "pl_win=", "pl_win_toggle"); rb_define_method(cRemote, "eq_win_toggle", xr_eq_toggle, 1); rb_define_alias(cRemote, "equalizer_win_toggle", "eq_win_toggle"); rb_define_alias(cRemote, "equalizer_win=", "eq_win_toggle"); rb_define_alias(cRemote, "equalizer_visible=", "eq_win_toggle"); rb_define_alias(cRemote, "eq_visible=", "eq_win_toggle"); rb_define_alias(cRemote, "eq_win=", "eq_win_toggle"); rb_define_method(cRemote, "is_main_win?", xr_is_main, 0); rb_define_alias(cRemote, "is_main?", "is_main_win?"); rb_define_alias(cRemote, "is_main_visible?", "is_main_win?"); rb_define_alias(cRemote, "main_visible?", "is_main_win?"); rb_define_alias(cRemote, "main?", "is_main_win?"); rb_define_method(cRemote, "is_pl_win?", xr_is_pl, 0); rb_define_alias(cRemote, "is_pl?", "is_pl_win?"); rb_define_alias(cRemote, "is_playlist_win?", "is_pl_win?"); rb_define_alias(cRemote, "is_playlist_visible?", "is_pl_win?"); rb_define_alias(cRemote, "is_playlist?", "is_pl_win?"); rb_define_alias(cRemote, "is_pl?", "is_pl_win?"); rb_define_alias(cRemote, "playlist_visible?", "is_pl_win?"); rb_define_alias(cRemote, "pl_visible?", "is_pl_win?"); rb_define_alias(cRemote, "playlist?", "is_pl_win?"); rb_define_alias(cRemote, "pl?", "is_pl_win?"); rb_define_method(cRemote, "is_eq_win?", xr_is_eq, 0); rb_define_alias(cRemote, "is_eq?", "is_eq_win?"); rb_define_alias(cRemote, "is_equalizer_win?", "is_eq_win?"); rb_define_alias(cRemote, "is_equalizer_visible?", "is_eq_win?"); rb_define_alias(cRemote, "is_equalizer?", "is_eq_win?"); rb_define_alias(cRemote, "is_eq?", "is_eq_win?"); rb_define_alias(cRemote, "equalizer_visible?", "is_eq_win?"); rb_define_alias(cRemote, "eq_visible?", "is_eq_win?"); rb_define_alias(cRemote, "equalizer?", "is_eq_win?"); rb_define_alias(cRemote, "eq?", "is_eq_win?"); rb_define_method(cRemote, "show_prefs", xr_prefs, 0); rb_define_alias(cRemote, "show_prefs_box", "show_prefs"); rb_define_alias(cRemote, "prefs", "show_prefs"); rb_define_method(cRemote, "toggle_aot", xr_set_aot, 1); rb_define_alias(cRemote, "toggle_always_on_top", "toggle_aot"); rb_define_alias(cRemote, "set_always_on_top", "toggle_aot"); rb_define_alias(cRemote, "set_aot", "toggle_aot"); rb_define_alias(cRemote, "always_on_top=", "toggle_aot"); rb_define_alias(cRemote, "aot=", "toggle_aot"); /* repeat/shuffle methods */ rb_define_method(cRemote, "toggle_repeat", xr_toggle_repeat, 0); rb_define_method(cRemote, "is_repeat?", xr_repeat, 0); rb_define_alias(cRemote, "is_repeating?", "is_repeat?"); rb_define_alias(cRemote, "repeating?", "is_repeat?"); rb_define_alias(cRemote, "repeat?", "is_repeat?"); rb_define_method(cRemote, "toggle_shuffle", xr_toggle_shuffle, 0); rb_define_method(cRemote, "is_shuffle?", xr_shuffle, 0); rb_define_alias(cRemote, "is_shuffling?", "is_shuffle?"); rb_define_alias(cRemote, "shuffling?", "is_shuffle?"); rb_define_alias(cRemote, "shuffle?", "is_shuffle?"); /* equalizer methods */ rb_define_method(cRemote, "get_eq", xr_eq, 0); rb_define_alias(cRemote, "get_equalizer", "get_eq"); rb_define_alias(cRemote, "equalizer", "get_eq"); rb_define_alias(cRemote, "eq", "get_eq"); rb_define_method(cRemote, "set_eq", xr_set_eq, -1); rb_define_alias(cRemote, "set_equalizer", "set_eq"); rb_define_method(cRemote, "get_eq_preamp", xr_eq_preamp, 0); rb_define_alias(cRemote, "get_equalizer_preamp", "get_eq_preamp"); rb_define_alias(cRemote, "equalizer_preamp", "get_eq_preamp"); rb_define_alias(cRemote, "eq_preamp", "get_eq_preamp"); rb_define_alias(cRemote, "preamp", "get_eq_preamp"); rb_define_method(cRemote, "set_eq_preamp", xr_eq_set_preamp, 1); rb_define_alias(cRemote, "set_equalizer_preamp", "set_eq_preamp"); rb_define_alias(cRemote, "equalizer_preamp=", "set_eq_preamp"); rb_define_alias(cRemote, "eq_preamp=", "set_eq_preamp"); rb_define_alias(cRemote, "preamp=", "set_eq_preamp"); rb_define_method(cRemote, "get_eq_band", xr_eq_band, 1); rb_define_alias(cRemote, "get_equalizer_band", "get_eq_band"); rb_define_alias(cRemote, "equalizer_band", "get_eq_band"); rb_define_alias(cRemote, "eq_band", "get_eq_band"); rb_define_alias(cRemote, "band", "get_eq_band"); rb_define_method(cRemote, "set_eq_band", xr_eq_set_band, 2); rb_define_alias(cRemote, "set_equalizer_band", "set_eq_band"); rb_define_alias(cRemote, "set_band", "set_eq_band"); /* misc methods */ rb_define_method(cRemote, "get_info", xr_info, 0); rb_define_alias(cRemote, "info", "get_info"); rb_define_method(cRemote, "is_running?", xr_running, 0); rb_define_alias(cRemote, "running?", "is_running?"); rb_define_method(cRemote, "get_version", xr_version, 0); rb_define_alias(cRemote, "version", "get_version"); /**********************/ /* define Error class */ /**********************/ eError = rb_define_class_under(mXmms, "Error", rb_eStandardError); }