Browse Source

Use Getopt in place of Glib::OptionContext to parse the args in the command line

release_0.2.4
Aitor 10 months ago
parent
commit
75982ed674
  1. 49
      alsa/amixer.c
  2. 1
      globals.h
  3. 25
      ui/amixer_ui.cpp
  4. 2
      ui/amixer_ui.h
  5. 289
      ui/main.cpp

49
alsa/amixer.c

@ -1147,55 +1147,6 @@ done:
return err < 0 ? 1 : 0;
}
int get_snd_card(unsigned int argc, const char *argv[], char **buf)
{
int badopt = 0;
static const struct option long_option[] =
{
{"card", 1, NULL, 'c'},
{"device", 1, NULL, 'D'},
{NULL, 0, NULL, 0},
};
*buf = (char*)malloc(sizeof(char) * 64);
if (!*buf) {
fprintf(stderr, "Memory allocation failure\n");
exit (EXIT_FAILURE);
}
while (1) {
int c;
if ((c = getopt_long(argc, (char * const*)argv, "c:D:", long_option, NULL)) < 0)
break;
switch (c) {
case 'c':
{
int i;
i = snd_card_get_index(optarg);
if (i >= 0 && i < 32)
sprintf(*buf, "hw:%i", i);
}
break;
case 'D':
{
char tmp[64];
strncpy(tmp, optarg, sizeof(tmp)-1);
tmp[sizeof(tmp)-1] = '\0';
sprintf(*buf, "%s", tmp);
}
break;
default:
fprintf(stderr, "Invalid switch or option -%c needs an argument.\n", c);
badopt++;
} // switch
} // while
if (badopt)
return 1;
return 0;
}
int amixer(const char *snd_card, unsigned int n, const char *params[])
{
int retval, level = 0;

1
globals.h

@ -73,7 +73,6 @@ void append(const char *, int, scontrols_t *);
void display(scontrols_t *);
void clear(scontrols_t *);
void destroy(scontrols_t *);
int get_snd_card(unsigned int, const char **, char **);
int amixer(const char *, unsigned int, const char **);
void * ui_new();
int run_async_snd_monitor(const char *);

25
ui/amixer_ui.cpp

@ -103,7 +103,7 @@ void nop_destroy (guchar *pixels, gpointer data)
/* NO OP */
}
AMixer_Ui::AMixer_Ui(string snd_card, vector<AMixer::SControl *> scontents, string _arg0, string _progname, bool with_systray, int x_pos, int y_pos, int width, int height, bool hidden_ok)
AMixer_Ui::AMixer_Ui(string snd_card, vector<AMixer::SControl *> scontents, string _arg0, string _progname, bool with_systray, int x_pos, int y_pos, int width, int height, int hidden_ok)
:
m_MonitorThread(nullptr),
m_HBox(false, 1),
@ -890,20 +890,25 @@ Glib::RefPtr<Gdk::Pixbuf> AMixer_Ui::set_capture_icon()
void AMixer_Ui::restart()
{
int x,y;
string systray_ok, hidden_ok;
string systray_ok;
int hidden_ok;
get_position(x, y);
restart_ok = false;
char *tmp = rindex((char*)sndCard.c_str(), ':') + 1;
systray ? systray_ok = "--systray" : systray_ok = "";
hidden ? hidden_ok = "--hidden" : hidden_ok = "";
hidden ? hidden_ok = 1 : hidden_ok = 0;
const char * params[] = { progname.c_str(), systray_ok.c_str(),
"-D", selem_name.c_str(), "-c", tmp,
"-x", to_string(x).c_str(), "-y", to_string(y).c_str(),
"-W", to_string(get_width()).c_str(), "-H", to_string(get_height()).c_str(),
hidden_ok.c_str(), (char*)0 };
const char * params[] = {
progname.c_str(),
systray_ok.c_str(),
"-D", sndCard.c_str(),
"-x", to_string(x).c_str(),
"-y", to_string(y).c_str(),
"-W", to_string(get_width()).c_str(),
"-H", to_string(get_height()).c_str(),
"-i", to_string(hidden_ok).c_str(),
(char*)0
};
execv(arg0.c_str(), (char * const*)params);
}

2
ui/amixer_ui.h

@ -109,7 +109,7 @@ typedef struct Data {
class AMixer_Ui : public Gtk::Window
{
public:
AMixer_Ui(string, vector<AMixer::SControl *>, string, string, bool, int, int, int, int, bool);
AMixer_Ui(string, vector<AMixer::SControl *>, string, string, bool, int, int, int, int, int);
virtual ~AMixer_Ui();
class SndMonitor

289
ui/main.cpp

@ -26,6 +26,8 @@
#include <unistd.h>
#include <limits.h>
#include <getopt.h>
#include <stdarg.h>
#include <globals.h>
#include "scontrol.h"
@ -132,111 +134,21 @@ static const char *amixer_warning_message = "\n\
Another instance of amixer-gtk \n\
is already running.\n";
static
void signal_handler(int signum)
{
switch(signum) {
case SIGALRM:
break;
case SIGHUP:
break;
case SIGUSR1:
break;
switch(signum) {
case SIGTERM:
case SIGINT:
case SIGQUIT:
{
ui_delete();
}
ui_delete();
exit(EXIT_SUCCESS); /* exit gracefully. */
break;
break;
default:
break;
}
}
class CmdArgParser : public Glib::OptionGroup
{
public:
CmdArgParser(const std::string&, const std::string&, const std::string&);
private:
void on_error(Glib::OptionContext& context, const Glib::Error& error);
bool on_option_arg_filename(
const Glib::ustring& option_name, const std::string& value, bool has_value);
public:
int m_card;
std::string m_device;
bool m_systray;
int m_pid = 0;
int x_pos = 1500;
int y_pos = 0;
int width = 850;
int height = 480;
bool m_hidden = true;
};
CmdArgParser::CmdArgParser(const std::string& dsc1, const std::string& dsc2, const std::string& dsc3)
: Glib::OptionGroup{dsc1, dsc2, dsc3},
m_device(""),
m_card(-1),
m_systray(false)
{
Glib::OptionEntry optDevice;
optDevice.set_long_name("device");
optDevice.set_short_name('D');
optDevice.set_description(dsc1);
add_entry_filename(optDevice, m_device);
Glib::OptionEntry optCard;
optCard.set_long_name("card");
optCard.set_short_name('c');
optCard.set_description(dsc2);
add_entry(optCard, m_card);
Glib::OptionEntry optSystray;
optSystray.set_long_name("systray");
optSystray.set_description(dsc3);
add_entry(optSystray, m_systray);
Glib::OptionEntry optX;
optX.set_long_name("xpos");
optX.set_short_name('x');
add_entry(optX, x_pos);
Glib::OptionEntry optY;
optY.set_long_name("ypos");
optY.set_short_name('y');
add_entry(optY, y_pos);
Glib::OptionEntry optW;
optW.set_long_name("width");
optW.set_short_name('W');
add_entry(optW, width);
Glib::OptionEntry optH;
optH.set_long_name("height");
optH.set_short_name('H');
add_entry(optH, height);
Glib::OptionEntry optHidden;
optHidden.set_long_name("hidden");
add_entry(optHidden, m_hidden);
}
void
CmdArgParser::on_error(Glib::OptionContext& /* context */, const Glib::Error& /* error */)
{
std::cout << "on_error called" << std::endl;
}
static
bool CheckForAnotherInstance(const char *filename)
{
@ -291,10 +203,28 @@ bool CheckForAnotherInstance(const char *filename)
return false;
}
// print usage statement
static
void config_usage(const char *progname)
{
fprintf(stderr, "%s -- Amixer-gtk\n\n"
"Usage: %s [options]\n\n"
"Options:\n"
" -h --help this help\n"
" -c --card N select the hw:N card"
" -D --device select the device, default 'default'\n"
" -s --systray run in the systray\n"
" -x --xpos x position\n"
" -y --ypos y position\n"
" -W --width window width\n"
" -H --height window height\n"
" -i --hide hide the window\n\n",
progname, progname);
}
int main(int argc, char *argv[])
{
unsigned int n, m;
char *buf = nullptr;
std::string snd_card;
snd_pcm_t *pcm_handle = NULL;
std::vector<AMixer::SControl *> scontents;
@ -302,6 +232,14 @@ int main(int argc, char *argv[])
char lockfile[128]={0};
bool is_already_running;
char target[PATH_MAX]={0};
char *buf = nullptr;
bool m_systray = false;
int x_pos = 1500;
int y_pos = 0;
int width = 850;
int height = 480;
int m_hidden = 0;
std::string filename = "/proc/" + std::to_string(getpid()) + "/exe";
ssize_t len = ::readlink(filename.c_str(), target, sizeof(target)-1);
@ -336,73 +274,110 @@ int main(int argc, char *argv[])
gtk_widget_destroy(dialog);
exit(EXIT_FAILURE);
}
std::signal(SIGTERM, signal_handler);
std::signal(SIGINT, signal_handler);
std::signal(SIGQUIT, signal_handler);
// Parse command line arguments and retrieve values:
Glib::init();
setlocale(LC_ALL, "");
Glib::OptionContext context;
CmdArgParser parser{
"Select the device",
"Select the card",
"Send to the system tray"
};
context.set_main_group(parser);
try
{
context.parse(argc, argv);
}
catch (const Glib::Error& ex)
{
std::cout << "Exception: " << ex.what() << std::endl;
}
std::cout << "parsed values: " << std::endl
<< " device = " << parser.m_device << std::endl
<< " card = " << parser.m_card << std::endl
<< " systray = " << (parser.m_systray ? "enabled" : "disabled") << std::endl
<< std::endl;
if( !parser.m_device.empty() && parser.m_card != -1 ) {
const char *p[] = { "amixer", "-D", parser.m_device.c_str(), "-c", std::to_string(parser.m_card).c_str(), (char*)0 };
n = sizeof(p)/sizeof(char*) - 1;
get_snd_card( n, p, &buf);
snd_card = std::string(buf);
free(buf);
static const struct option long_option[] =
{
{"card", required_argument, 0, 'c'},
{"device", required_argument, 0, 'D'},
{"systray", no_argument, 0, 's'},
{"xpos", required_argument, 0, 'x'},
{"ypos", required_argument, 0, 'y'},
{"width", required_argument, 0, 'W'},
{"height", required_argument, 0, 'H'},
{"hide", required_argument, 0, 'i'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0 },
};
} else if ( parser.m_device.empty() && parser.m_card != -1 ) {
const char *p[] = { "amixer", "-c", std::to_string(parser.m_card).c_str(), (char*)0 };
n = sizeof(p)/sizeof(char*) - 1;
get_snd_card( n, p, &buf);
snd_card = std::string(buf);
free(buf);
buf = (char*)malloc(sizeof(char) * 64);
if (!buf) {
fprintf(stderr, "Memory allocation failure\n");
exit (EXIT_FAILURE);
}
memset(buf, 0, sizeof(buf));
while (1) {
int c;
int option_index = 0;
if ((c = getopt_long(argc, argv, "c:D:sx:y:W:H:i:h", long_option, &option_index)) < 0)
break;
switch (c) {
} else {
case 's':
m_systray = true;
m_hidden = 1;
break;
case 'i':
m_hidden = atoi(optarg);
break;
case 'c':
{
int i;
i = snd_card_get_index(optarg);
if (i >= 0 && i < 32)
sprintf(buf, "hw:%i", i);
else {
fprintf(stderr, "Invalid card number.\n");
exit(EXIT_FAILURE);
}
}
break;
case 'D':
{
char tmp[64];
strncpy(tmp, optarg, sizeof(tmp)-1);
tmp[sizeof(tmp)-1] = '\0';
sprintf(buf, "%s", tmp);
}
break;
case 'x':
x_pos = atoi(optarg);
break;
case 'y':
y_pos = atoi(optarg);
break;
case 'W':
width = atoi(optarg);
break;
case 'H':
height = atoi(optarg);
break;
case 'h':
config_usage(progname.c_str());
break;
case '?':
if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr, "Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
abort ();
} // switch
} // while
if(*buf != 0) {
snd_card = std::string(buf);
} else {
int err;
snd_pcm_t *pcm_handle = NULL;
int n = 0;
char device_name[8] = {0};
bool found_ok = false;
while(!found_ok && n<32) {
int err;
memset(&device_name, 0, 8);
if( !parser.m_device.empty() )
sprintf(device_name, "%s:%i", parser.m_device.c_str(), n);
else
sprintf(device_name, "hw:%i", n);
snd_card = std::string("hw:") + std::to_string(n);
printf("..%s\n", snd_card.c_str());
err = snd_pcm_open (&pcm_handle, device_name, SND_PCM_STREAM_PLAYBACK, 0);
err = snd_pcm_open (&pcm_handle, snd_card.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
if(errno == 16) {
std::cout << "Device is occupied\n";
@ -416,18 +391,20 @@ int main(int argc, char *argv[])
found_ok = true;
}
if(!found_ok && argc<2) {
if(!found_ok) {
std::cout << "Sorry, cannot find sound device\n" << std::endl;
exit(EXIT_FAILURE);
} else {
snd_card = std::string(device_name);
if(!occupied_ok)
snd_pcm_close(pcm_handle);
} else if(!occupied_ok) {
snd_pcm_close(pcm_handle);
}
}
std::signal(SIGTERM, signal_handler);
std::signal(SIGINT, signal_handler);
std::signal(SIGQUIT, signal_handler);
clist = makelist();
@ -488,7 +465,7 @@ int main(int argc, char *argv[])
f_ui = new functions_Ui();
Gtk::Main kit(argc, argv, true);
AMixer::AMixer_Ui mixer(snd_card, scontents, arg0, progname, parser.m_systray, parser.x_pos, parser.y_pos, parser.width, parser.height, parser.m_hidden);
AMixer::AMixer_Ui mixer(snd_card, scontents, arg0, progname, m_systray, x_pos, y_pos, width, height, m_hidden);
kit.run(mixer);
return EXIT_SUCCESS;

Loading…
Cancel
Save