Implemented --on-connect and --on-disconnect

This commit is contained in:
Ingo Ruhnke 2011-01-29 05:10:34 +01:00
parent e67d5b1a1f
commit be1c7a3d27
8 changed files with 69 additions and 12 deletions

1
NEWS
View file

@ -14,6 +14,7 @@ xboxdrv 0.7.1 - (??/???/2011)
* fixed --dpad-only
* added support for Playstation button names (triangle,
circle, square, cross, L1, L2, L3, R1, R2, R3)
* added --on-connect and --on-disconnect to xboxdrv --daemon
xboxdrv 0.7.0 - (28/Jan/2011)

8
TODO
View file

@ -56,6 +56,7 @@ Stuff to do before 0.7.1 release:
* fix device name of mimic_xpad
* allow multiple controllers in non-daemon mode
* improve output in daemon mode, when --quiet is not given print the
@ -89,11 +90,6 @@ Stuff to do before 0.7.1 release:
* remember controllers that couldn't be used when all slots where full
and use them when a slot got free
* implement --on-connect and --on-disconnect for the daemon
- maybe have a more general event interface that allows to run stuff
on configuration changes, controller plug-ins, etc. (notifiy area as example)
- also supply useful information as argument
* improve output on which uinput devices are created (even with udev
there doesn't seem to be a bullet proof way to detect what gets
created)
@ -105,6 +101,8 @@ Stuff to do before 0.7.1 release:
Stuff to do before 0.7.2 release:
=================================
* add extra arguments to --on-connect and --on-disconnect (controller name, usb path, etc.)
* boost::lexical_cast<> error messages are useless, make some better ones
* couldn't convert 'XK_Page_Up' to enum, not a member of X11Keysym

View file

@ -180,8 +180,8 @@ CommandLineParser::init_argp()
.add_option(OPTION_DAEMON, 'D', "daemon", "", "Run as daemon")
.add_option(OPTION_DAEMON_DETACH, 0, "detach", "", "Detach the daemon from the current shell")
.add_option(OPTION_DAEMON_PID_FILE, 0, "pid-file", "FILE", "Write daemon pid to FILE")
.add_option(OPTION_DAEMON_ON_CONNECT, 0, "on-connect", "FILE", "Launch EXE when a new controller is connected", false)
.add_option(OPTION_DAEMON_ON_DISCONNECT, 0, "on-disconnect", "FILE", "Launch EXE when a controller is disconnected", false)
.add_option(OPTION_DAEMON_ON_CONNECT, 0, "on-connect", "FILE", "Launch EXE when a new controller is connected")
.add_option(OPTION_DAEMON_ON_DISCONNECT, 0, "on-disconnect", "FILE", "Launch EXE when a controller is disconnected")
.add_newline()
.add_text("Device Options: ")

View file

@ -18,12 +18,15 @@
#include "helper.hpp"
#include <assert.h>
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
#include <stdio.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include <iostream>
#include "raise_exception.hpp"
@ -175,5 +178,34 @@ int get_terminal_width()
return w.ws_col;
}
}
void spawn_exe(const std::string& arg0)
{
std::vector<std::string> args;
args.push_back(arg0);
spawn_exe(args);
}
void spawn_exe(const std::vector<std::string>& args)
{
assert(!args.empty());
pid_t pid = fork();
if (pid == 0)
{
char** argv = static_cast<char**>(malloc(sizeof(char*) * (args.size() + 1)));
for(size_t i = 0; i < args.size(); ++i)
{
argv[i] = strdup(args[i].c_str());
}
argv[args.size()] = NULL;
if (execvp(args[0].c_str(), argv) == -1)
{
log_error(args[0] << ": exec failed: " << strerror(errno));
_exit(EXIT_FAILURE);
}
}
}
/* EOF */

View file

@ -21,6 +21,7 @@
#include <boost/function.hpp>
#include <stdint.h>
#include <vector>
int hexstr2int(const std::string& str);
@ -73,6 +74,8 @@ float to_float_no_range_check(int value, int min, int max);
int from_float(float value, int min, int max);
int get_terminal_width();
void spawn_exe(const std::vector<std::string>& args);
void spawn_exe(const std::string& arg0);
#endif

View file

@ -600,7 +600,7 @@ Xboxdrv::run_daemon(const Options& opts)
if (!opts.detach)
{
XboxdrvDaemon daemon;
XboxdrvDaemon daemon(opts);
daemon.run(opts);
}
else
@ -637,7 +637,7 @@ Xboxdrv::run_daemon(const Options& opts)
}
else
{
XboxdrvDaemon daemon;
XboxdrvDaemon daemon(opts);
daemon.run(opts);
}
}

View file

@ -87,8 +87,9 @@ bool get_usb_path(udev_device* device, int* bus, int* dev)
}
} // namespace
XboxdrvDaemon::XboxdrvDaemon() :
XboxdrvDaemon::XboxdrvDaemon(const Options& opts) :
m_opts(opts),
m_udev(0),
m_monitor(0),
m_controller_slots(),
@ -122,6 +123,8 @@ XboxdrvDaemon::cleanup_threads()
delete i->thread;
i->thread = 0;
count += 1;
on_disconnect();
}
}
}
@ -495,6 +498,8 @@ XboxdrvDaemon::launch_xboxdrv(const XPadDevice& dev_type, const Options& opts,
thread->start_thread(opts);
slot.thread = thread.release();
on_connect();
log_info("launched XboxdrvThread for " << boost::format("%03d:%03d")
% static_cast<int>(busnum)
% static_cast<int>(devnum)
@ -519,4 +524,18 @@ XboxdrvDaemon::get_free_slot_count() const
return slot_count;
}
void
XboxdrvDaemon::on_connect()
{
log_info("launching connect script");
spawn_exe(m_opts.on_connect);
}
void
XboxdrvDaemon::on_disconnect()
{
log_info("launching disconnect script");
spawn_exe(m_opts.on_disconnect);
}
/* EOF */

View file

@ -31,6 +31,7 @@ struct XPadDevice;
class XboxdrvDaemon
{
private:
const Options& m_opts;
struct udev* m_udev;
struct udev_monitor* m_monitor;
@ -84,7 +85,7 @@ private:
std::auto_ptr<UInput> m_uinput;
public:
XboxdrvDaemon();
XboxdrvDaemon(const Options& opts);
~XboxdrvDaemon();
void run(const Options& opts);
@ -107,6 +108,9 @@ private:
ControllerSlot& slot);
int get_free_slot_count() const;
void on_connect();
void on_disconnect();
private:
XboxdrvDaemon(const XboxdrvDaemon&);
XboxdrvDaemon& operator=(const XboxdrvDaemon&);