From ec1ce20be1dc30748c31fc18afc1b4ca1532852e Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 16 Jan 2014 13:18:58 -0500 Subject: add is-available verb --- ponymix.1 | 4 ++++ ponymix.cc | 14 +++++++++++--- pulse.cc | 14 ++++++++++++++ pulse.h | 11 +++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/ponymix.1 b/ponymix.1 index e93a405..c78d482 100644 --- a/ponymix.1 +++ b/ponymix.1 @@ -76,6 +76,10 @@ Mute, unmute, or toggle the mute status of a device. .IP "\fBis-muted\fR" Check if a device is muted. ponymix will exit zero if muted, and non-zero otherwise. +.IP "\fis-available\fR" +Check if a device is available. This usually applies to headphone jacks, but not +all devices will support this check. ponymix will exit zero if the port is +definitively available, and non-zero if unavailable or unknown. .SS Application Commands These commands are specific to devices which refer to streams of applications. For these commands, \fIsink\fR and \fIsource\fR are synonymous with \fIsink-input\fR diff --git a/ponymix.cc b/ponymix.cc index 05fbf89..15e09f3 100644 --- a/ponymix.cc +++ b/ponymix.cc @@ -169,6 +169,7 @@ static void Print(const Card& card) { card.Name().c_str(), card.Driver().c_str(), card.ActiveProfile().name.c_str()); + } static void Print(const Profile& profile, bool active) { @@ -395,6 +396,11 @@ static int Kill(PulseClient& ponymix, int, char*[]) { return !ponymix.Kill(*device); } +static int IsAvailable(PulseClient& ponymix, int, char*[]) { + auto device = string_to_device_or_die(ponymix, opt_device, opt_devtype); + return ponymix.Availability(*device) == Device::AVAILABLE_YES; +} + static bool endswith(const string& subject, const string& predicate) { if (subject.size() < predicate.size()) { return false; @@ -430,7 +436,8 @@ static const std::pair& string_to_command( { "get-profile", { GetProfile, { 0, 0 } } }, { "set-profile", { SetProfile, { 1, 1 } } }, { "move", { Move, { 1, 1 } } }, - { "kill", { Kill, { 0, 0 } } } + { "kill", { Kill, { 0, 0 } } }, + { "is-available", { IsAvailable, { 0, 0 } } }, }; const auto match = actionmap.lower_bound(str); @@ -488,7 +495,7 @@ static void usage() { " --max-volume VALUE use VALUE as max volume\n" " --short output brief (parseable) lists\n" " --source alias to -t source\n" - " --input alais to -t source\n" + " --input alias to -t source\n" " --sink alias to -t sink\n" " --output alias to -t sink\n" " --sink-input alias to -t sink-input\n" @@ -510,7 +517,8 @@ static void usage() { " mute mute device\n" " unmute unmute device\n" " toggle toggle mute\n" - " is-muted check if muted\n", stdout); + " is-muted check if muted\n" + " is-available check if available\n", stdout); fputs("\nApplication Commands:\n" " move DEVICE move target device to DEVICE\n" " kill DEVICE kill target DEVICE\n", stdout); diff --git a/pulse.cc b/pulse.cc index 3f98b19..1704bb8 100644 --- a/pulse.cc +++ b/pulse.cc @@ -596,6 +596,20 @@ Device::Device(const pa_sink_info* info) : ops_.Kill = nullptr; ops_.Move = nullptr; ops_.SetDefault = pa_context_set_default_sink; + + if (info->active_port) { + switch (info->active_port->available) { + case PA_PORT_AVAILABLE_YES: + available_ = Device::AVAILABLE_YES; + break; + case PA_PORT_AVAILABLE_NO: + available_ = Device::AVAILABLE_NO; + break; + case PA_PORT_AVAILABLE_UNKNOWN: + available_ = Device::AVAILABLE_UNKNOWN; + break; + } + } } Device::Device(const pa_source_info* info) : diff --git a/pulse.h b/pulse.h index 2d980f0..7c17baf 100644 --- a/pulse.h +++ b/pulse.h @@ -48,6 +48,12 @@ struct Operations { class Device { public: + typedef enum { + AVAILABLE_UNKNOWN = 0, + AVAILABLE_NO, + AVAILABLE_YES, + } Availability; + Device(const pa_source_info* info); Device(const pa_sink_info* info); Device(const pa_sink_input_info* info); @@ -77,6 +83,7 @@ class Device { int balance_; uint32_t card_idx_; Operations ops_; + Device::Availability available_ = Device::AVAILABLE_UNKNOWN; }; class Card { @@ -198,6 +205,10 @@ class PulseClient { bool IsMuted(const Device& device) const { return device.mute_; }; bool SetMute(Device& device, bool mute); + Device::Availability Availability(const Device& device) const { + return device.available_; + } + // Set the profile for a card by name. bool SetProfile(Card& card, const string& profile); -- cgit v1.2.3