00001
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "GizmoDaemon.hpp"
00030 #include "GizmoDaemonDefs.hpp"
00031 #include "../libGizmod/GizmodThread.hpp"
00032 #include "../libGizmod/GizmodTimer.hpp"
00033 #include "../libGizmod/GizmoEventATIX10.hpp"
00034 #include "../libGizmod/GizmoEventCPUUsage.hpp"
00035 #include "../libGizmod/GizmoEventLIRC.hpp"
00036 #include "../libGizmod/GizmoEventPowermate.hpp"
00037 #include "../libGizmod/GizmoEventSoundCard.hpp"
00038 #include "../libGizmod/GizmoEventStandard.hpp"
00039 #include "../libGizmod/GizmoEventSoundCard.hpp"
00040 #include "../libGizmod/GizmoEventSoundVisualization.hpp"
00041 #include "../libGizmod/GizmoEventWindowFocus.hpp"
00042 #include "../libGizmod/GizmoATIX10.hpp"
00043 #include "../libGizmod/GizmoLIRC.hpp"
00044 #include "../libGizmod/GizmoPowermate.hpp"
00045 #include "../libGizmod/GizmoStandard.hpp"
00046 #include "../libH/Debug.hpp"
00047 #include "../libH/Exception.hpp"
00048 #include "../libH/Util.hpp"
00049 #include "../libH/UtilFile.hpp"
00050 #include "../libH/SocketException.hpp"
00051 #include <cstdlib>
00052 #include <iostream>
00053 #include <sstream>
00054 #include <fstream>
00055 #include <list>
00056 #include <boost/program_options.hpp>
00057 #include <boost/format.hpp>
00058 #include <boost/python.hpp>
00059 #include <boost/filesystem/operations.hpp>
00060 #include <boost/filesystem/exception.hpp>
00061 #include <boost/algorithm/string/replace.hpp>
00062 #include <boost/algorithm/string/trim.hpp>
00063 #include <boost/archive/text_iarchive.hpp>
00064 #include <boost/archive/text_oarchive.hpp>
00065 #include <boost/serialization/base_object.hpp>
00066 #include <boost/serialization/utility.hpp>
00067 #include <boost/serialization/list.hpp>
00068 #include <boost/tokenizer.hpp>
00069 #include <fcntl.h>
00070 #include <pystate.h>
00071
00072 using namespace std;
00073 using namespace boost;
00074 using namespace boost::program_options;
00075 using namespace boost::python;
00076 using namespace boost::filesystem;
00077 using namespace H;
00078
00080
00082
00087 #define CONFIG_FILE PACKAGE ".conf"
00088
00093 #define SCRIPT_DIR SYSCONFDIR "/gizmod/"
00094
00099 #define HOME_SCRIPT_DIR "~/.gizmod/"
00100
00105 #define CONFIG_FILE_PATH HOME_SCRIPT_DIR PACKAGE ".conf"
00106
00111 #define USER_SCRIPT_DIR "modules.d"
00112
00117 #define SCRIPT_DISPATCHER "GizmodDispatcher.py"
00118
00123 #define SCRIPT_USER "GizmodUser.py"
00124
00129 #define EVENT_NODE_DIR "/dev/input"
00130
00135 #define LIRC_DEV "/dev/lircd"
00136
00141 #define NO_GETTER python::object()
00142
00147 #define DEFAULT_PORT 30303
00148
00153 #define DEFAULT_PORT_STR "30303"
00154
00156
00158
00163 struct GizmodEventHandlerInterfaceWrap : public GizmodEventHandlerInterface {
00165 GizmodEventHandlerInterfaceWrap(PyObject * self_) : self(self_) {}
00166
00167 bool getInitialized() { return python::call_method<bool>(self, "getInitialized"); }
00168 void initialize() { return python::call_method<void>(self, "initialize"); }
00169 void onDeregisterDevice(GizmoATIX10 const * Device) { return python::call_method<void>(self, "onDeregisterDevice", ptr(Device)); }
00170 void onDeregisterDevice(GizmoLIRC const * Device) { return python::call_method<void>(self, "onDeregisterDevice", ptr(Device)); }
00171 void onDeregisterDevice(GizmoPowermate const * Device) { return python::call_method<void>(self, "onDeregisterDevice", ptr(Device)); }
00172 void onDeregisterDevice(GizmoStandard const * Device) { return python::call_method<void>(self, "onDeregisterDevice", ptr(Device)); }
00173 void onEvent(GizmoEventATIX10 const * Event, GizmoATIX10 const * Device) { return python::call_method<void>(self, "onEvent", ptr(Event), ptr(Device)); }
00174 void onEvent(GizmoEventCPUUsage const * Event) { return python::call_method<void>(self, "onEvent", ptr(Event)); }
00175 void onEvent(GizmoEventLIRC const * Event, GizmoLIRC const * Device) { return python::call_method<void>(self, "onEvent", ptr(Event), ptr(Device)); }
00176 void onEvent(GizmoEventPowermate const * Event, GizmoPowermate const * Device) { return python::call_method<void>(self, "onEvent", ptr(Event), ptr(Device)); }
00177 void onEvent(GizmoEventSoundCard const * Event) { return python::call_method<void>(self, "onEvent", ptr(Event)); }
00178 void onEvent(GizmoEventSoundVisualization const * Event) { return python::call_method<void>(self, "onEvent", ptr(Event)); }
00179 void onEvent(GizmoEventStandard const * Event, GizmoStandard const * Device) { return python::call_method<void>(self, "onEvent", ptr(Event), ptr(Device)); }
00180 void onEvent(GizmoEventWindowFocus const * Event) { return python::call_method<void>(self, "onEvent", ptr(Event)); }
00181 GizmoClass onQueryDeviceClass(DeviceInfo DeviceInformation) { return python::call_method<GizmoClass>(self, "onQueryDeviceClass", DeviceInformation); };
00182 void onRegisterDevice(GizmoATIX10 const * Device) { return python::call_method<void>(self, "onRegisterDevice", ptr(Device)); }
00183 void onRegisterDevice(GizmoLIRC const * Device) { return python::call_method<void>(self, "onRegisterDevice", ptr(Device)); }
00184 void onRegisterDevice(GizmoPowermate const * Device) { return python::call_method<void>(self, "onRegisterDevice", ptr(Device)); }
00185 void onRegisterDevice(GizmoStandard const * Device) { return python::call_method<void>(self, "onRegisterDevice", ptr(Device)); }
00186
00187 PyObject * self;
00188 };
00189
00193 BOOST_PYTHON_MODULE(GizmoDaemon) {
00195
00197
00199 enum_<AlsaEventType>("AlsaEventType")
00200 .value("Error", ALSAEVENT_ERROR)
00201 .value("SoundCardAttach", ALSAEVENT_SOUNDCARD_ATTACH)
00202 .value("SoundCardDetach", ALSAEVENT_SOUNDCARD_DETACH)
00203 .value("MixerElementAttach", ALSAEVENT_MIXERELEMENT_ATTACH)
00204 .value("MixerElementChange", ALSAEVENT_MIXERELEMENT_CHANGE)
00205 .value("MixerElementDetach", ALSAEVENT_MIXERELEMENT_DETACH)
00206 ;
00207
00209 enum_<GizmoClass>("GizmoClass")
00210 .value("ATIX10", GIZMO_CLASS_ATIX10)
00211 .value("LIRC", GIZMO_CLASS_LIRC)
00212 .value("Powermate", GIZMO_CLASS_POWERMATE)
00213 .value("Standard", GIZMO_CLASS_STANDARD)
00214 ;
00215
00217 enum_<GizmoEventClass>("GizmoEventClass")
00218 .value("ATIX10", GIZMO_EVENTCLASS_ATIX10)
00219 .value("CPUUsage", GIZMO_EVENTCLASS_CPUUSAGE)
00220 .value("LIRC", GIZMO_EVENTCLASS_LIRC)
00221 .value("Powermate", GIZMO_EVENTCLASS_POWERMATE)
00222 .value("SoundCard", GIZMO_EVENTCLASS_SOUNDCARD)
00223 .value("SoundVisualization", GIZMO_EVENTCLASS_SOUNDVISUALIZATION)
00224 .value("Standard", GIZMO_EVENTCLASS_STANDARD)
00225 .value("WindowFocus", GIZMO_EVENTCLASS_WINDOWFOCUS)
00226 ;
00227
00229 enum_<SoundVisualizationEventType>("SoundVisualizationEventType")
00230 .value("Connect", SOUNDVISUALIZATION_CONNECT)
00231 .value("Disconnect", SOUNDVISUALIZATION_DISCONNECT)
00232 .value("Render", SOUNDVISUALIZATION_RENDER)
00233 ;
00234
00236 enum_<X11FocusEventType>("X11FocusEventType")
00237 .value("FocusIn", X11FOCUSEVENT_IN)
00238 .value("FocusOut", X11FOCUSEVENT_OUT)
00239 ;
00240
00242 #include "GizmoKeyDefPythonExposures.hpp"
00243
00245
00247
00249 class_<AlsaInterface>("AlsaInterface")
00250 ;
00251
00253 class_<AlsaMixerElements>("AlsaMixerElements")
00254 .def_readonly("IsActive", &AlsaMixerElements::IsActive)
00255 .def_readonly("HasCommonVolume", &AlsaMixerElements::HasCommonVolume)
00256 .def_readonly("HasPlaybackVolume", &AlsaMixerElements::HasPlaybackVolume)
00257 .def_readonly("HasPlaybackVolumeJoined", &AlsaMixerElements::HasPlaybackVolumeJoined)
00258 .def_readonly("HasCaptureVolume", &AlsaMixerElements::HasCaptureVolume)
00259 .def_readonly("HasCaptureVolumeJoined", &AlsaMixerElements::HasCaptureVolumeJoined)
00260 .def_readonly("HasCommonSwitch", &AlsaMixerElements::HasCommonSwitch)
00261 .def_readonly("HasPlaybackSwitch", &AlsaMixerElements::HasPlaybackSwitch)
00262 .def_readonly("HasPlaybackSwitchJoined", &AlsaMixerElements::HasPlaybackSwitchJoined)
00263 .def_readonly("HasCaptureSwitch", &AlsaMixerElements::HasCaptureSwitch)
00264 .def_readonly("HasCaptureSwitchJoined", &AlsaMixerElements::HasCaptureSwitchJoined)
00265 .def_readonly("HasCaptureSwitchExclusive", &AlsaMixerElements::HasCaptureSwitchExclusive)
00266 .def_readonly("VolumeCapture", &AlsaMixerElements::VolumeCapture)
00267 .def_readonly("VolumeCaptureMin", &AlsaMixerElements::VolumeCaptureMin)
00268 .def_readonly("VolumeCaptureMax", &AlsaMixerElements::VolumeCaptureMax)
00269 .def_readonly("VolumeCapturePercent", &AlsaMixerElements::VolumeCapturePercent)
00270 .def_readonly("VolumePlayback", &AlsaMixerElements::VolumePlayback)
00271 .def_readonly("VolumePlaybackMin", &AlsaMixerElements::VolumePlaybackMin)
00272 .def_readonly("VolumePlaybackMax", &AlsaMixerElements::VolumePlaybackMax)
00273 .def_readonly("VolumePlaybackPercent", &AlsaMixerElements::VolumePlaybackPercent)
00274 .def_readonly("SwitchPlayback", &AlsaMixerElements::SwitchPlayback)
00275 .def_readonly("SwitchCapture", &AlsaMixerElements::SwitchCapture)
00276 ;
00277
00279 class_< AlsaMixer, bases<AlsaMixerElements> >("AlsaMixer")
00280 .def("getName", &AlsaMixer::getName)
00281 .add_property("Name", &AlsaMixer::getName)
00282 .def("getNameShort", &AlsaMixer::getNameShort)
00283 .add_property("NameShort", &AlsaMixer::getNameShort)
00284 .def("setSwitchCapture", &AlsaMixer::setSwitchCapture)
00285 .add_property("SwitchCapture", &AlsaMixer::SwitchCapture, &AlsaMixer::setSwitchCapture)
00286 .def("setSwitchPlayback", &AlsaMixer::setSwitchPlayback)
00287 .add_property("SwitchPlayback", &AlsaMixer::SwitchPlayback, &AlsaMixer::setSwitchPlayback)
00288 .def("setVolumeCapture", &AlsaMixer::setVolumeCapture)
00289 .add_property("VolumeCapture", &AlsaMixer::VolumeCapture, &AlsaMixer::setVolumeCapture)
00290 .def("setVolumeCapturePercent", &AlsaMixer::setVolumeCapturePercent)
00291 .add_property("VolumeCapturePercent", &AlsaMixer::VolumeCapturePercent, &AlsaMixer::setVolumeCapturePercent)
00292 .def("setVolumePlayback", &AlsaMixer::setVolumePlayback)
00293 .add_property("VolumePlayback", &AlsaMixer::VolumePlayback, &AlsaMixer::setVolumePlayback)
00294 .def("setVolumePlaybackPercent", &AlsaMixer::setVolumePlaybackPercent)
00295 .add_property("VolumePlaybackPercent", &AlsaMixer::VolumePlaybackPercent, &AlsaMixer::setVolumePlaybackPercent)
00296 ;
00297
00299 class_<AlsaSoundCard>("AlsaSoundCard", init<AlsaInterface *, int>())
00300 .def("getCardHardwareID", &AlsaSoundCard::getCardHardwareID)
00301 .add_property("CardHardwareID", &AlsaSoundCard::getCardHardwareID)
00302 .def("getCardID", &AlsaSoundCard::getCardID)
00303 .add_property("CardID", &AlsaSoundCard::getCardID)
00304 .def("getCardNameLong", &AlsaSoundCard::getCardNameLong)
00305 .add_property("CardNameLong", &AlsaSoundCard::getCardNameLong)
00306 .def("getCardName", &AlsaSoundCard::getCardName)
00307 .add_property("CardName", &AlsaSoundCard::getCardName)
00308 .def("getMixer", &AlsaSoundCard::getMixer, return_internal_reference<>())
00309 .def("getNumMixers", &AlsaSoundCard::getNumMixers)
00310 .def("setAllPlaybackSwitches", &AlsaSoundCard::setAllPlaybackSwitches)
00311 ;
00312
00314 class_<Alsa>("Alsa")
00315 .def("getDefaultMixerSwitch", &Alsa::getDefaultMixerSwitch, return_internal_reference<>())
00316 .add_property("DefaultMixerSwitch", make_function(&Alsa::getDefaultMixerSwitch, return_internal_reference<>()))
00317 .def("getDefaultMixerVolume", &Alsa::getDefaultMixerVolume, return_internal_reference<>())
00318 .add_property("DefaultMixerVolume", make_function(&Alsa::getDefaultMixerVolume, return_internal_reference<>()))
00319 .def("getSoundCard", &Alsa::getSoundCard, return_internal_reference<>())
00320 .def("getNumSoundCards", &Alsa::getNumSoundCards)
00321 .def("registerDefaultMixerPriority", &Alsa::registerDefaultMixerPriority)
00322 .def("toggleMuteAllCards", &Alsa::toggleMuteAllCards)
00323 ;
00324
00326 class_<DeviceInfo>("GizmoDeviceInfo")
00327 .def_readonly("DeviceName", &DeviceInfo::DeviceName)
00328 .def_readonly("DeviceIDBusType", &DeviceInfo::DeviceIDBusType)
00329 .def_readonly("DeviceIDVendor", &DeviceInfo::DeviceIDVendor)
00330 .def_readonly("DeviceIDProduct", &DeviceInfo::DeviceIDProduct)
00331 .def_readonly("DeviceIDVersion", &DeviceInfo::DeviceIDVersion)
00332 .def_readonly("FileName", &DeviceInfo::FileName)
00333 ;
00334
00336 class_< Gizmo, bases<DeviceInfo> >("Gizmo", init<GizmoClass, const DeviceInfo &, int, int>())
00337 .def("getClass", &Gizmo::getClass)
00338 .add_property("Class", &Gizmo::getClass)
00339 .def("getDeviceID", &Gizmo::getDeviceID)
00340 .add_property("DeviceID", &Gizmo::getDeviceID)
00341 .def("getDeviceClassID", &Gizmo::getDeviceClassID)
00342 .add_property("DeviceClassID", &Gizmo::getDeviceClassID)
00343 .def("getKeyState", &Gizmo::getKeyState)
00344 .def("getType", &Gizmo::getType)
00345 .add_property("Type", &Gizmo::getType)
00346 .def("setKeyState", &Gizmo::setKeyState)
00347 ;
00348
00350 class_<CPUUsage>("CPUUsage")
00351 .def("getNumCPUs", &CPUUsage::getNumCPUs)
00352 .def("setTimeBetweenUpdates", &CPUUsage::setTimeBetweenUpdates)
00353 ;
00354
00356 class_<Processes>("Processes")
00357 .def("isProcessRunning", &Processes::isProcessRunning)
00358 .staticmethod("isProcessRunning")
00359 .def("setTimeBetweenUpdates", &Processes::setTimeBetweenUpdates)
00360 .staticmethod("setTimeBetweenUpdates")
00361 .def("updateProcessTree", &Processes::updateProcessTree)
00362 .staticmethod("updateProcessTree")
00363 ;
00364
00366 class_<X11FocusWatcher>("X11FocusWatcher")
00367 .def("isApplicationRunning", &X11FocusWatcher::isApplicationRunning)
00368 .def("setInputFocus", &X11FocusWatcher::setInputFocus)
00369 ;
00370
00372 class_<GizmoUtils>("GizmoUtils")
00373 .def("bitDifference", &GizmoUtils::bitDifference)
00374 .staticmethod("bitDifference")
00375 ;
00376
00378 class_<GizmoDaemon, bases<Alsa, X11FocusWatcher, Processes, CPUUsage, GizmoUtils> >("PyGizmoDaemon")
00379 .def("checkVersion", &GizmoDaemon::checkVersion)
00380 .def("getCurrentFocus", &GizmoDaemon::getCurrentFocus)
00381 .add_property("CurrentFocus", &GizmoDaemon::getCurrentFocus)
00382 .def("getDebugEnabled", &GizmoDaemon::getDebugEnabled)
00383 .add_property("DebugEnabled", &GizmoDaemon::getDebugEnabled)
00384 .def("getNumGizmosByClass", &GizmoDaemon::getNumGizmosByClass)
00385 .def("getUseKeyboardLEDs", &GizmoDaemon::getUseKeyboardLEDs)
00386 .add_property("UseKeyboardLEDs", &GizmoDaemon::getUseKeyboardLEDs)
00387 .def("getUseRemoteControl", &GizmoDaemon::getUseRemoteControl)
00388 .add_property("UseRemoteControl", &GizmoDaemon::getUseRemoteControl)
00389 .def("getVersion", &GizmoDaemon::getVersion)
00390 .add_property("Version", &GizmoDaemon::getVersion)
00391 .def("printNiceScriptInit", &GizmoDaemon::printNiceScriptInit)
00392 .def("printNiceScriptRegister", &GizmoDaemon::printNiceScriptRegister)
00393 .def("signalShutdown", &GizmoDaemon::signalShutdown)
00394 ;
00395
00397 class_<GizmoTimeVal>("GizmoTimeVal")
00398 .def_readonly("Seconds", &GizmoTimeVal::Seconds)
00399 .def_readonly("MicroSeconds", &GizmoTimeVal::MicroSeconds)
00400 ;
00401
00403
00405
00407 class_<AlsaEvent>("AlsaEvent")
00408 .def_readonly("Type", &AlsaEvent::Type)
00409 .def_readonly("Mask", &AlsaEvent::Mask)
00410 .def_readonly("IsActiveChanged", &AlsaEvent::IsActiveChanged)
00411 .def_readonly("ElementsChanged", &AlsaEvent::ElementsChanged)
00412 .def_readonly("VolumePlaybackChanged", &AlsaEvent::VolumePlaybackChanged)
00413 .def_readonly("VolumeCaptureChanged", &AlsaEvent::VolumeCaptureChanged)
00414 .def_readonly("SwitchPlaybackChanged", &AlsaEvent::SwitchPlaybackChanged)
00415 .def_readonly("SwitchCaptureChanged", &AlsaEvent::SwitchCaptureChanged)
00416 ;
00417
00419 class_<GizmodEventHandlerInterface, GizmodEventHandlerInterfaceWrap, boost::noncopyable>("GizmodEventHandler")
00420 ;
00421
00423 class_<GizmodThread>("GizmodThread", init<boost::python::object>())
00424 .def("create", &GizmodThread::create)
00425 ;
00426
00428 class_<GizmodTimer>("GizmodTimer", init<float, boost::python::object>())
00429 .def(init<float, boost::python::object, boost::python::object>())
00430 .def(init<float, boost::python::object, int, boost::python::object>())
00431 .def("start", &GizmodTimer::start)
00432 .def("setUserData", &GizmodTimer::setUserData)
00433 .def("setTime", &GizmodTimer::setTime)
00434 .def("resetTimer", &GizmodTimer::resetTimer)
00435 .def("cancel", &GizmodTimer::cancel)
00436 ;
00437
00439 class_<GizmoEvent>("GizmoEvent", init<GizmoEventClass, bool>())
00440 .def("getClass", &GizmoEvent::getClass)
00441 .add_property("Class", &GizmoEvent::getClass)
00442 .def("isRemote", &GizmoEvent::isRemote)
00443 .add_property("Remote", &GizmoEvent::isRemote)
00444 ;
00445
00447 class_< GizmoEventCPUUsage, bases<GizmoEvent> >("GizmoEventCPUUsage")
00448 .def("getCPUUsage", &GizmoEventCPUUsage::getCPUUsage)
00449 .def("getCPUUsageAvg", &GizmoEventCPUUsage::getCPUUsageAvg)
00450 .def("getNumCPUs", &GizmoEventCPUUsage::getNumCPUs)
00451 .add_property("NumCPUs", &GizmoEventCPUUsage::getNumCPUs)
00452 ;
00453
00455 class_< GizmoEventLIRC, bases<GizmoEvent> >("GizmoEventLIRC")
00456 .def_readonly("Code", &GizmoEventLIRC::Code)
00457 .def_readonly("Repeat", &GizmoEventLIRC::Repeat)
00458 .def_readonly("Button", &GizmoEventLIRC::Button)
00459 .def_readonly("Remote", &GizmoEventLIRC::Remote)
00460 ;
00461
00463 class_<GizmoLinuxInputDevice>("GizmoLinuxInputDevice", init<const DeviceInfo &>())
00464 .def("createEventRaw", &GizmoLinuxInputDevice::createEventRaw)
00465 .def("createEventPress", &GizmoLinuxInputDevice::createEventPress)
00466 .def("createEvent", &GizmoLinuxInputDevice::createEventPress)
00467 .def("createEventPressMod", &GizmoLinuxInputDevice::createEventPressMod)
00468 .def("createEventPress", &GizmoLinuxInputDevice::createEventPressMod)
00469 .def("createEvent", &GizmoLinuxInputDevice::createEventPressMod)
00470 .def("createEvents", &GizmoLinuxInputDevice::createEvents)
00471 .def("grabExclusiveAccess", &GizmoLinuxInputDevice::grabExclusiveAccess)
00472 .def("remapKey", &GizmoLinuxInputDevice::remapKey)
00473 .def("setMinimumTimeBetweenEvents", &GizmoLIRC::setMinimumTimeBetweenEvents)
00474 ;
00475
00477 class_<GizmoLinuxInputEvent>("GizmoLinuxInputEvent")
00478 .def_readonly("RawCode", &GizmoLinuxInputEvent::RawCode)
00479 .def_readonly("RawType", &GizmoLinuxInputEvent::RawType)
00480 .def_readonly("Value", &GizmoLinuxInputEvent::Value)
00481 .def_readonly("TimeStamp", &GizmoLinuxInputEvent::TimeStamp)
00482 .def_readonly("Code", &GizmoLinuxInputEvent::Code)
00483 .def_readonly("Type", &GizmoLinuxInputEvent::Type)
00484 ;
00485
00487 class_< GizmoEventATIX10, bases<GizmoEvent, GizmoLinuxInputEvent> >("GizmoEventATIX10")
00488 ;
00489
00491 class_< GizmoEventPowermate, bases<GizmoEvent, GizmoLinuxInputEvent> >("GizmoEventPowermate")
00492 .def_readonly("ClickTime", &GizmoEventPowermate::ClickTime)
00493 ;
00494
00496 class_< GizmoEventStandard, bases<GizmoEvent, GizmoLinuxInputEvent> >("GizmoEventStandard")
00497 ;
00498
00500 class_< GizmoEventSoundCard, bases<AlsaEvent, GizmoEvent> >("GizmoEventSoundCard", init<AlsaEvent const &, AlsaSoundCard const &, AlsaMixer const &>())
00501 .def("getMixer", &GizmoEventSoundCard::getMixer, return_internal_reference<>())
00502 .add_property("Mixer", make_function(&GizmoEventSoundCard::getMixer, return_internal_reference<>()))
00503 .def("getSoundCard", &GizmoEventSoundCard::getSoundCard, return_internal_reference<>())
00504 .add_property("SoundCard", make_function(&GizmoEventSoundCard::getSoundCard, return_internal_reference<>()))
00505 ;
00506
00508 class_< GizmoEventSoundVisualization, bases<GizmoEvent> >("GizmoEventSoundVisualization")
00509 .def("getVULeft", &GizmoEventSoundVisualization::getVULeft)
00510 .add_property("VULeft", &GizmoEventSoundVisualization::getVULeft)
00511 .def("getVURight", &GizmoEventSoundVisualization::getVURight)
00512 .add_property("VURight", &GizmoEventSoundVisualization::getVURight)
00513 .def("getVUCombined", &GizmoEventSoundVisualization::getVUCombined)
00514 .add_property("VUCombined", &GizmoEventSoundVisualization::getVUCombined)
00515 .def("getType", &GizmoEventSoundVisualization::getType)
00516 .add_property("Type", &GizmoEventSoundVisualization::getType)
00517 ;
00518
00520 class_<X11FocusEvent>("X11FocusEvent", init<X11FocusEvent const &>())
00521 .def_readonly("WindowEventType", &X11FocusEvent::EventType)
00522 .def_readonly("WindowClass", &X11FocusEvent::WindowClass)
00523 .def_readonly("WindowName", &X11FocusEvent::WindowName)
00524 .def_readonly("WindowNameFormal", &X11FocusEvent::WindowNameFormal)
00525 ;
00526
00528 class_< GizmoEventWindowFocus, bases<X11FocusEvent, GizmoEvent> >("GizmoEventWindowFocus", init<X11FocusEvent const &>())
00529 ;
00530
00532
00534
00536 class_< GizmoATIX10, bases<Gizmo, GizmoLinuxInputDevice> >("GizmoATIX10", init<const DeviceInfo &, int, int>())
00537 ;
00538
00540 class_< GizmoLIRC, bases<Gizmo> >("GizmoLIRC", init<const DeviceInfo &, int, int>())
00541 .def("setDisableFirstRepeats", &GizmoLIRC::setDisableFirstRepeats)
00542 .def("setMinimumTimeBetweenEvents", &GizmoLIRC::setMinimumTimeBetweenEvents)
00543 ;
00544
00546 class_< GizmoPowermate, bases<Gizmo, GizmoLinuxInputDevice> >("GizmoPowermate", init<const DeviceInfo &, int, int>())
00547 .def("changeLEDState", &GizmoPowermate::changeLEDState)
00548 .def("getLED", &GizmoPowermate::getLED)
00549 .def("getLEDPercent", &GizmoPowermate::getLEDPercent)
00550 .def("getLEDPulseAsleep", &GizmoPowermate::getLEDPulseAsleep)
00551 .def("getRotated", &GizmoPowermate::getRotated)
00552 .def("pulseLED", &GizmoPowermate::pulseLED)
00553 .def("setLED", &GizmoPowermate::setLED)
00554 .def("setLEDPercent", &GizmoPowermate::setLEDPercent)
00555 .def("setLEDPulseAsleep", &GizmoPowermate::setLEDPulseAsleep)
00556 .def("setRotateSensitivity", &GizmoPowermate::setRotateSensitivity)
00557 .add_property("LED", &GizmoPowermate::getLED, &GizmoPowermate::setLED)
00558 .add_property("LEDPercent", &GizmoPowermate::getLEDPercent, &GizmoPowermate::setLEDPercent)
00559 .add_property("LEDPulseAsleep", &GizmoPowermate::getLEDPulseAsleep, &GizmoPowermate::setLEDPulseAsleep)
00560 .add_property("Rotated", &GizmoPowermate::getRotated)
00561 .add_property("RotateSensitivity", &GizmoPowermate::setRotateSensitivity)
00562 ;
00563
00565 class_< GizmoStandard, bases<Gizmo, GizmoLinuxInputDevice> >("GizmoStandard", init<const DeviceInfo &, int, int>())
00566 ;
00567 }
00568
00570
00572
00576 GizmoDaemon::GizmoDaemon() {
00577 cout << getProps();
00578
00579 setConfigDir();
00580 mClientHost = "";
00581 mClientPort = DEFAULT_PORT;
00582 mDisabledALSA = false;
00583 mDisabledCPUUsage = false;
00584 mDisabledX11 = false;
00585 mDisableShutdownMessage = false;
00586 mEventsDir = EVENT_NODE_DIR;
00587 mInitialized = false;
00588 mLircDev = LIRC_DEV;
00589 mLocalDisabled = false;
00590 mpPyDispatcher = NULL;
00591 mReloadConfig = false;
00592 mServerPort = DEFAULT_PORT;
00593 mServerEnabled = false;
00594 mShuttingDown = false;
00595 mUseKeyboardLEDs = false;
00596 mUseRemoteControl = false;
00597 mVersion = 0.0;
00598 setVersionInfo();
00599 }
00600
00604 GizmoDaemon::~GizmoDaemon() {
00605 if (!mDisableShutdownMessage)
00606 cout << "GizmoDaemon Shutting Down... ";
00607 mShuttingDown = true;
00608 if (!mDisableShutdownMessage) cout << "|"; flush(cout);
00609 X11FocusWatcher::shutdown(); if (!mDisableShutdownMessage) cout << "\b/"; flush(cout);
00610 Alsa::shutdown(); if (!mDisableShutdownMessage) cout << "\b-"; flush(cout);
00611 CPUUsage::shutdown(); if (!mDisableShutdownMessage) cout << "\b\\"; flush(cout);
00612 SocketServer::shutdown(); if (!mDisableShutdownMessage) cout << "\b|"; flush(cout);
00613 Py_Finalize();
00614 Py_Initialize();
00615 if (!mDisableShutdownMessage)
00616 cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b Down. " << endl << endl;
00617 }
00618
00620
00622
00629 bool GizmoDaemon::checkVersion(double Version, bool Strict) {
00630 double VersionDiff = fabs(Version - mVersion);
00631 if (Strict) {
00632 return VersionDiff < 0.1;
00633 } else {
00634 if (Version - 0.05 <= mVersion)
00635 return true;
00636 else
00637 return false;
00638 }
00639 }
00640
00645 void GizmoDaemon::deleteGizmo(std::string FileName) {
00646 if (mShuttingDown)
00647 return;
00648
00649
00650 if (!mGizmos.count(FileName)) {
00651
00652 cdbg << "Tried to delete non-existent Gizmo [" << FileName << "]" << endl;
00653 return;
00654 }
00655
00656
00657 shared_ptr<Gizmo> pGizmo = mGizmos[FileName];
00658
00659
00660 try {
00661 mutex::scoped_lock lock(mMutexScript);
00662 switch (pGizmo->getClass()) {
00663 case GIZMO_CLASS_ATIX10:
00664 mpPyDispatcher->onDeregisterDevice(static_cast<GizmoATIX10 const *>(pGizmo.get()));
00665 break;
00666 case GIZMO_CLASS_LIRC:
00667 mpPyDispatcher->onDeregisterDevice(static_cast<GizmoLIRC const *>(pGizmo.get()));
00668 break;
00669 case GIZMO_CLASS_POWERMATE:
00670 mpPyDispatcher->onDeregisterDevice(static_cast<GizmoPowermate const *>(pGizmo.get()));
00671 break;
00672 case GIZMO_CLASS_STANDARD:
00673 mpPyDispatcher->onDeregisterDevice(static_cast<GizmoStandard const *>(pGizmo.get()));
00674 break;
00675 }
00676 } catch (error_already_set) {
00677 PyErr_Print();
00678 throw H::Exception("Failed to call GizmodDispatcher.onEvent for deleteGizmo", __FILE__, __FUNCTION__, __LINE__);
00679 }
00680
00681
00682 mGizmos.erase(FileName);
00683 cdbg2 << "Deleted Gizmo [" << FileName << "]" << endl;
00684 }
00685
00691 void GizmoDaemon::deserializeMessage(GizmoEventClass EventClass, std::string const & Message) {
00692 switch (EventClass) {
00693 case GIZMO_EVENTCLASS_ATIX10:
00694 deserializeMessageATIX10(Message);
00695 break;
00696 case GIZMO_EVENTCLASS_CPUUSAGE:
00697 deserializeMessageCPUUsage(Message);
00698 break;
00699 case GIZMO_EVENTCLASS_LIRC:
00700 deserializeMessageLIRC(Message);
00701 break;
00702 case GIZMO_EVENTCLASS_POWERMATE:
00703 deserializeMessagePowermate(Message);
00704 break;
00705 case GIZMO_EVENTCLASS_SOUNDCARD:
00706 deserializeMessageSoundcard(Message);
00707 break;
00708 case GIZMO_EVENTCLASS_SOUNDVISUALIZATION:
00709 deserializeMessageSoundVisualization(Message);
00710 break;
00711 case GIZMO_EVENTCLASS_STANDARD:
00712 deserializeMessageStandard(Message);
00713 break;
00714 case GIZMO_EVENTCLASS_WINDOWFOCUS:
00715 deserializeMessageWindowFocus(Message);
00716 break;
00717 }
00718 }
00719
00724 void GizmoDaemon::deserializeMessageATIX10(std::string const & Message) {
00725
00726 size_t SepPos = Message.find("|");
00727 if (SepPos == string::npos) {
00728 cdbg << "Could not deserialize LIRC message -- invalid format" << endl;
00729 return;
00730 }
00731 string MessageEvent = Message.substr(0, SepPos);
00732 string MessageDevice = Message.substr(SepPos + 1);
00733
00734
00735 stringstream InStreamEvent(MessageEvent);
00736 archive::text_iarchive InArchiveEvent(InStreamEvent);
00737 GizmoEventATIX10 Event;
00738 InArchiveEvent >> Event;
00739 Event.setIsRemote(true);
00740
00741 stringstream InStreamDevice(MessageDevice);
00742 archive::text_iarchive InArchiveDevice(InStreamDevice);
00743 GizmoATIX10 Gizmo;
00744 InArchiveDevice >> Gizmo;
00745
00746
00747 if (!mLocalDisabled) {
00748 try {
00749 mutex::scoped_lock lock(mMutexScript);
00750 mpPyDispatcher->onEvent(&Event, &Gizmo);
00751 } catch (error_already_set) {
00752 PyErr_Print();
00753 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
00754 }
00755 }
00756 }
00757
00762 void GizmoDaemon::deserializeMessageCPUUsage(std::string const & Message) {
00763
00764 stringstream InStream(Message);
00765 archive::text_iarchive InArchive(InStream);
00766 GizmoEventCPUUsage Event;
00767 InArchive >> Event;
00768 Event.setIsRemote(true);
00769
00770
00771 if (!mLocalDisabled) {
00772 try {
00773 mutex::scoped_lock lock(mMutexScript);
00774 mpPyDispatcher->onEvent(&Event);
00775 } catch (error_already_set) {
00776 PyErr_Print();
00777 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
00778 }
00779 }
00780 }
00781
00786 void GizmoDaemon::deserializeMessageLIRC(std::string const & Message) {
00787
00788 size_t SepPos = Message.find("|");
00789 if (SepPos == string::npos) {
00790 cdbg << "Could not deserialize LIRC message -- invalid format" << endl;
00791 return;
00792 }
00793 string MessageEvent = Message.substr(0, SepPos);
00794 string MessageDevice = Message.substr(SepPos + 1);
00795
00796
00797 stringstream InStreamEvent(MessageEvent);
00798 archive::text_iarchive InArchiveEvent(InStreamEvent);
00799 GizmoEventLIRC Event;
00800 InArchiveEvent >> Event;
00801 Event.setIsRemote(true);
00802
00803 stringstream InStreamDevice(MessageDevice);
00804 archive::text_iarchive InArchiveDevice(InStreamDevice);
00805 GizmoLIRC Gizmo;
00806 InArchiveDevice >> Gizmo;
00807
00808
00809 if (!mLocalDisabled) {
00810 try {
00811 mutex::scoped_lock lock(mMutexScript);
00812 mpPyDispatcher->onEvent(&Event, &Gizmo);
00813 } catch (error_already_set) {
00814 PyErr_Print();
00815 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
00816 }
00817 }
00818 }
00819
00824 void GizmoDaemon::deserializeMessagePowermate(std::string const & Message) {
00825
00826 size_t SepPos = Message.find("|");
00827 if (SepPos == string::npos) {
00828 cdbg << "Could not deserialize LIRC message -- invalid format" << endl;
00829 return;
00830 }
00831 string MessageEvent = Message.substr(0, SepPos);
00832 string MessageDevice = Message.substr(SepPos + 1);
00833
00834
00835 stringstream InStreamEvent(MessageEvent);
00836 archive::text_iarchive InArchiveEvent(InStreamEvent);
00837 GizmoEventPowermate Event;
00838 InArchiveEvent >> Event;
00839 Event.setIsRemote(true);
00840
00841 stringstream InStreamDevice(MessageDevice);
00842 archive::text_iarchive InArchiveDevice(InStreamDevice);
00843 GizmoPowermate Gizmo;
00844 InArchiveDevice >> Gizmo;
00845
00846
00847 if (!mLocalDisabled) {
00848 try {
00849 mutex::scoped_lock lock(mMutexScript);
00850 mpPyDispatcher->onEvent(&Event, &Gizmo);
00851 } catch (error_already_set) {
00852 PyErr_Print();
00853 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
00854 }
00855 }
00856 }
00857
00862 void GizmoDaemon::deserializeMessageSoundcard(std::string const & Message) {
00863
00864 stringstream InStream(Message);
00865 archive::text_iarchive InArchive(InStream);
00866 GizmoEventSoundCard Event;
00867 InArchive >> Event;
00868 Event.setIsRemote(true);
00869
00870
00871 if (!mLocalDisabled) {
00872 try {
00873 mutex::scoped_lock lock(mMutexScript);
00874 mpPyDispatcher->onEvent(&Event);
00875 } catch (error_already_set) {
00876 PyErr_Print();
00877 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
00878 }
00879 }
00880 }
00881
00886 void GizmoDaemon::deserializeMessageSoundVisualization(std::string const & Message) {
00887
00888 stringstream InStream(Message);
00889 archive::text_iarchive InArchive(InStream);
00890 GizmoEventSoundVisualization Event;
00891 InArchive >> Event;
00892 Event.setIsRemote(true);
00893
00894
00895 if (!mLocalDisabled) {
00896 try {
00897 mutex::scoped_lock lock(mMutexScript);
00898 mpPyDispatcher->onEvent(&Event);
00899 } catch (error_already_set) {
00900 PyErr_Print();
00901 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
00902 }
00903 }
00904 }
00905
00910 void GizmoDaemon::deserializeMessageStandard(std::string const & Message) {
00911
00912 size_t SepPos = Message.find("|");
00913 if (SepPos == string::npos) {
00914 cdbg << "Could not deserialize LIRC message -- invalid format" << endl;
00915 return;
00916 }
00917 string MessageEvent = Message.substr(0, SepPos);
00918 string MessageDevice = Message.substr(SepPos + 1);
00919
00920
00921 stringstream InStreamEvent(MessageEvent);
00922 archive::text_iarchive InArchiveEvent(InStreamEvent);
00923 GizmoEventStandard Event;
00924 InArchiveEvent >> Event;
00925 Event.setIsRemote(true);
00926
00927 stringstream InStreamDevice(MessageDevice);
00928 archive::text_iarchive InArchiveDevice(InStreamDevice);
00929 GizmoStandard Gizmo;
00930 InArchiveDevice >> Gizmo;
00931
00932
00933 if (!mLocalDisabled) {
00934 try {
00935 mutex::scoped_lock lock(mMutexScript);
00936 mpPyDispatcher->onEvent(&Event, &Gizmo);
00937 } catch (error_already_set) {
00938 PyErr_Print();
00939 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
00940 }
00941 }
00942 }
00943
00948 void GizmoDaemon::deserializeMessageWindowFocus(std::string const & Message) {
00949
00950 stringstream InStream(Message);
00951 archive::text_iarchive InArchive(InStream);
00952 GizmoEventWindowFocus Event;
00953 InArchive >> Event;
00954 Event.setIsRemote(true);
00955
00956
00957 if (!mLocalDisabled) {
00958 try {
00959 mutex::scoped_lock lock(mMutexScript);
00960 mpPyDispatcher->onEvent(&Event);
00961 } catch (error_already_set) {
00962 PyErr_Print();
00963 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
00964 }
00965 }
00966 }
00967
00971 void GizmoDaemon::enterLoop() {
00972 if (mShuttingDown)
00973 return;
00974 if (!mInitialized)
00975 throw H::Exception("You must initialize GizmoDaemon first!", __FILE__, __FUNCTION__, __LINE__);
00976
00977 watchForFileEvents();
00978 }
00979
00987 X11FocusEvent GizmoDaemon::getCurrentFocus() {
00988 return mCurrentFocus;
00989 }
00990
00998 bool GizmoDaemon::getDebugEnabled() {
00999 return Debug::getEnabled();
01000 }
01001
01006 GizmodEventHandlerInterface * GizmoDaemon::getDispatcher() {
01007 return mpPyDispatcher;
01008 }
01009
01015 boost::shared_ptr<Gizmo> GizmoDaemon::getGizmoByFileName(std::string FileName) {
01016 return mGizmos[FileName];
01017 }
01018
01024 int GizmoDaemon::getNumGizmosByClass(GizmoClass Class) {
01025 int Count = 0;
01026 for (map< string, shared_ptr<Gizmo> >::iterator iter = mGizmos.begin(); iter != mGizmos.end(); iter ++) {
01027 shared_ptr<Gizmo> pGizmo = iter->second;
01028 if ( (pGizmo.get() != NULL) && (pGizmo->getClass() == Class) )
01029 Count ++;
01030 }
01031 return Count;
01032 }
01033
01039 int GizmoDaemon::getGizmoClassID(GizmoClass Class) {
01040 vector<bool> IDs;
01041 int tot = getNumGizmosByClass(Class);
01042 IDs.resize(tot + 1, false);
01043
01044 for (map< string, shared_ptr<Gizmo> >::iterator iter = mGizmos.begin(); iter != mGizmos.end(); iter ++) {
01045 shared_ptr<Gizmo> pGizmo = iter->second;
01046 if ( (pGizmo.get() != NULL) && (pGizmo->getClass() == Class) )
01047 IDs[pGizmo->getDeviceClassID()] = true;
01048 }
01049
01050 for (size_t lp = 0; lp < IDs.size(); lp ++) {
01051 if (!IDs[lp])
01052 return lp;
01053 }
01054
01055 return tot;
01056 }
01057
01061 string GizmoDaemon::getProps() {
01062 return "\nGizmoDaemon v" VERSION " -=- (c) 2007, Tim Burrell <tim.burrell@gmail.com>\n=---------=\n";
01063 }
01064
01069 bool GizmoDaemon::getReloadConfig() {
01070 return mReloadConfig;
01071 }
01072
01077 bool GizmoDaemon::getUseKeyboardLEDs() {
01078 return mUseKeyboardLEDs;
01079 }
01080
01085 bool GizmoDaemon::getUseRemoteControl() {
01086 return mUseRemoteControl;
01087 }
01088
01096 std::string GizmoDaemon::getUserScriptDirPaths() {
01097 string ret;
01098 string UserScriptDir = mConfigDir + USER_SCRIPT_DIR;
01099 cdbg1 << "Adding [" << UserScriptDir << "] to the System Path" << endl;
01100 path UserScriptPath(UserScriptDir);
01101 if (!filesystem::exists(UserScriptPath))
01102 throw H::Exception("User Script dir [" + UserScriptDir + "] does NOT exist or permissions are wrong!", __FILE__, __FUNCTION__, __LINE__);
01103
01104
01105
01106 directory_iterator endItr;
01107 for (directory_iterator iter(UserScriptDir); iter != endItr; iter ++) {
01108 if (filesystem::is_directory(*iter))
01109 ret += "sys.path.insert(0, \"" + iter->string() + "\")\n";
01110 }
01111
01112 return ret;
01113 }
01114
01121 double GizmoDaemon::getVersion() {
01122 return mVersion;
01123 }
01124
01130 void GizmoDaemon::handleFileEventReadATIX10(GizmoATIX10 & Gizmo, DynamicBuffer<char> const & ReadBuffer) {
01131 std::vector< boost::shared_ptr<GizmoEventATIX10> > EventVector;
01132 GizmoEventATIX10::buildEventsVectorFromBuffer(EventVector, ReadBuffer, Gizmo.getSendNullEvents());
01133 for (size_t lp = 0; lp < EventVector.size(); lp ++) {
01134 if (Gizmo.processEvent(EventVector[lp].get()))
01135 if (!mLocalDisabled) {
01136 try {
01137 mutex::scoped_lock lock(mMutexScript);
01138 mpPyDispatcher->onEvent(EventVector[lp].get(), &Gizmo);
01139 } catch (error_already_set) {
01140 PyErr_Print();
01141 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
01142 }
01143 }
01144
01145
01146 try {
01147 sendEventATIX10(static_cast<GizmoEventATIX10 const &>(*EventVector[lp]), static_cast<GizmoATIX10 const &>(Gizmo));
01148 } catch (SocketException const & e) {
01149 cdbg << "Failed to send LIRC Message to Server -- " << e.getExceptionMessage() << endl;
01150 }
01151 }
01152 }
01153
01159 void GizmoDaemon::handleFileEventReadLIRC(GizmoLIRC & Gizmo, DynamicBuffer<char> const & ReadBuffer) {
01160 std::vector< boost::shared_ptr<GizmoEventLIRC> > EventVector;
01161 GizmoEventLIRC::buildEventsVectorFromBuffer(EventVector, ReadBuffer);
01162 for (size_t lp = 0; lp < EventVector.size(); lp ++) {
01163 if (Gizmo.processEvent(EventVector[lp].get())) {
01164
01165 if (!mLocalDisabled) {
01166 try {
01167 mutex::scoped_lock lock(mMutexScript);
01168 mpPyDispatcher->onEvent(EventVector[lp].get(), &Gizmo);
01169 } catch (error_already_set) {
01170 PyErr_Print();
01171 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
01172 }
01173 }
01174
01175
01176 try {
01177 sendEventLIRC(static_cast<GizmoEventLIRC const &>(*EventVector[lp]), static_cast<GizmoLIRC const &>(Gizmo));
01178 } catch (SocketException const & e) {
01179 cdbg << "Failed to send LIRC Message to Server -- " << e.getExceptionMessage() << endl;
01180 }
01181 }
01182 }
01183 }
01184
01190 void GizmoDaemon::handleFileEventReadPowermate(GizmoPowermate & Gizmo, DynamicBuffer<char> const & ReadBuffer) {
01191 std::vector< boost::shared_ptr<GizmoEventPowermate> > EventVector;
01192 GizmoEventPowermate::buildEventsVectorFromBuffer(EventVector, ReadBuffer, Gizmo.getSendNullEvents());
01193 for (size_t lp = 0; lp < EventVector.size(); lp ++) {
01194 if (Gizmo.processEvent(EventVector[lp].get()))
01195 if (!mLocalDisabled) {
01196 try {
01197 mutex::scoped_lock lock(mMutexScript);
01198 mpPyDispatcher->onEvent(EventVector[lp].get(), &Gizmo);
01199 } catch (error_already_set) {
01200 PyErr_Print();
01201 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
01202 }
01203 }
01204
01205
01206 try {
01207 sendEventPowermate(static_cast<GizmoEventPowermate const &>(*EventVector[lp]), static_cast<GizmoPowermate const &>(Gizmo));
01208 } catch (SocketException const & e) {
01209 cdbg << "Failed to send LIRC Message to Server -- " << e.getExceptionMessage() << endl;
01210 }
01211 }
01212 }
01213
01219 void GizmoDaemon::handleFileEventReadStandard(GizmoStandard & Gizmo, DynamicBuffer<char> const & ReadBuffer) {
01220 std::vector< boost::shared_ptr<GizmoEventStandard> > EventVector;
01221 GizmoEventStandard::buildEventsVectorFromBuffer(EventVector, ReadBuffer, Gizmo.getSendNullEvents());
01222 for (size_t lp = 0; lp < EventVector.size(); lp ++) {
01223 if (Gizmo.processEvent(EventVector[lp].get()))
01224 if (!mLocalDisabled) {
01225 try {
01226 mutex::scoped_lock lock(mMutexScript);
01227 mpPyDispatcher->onEvent(EventVector[lp].get(), &Gizmo);
01228 } catch (error_already_set) {
01229 PyErr_Print();
01230 cerr << "Failed to call GizmodDispatcher.onEvent for deserializeMessage" << endl;
01231 }
01232 }
01233
01234
01235 try {
01236 sendEventStandard(static_cast<GizmoEventStandard const &>(*EventVector[lp]), static_cast<GizmoStandard const &>(Gizmo));
01237 } catch (SocketException const & e) {
01238 cdbg << "Failed to send LIRC Message to Server -- " << e.getExceptionMessage() << endl;
01239 }
01240 }
01241 }
01242
01248 void GizmoDaemon::initGizmod() {
01249 if (mInitialized)
01250 return;
01251
01252
01253 initSignals();
01254
01255
01256 try {
01257 initPython();
01258 if (mShuttingDown)
01259 return;
01260 } catch (H::Exception & e) {
01261 throw e;
01262 } catch (exception & e) {
01263 throw H::Exception("Failed to Initialize Python!", __FILE__, __FUNCTION__, __LINE__);
01264 }
01265
01266
01267 if (mClientHost != "") {
01268 try {
01269 cout << "Connecting to [" << mClientHost << "] at Port [" << mClientPort << "]..." << endl;
01270 connectToServer(mClientHost, mClientPort);
01271 if (mShuttingDown)
01272 return;
01273 } catch (SocketException const & e) {
01274 throw H::Exception(e.getExceptionMessage(), __FILE__, __FUNCTION__, __LINE__);
01275 }
01276 }
01277
01278
01279 try {
01280 registerDevices();
01281 if (mShuttingDown)
01282 return;
01283 } catch (H::Exception & e) {
01284 throw e;
01285 }
01286
01287
01288 try {
01289 loadUserScripts();
01290 if (mShuttingDown)
01291 return;
01292 } catch (H::Exception & e) {
01293 throw e;
01294 }
01295
01296
01297 if (mServerEnabled) {
01298 try {
01299 acceptConnections(mServerPort);
01300 } catch (SocketException const & e) {
01301 throw H::Exception("Failed to Start Server -- " + e.getExceptionMessage(), __FILE__, __FUNCTION__, __LINE__);
01302 }
01303 }
01304
01305
01306 if (!mDisabledX11)
01307 X11FocusWatcher::init();
01308
01309
01310 if (!mDisabledCPUUsage)
01311 CPUUsage::init();
01312
01313
01314 if (!mDisabledALSA) {
01315 try {
01316 Alsa::init();
01317 } catch (H::Exception & e) {
01318 cerr << e.getExceptionMessage() << endl;
01319 }
01320 }
01321
01322
01323 mInitialized = true;
01324 }
01325
01329 void GizmoDaemon::initPython() {
01330 try {
01331 cdbg1 << "Embedding Python Interpreter..." << endl;
01332 PyImport_AppendInittab("GizmoDaemon", &initGizmoDaemon);
01333
01334
01335 Py_Initialize();
01336
01337 cdbg1 << "Initializing Python Environment..." << endl;
01338 mPyMainModule = object((handle<>(borrowed(PyImport_AddModule("__main__")))));
01339 mPyMainNamespace = mPyMainModule.attr("__dict__");
01340
01341
01342 object GizmoDaemonModule( (handle<>(PyImport_ImportModule("GizmoDaemon"))) );
01343 mPyMainNamespace["GizmoDaemon"] = GizmoDaemonModule;
01344
01345
01346 scope(GizmoDaemonModule).attr("Gizmod") = ptr(this);
01347
01348
01349 string PathInsertion =
01350 "import sys\nsys.path.insert(0, \"" + mConfigDir + "\")\n" +
01351 "sys.path.insert(0, \"" + mConfigDir + USER_SCRIPT_DIR + "/\")\n" +
01352 getUserScriptDirPaths();
01353 cdbg1 << "Modifying PYTHONPATH:\n" << PathInsertion << endl;
01354 handle<> ignore_path_exec((PyRun_String(
01355 PathInsertion.c_str(),
01356 Py_file_input, mPyMainNamespace.ptr(), mPyMainNamespace.ptr())));
01357
01358
01359 string ScriptFile = mConfigDir + SCRIPT_DISPATCHER;
01360 cdbg1 << "Executing Dispatcher Python Script [" << ScriptFile << "]..." << endl;
01361 FILE * ifScript = fopen(ScriptFile.c_str(), "r");
01362 if (!ifScript)
01363 throw H::Exception("Failed to Open Python Script [" + ScriptFile + "] for Reading", __FILE__, __FUNCTION__, __LINE__);
01364 PyRun_SimpleFile(ifScript, ScriptFile.c_str());
01365 fclose(ifScript);
01366
01367
01368 cdbg1 << "Creating Dispatcher Object" << endl;
01369 handle<> ignore_dispatcher_exec((PyRun_String(
01370 "Dispatcher = GizmodDispatcher()\nGizmod.Dispatcher = Dispatcher\n",
01371 Py_file_input, mPyMainNamespace.ptr(), mPyMainNamespace.ptr())));
01372
01373
01374 mpPyDispatcher = extract<GizmodEventHandlerInterface*>(mPyMainNamespace["Dispatcher"]);
01375
01376
01377 mpPyDispatcher->initialize();
01378
01379
01380 ScriptFile = mConfigDir + SCRIPT_USER;
01381 cdbg1 << "Executing User Python Script [" << ScriptFile << "]..." << endl;
01382 ifScript = fopen(ScriptFile.c_str(), "r");
01383 if (!ifScript)
01384 throw H::Exception("Failed to Open Python Script [" + ScriptFile + "] for Reading", __FILE__, __FUNCTION__, __LINE__);
01385 PyRun_SimpleFile(ifScript, ScriptFile.c_str());
01386 fclose(ifScript);
01387 } catch (error_already_set) {
01388 PyErr_Print();
01389 throw H::Exception("Failed to Execute Python Script!", __FILE__, __FUNCTION__, __LINE__);
01390 }
01391 }
01392
01401 bool GizmoDaemon::initialize(int argc, char ** argv) {
01402
01403 options_description GenericOptions("Generic Options");
01404 GenericOptions.add_options()
01405 ("debug,g", "Enable debug mode")
01406 ("help,h", "Display informative help message")
01407 ("verbosity,V", value<int>(), "Set debug vebosity level (0-5) [Default = 0]")
01408 ("version,v", "Print version information")
01409 ;
01410
01411
01412 options_description ConfigurationOptions("Configuration Options");
01413 ConfigurationOptions.add_options()
01414 ("client-host,c", value<string>(), "Enable event forwarding to a remote host")
01415 ("client-port,P", value<int>(), "Port to forward events to (default: " DEFAULT_PORT_STR ")")
01416 ("config-dir,C", value<string>(), "Set config scripts directory")
01417 ("events-dir,e", value<string>(), "Set event node directory (default: " EVENT_NODE_DIR ")")
01418 ("keyboard-leds,k", "Allow Gizmod to Visualize on the Keyboard LEDs")
01419 ("lirc-dev,l", value<string>(), "Set LIRC device node (default: " LIRC_DEV ")")
01420 ("no-alsa,A", "Disable ALSA support")
01421 ("no-cpuusage,U", "Disable CPU Usage reporting")
01422 ("no-local,N", "Disable local processing of events")
01423 ("no-x11,X", "Disable X11 support")
01424 ("remote-control,r", "Enable Remote Control mode")
01425 ("server,s", "Enable server (default: not enabled)")
01426 ("server-port,p", value<int>(), "Port to start Gizmod server on (default: " DEFAULT_PORT_STR ")")
01427 ;
01428
01429
01430 options_description HiddenOptions("Hidden Options");
01431 HiddenOptions.add_options();
01432
01433
01434 options_description CommandLineOptions;
01435 CommandLineOptions.add(GenericOptions).add(ConfigurationOptions).add(HiddenOptions);
01436
01437
01438 options_description ConfigFileOptions;
01439 ConfigFileOptions.add(ConfigurationOptions).add(HiddenOptions);
01440
01441
01442 options_description VisibleOptions("");
01443 VisibleOptions.add(GenericOptions).add(ConfigurationOptions);
01444
01445
01446 variables_map VarMap;
01447
01448
01449 try {
01450 store(parse_command_line(argc, argv, CommandLineOptions), VarMap);
01451 } catch (exception & e) {
01452 cout << VisibleOptions;
01453 throw H::Exception("Invalid Command Line Argument(s)");
01454 }
01455
01456
01457 try {
01458 string ConfigFile = CONFIG_FILE_PATH;
01459 UtilFile::relativeToAbsolute(ConfigFile);
01460 ifstream ifs(ConfigFile.c_str());
01461 if (ifs.is_open())
01462 store(parse_config_file(ifs, ConfigFileOptions), VarMap);
01463 } catch (exception & e) {
01464 cout << VisibleOptions;
01465 throw H::Exception("Invalid Configuration File");
01466 }
01467
01468
01469 notify(VarMap);
01470
01471
01472 if (VarMap.count("help")) {
01473 cout << VisibleOptions << endl;
01474 mDisableShutdownMessage = true;
01475 return false;
01476 }
01477 if (VarMap.count("version")) {
01478 cout << endl;
01479 mDisableShutdownMessage = true;
01480 return false;
01481 }
01482 if (VarMap.count("debug")) {
01483 Debug::setEnabled(true);
01484 cdbg << "Debug Mode Enabled" << endl;
01485 }
01486 if (VarMap.count("verbosity")) {
01487 Debug::setVerbosity(VarMap["verbosity"].as<int>());
01488 cdbg << "Debug Verbosity set to [" << VarMap["verbosity"].as<int>() << "]" << endl;
01489 }
01490 if (VarMap.count("client-host")) {
01491 mClientHost = VarMap["client-host"].as<string>();
01492 cdbg << "Client Forwarding to [" << mClientHost << "]" << endl;
01493 }
01494 if (VarMap.count("client-port")) {
01495 mClientPort = VarMap["client-port"].as<int>();
01496 cdbg << "Client port set to [" << mClientPort << "]" << endl;
01497 }
01498 if (VarMap.count("config-dir")) {
01499 mConfigDir = VarMap["config-dir"].as<string>();
01500 if (mConfigDir[mConfigDir.length() - 1] != '/')
01501 mConfigDir += "/";
01502 cdbg << "Config Scripts Directory set to [" << mConfigDir << "]" << endl;
01503 }
01504 if (VarMap.count("events-dir")) {
01505 mEventsDir = VarMap["events-dir"].as<string>();
01506 if (mEventsDir[mEventsDir.length() - 1] != '/')
01507 mEventsDir += "/";
01508 cdbg << "Event Node Directory set to [" << mEventsDir << "]" << endl;
01509 }
01510 if (VarMap.count("keyboard-leds")) {
01511 cdbg << "Allowing takeover of Keyboard LEDs" << endl;
01512 mUseKeyboardLEDs = true;
01513 }
01514 if (VarMap.count("lirc-dev")) {
01515 mLircDev = VarMap["lirc-dev"].as<string>();
01516 cdbg << "LIRC Device Node set to [" << mLircDev << "]" << endl;
01517 }
01518 if (VarMap.count("no-alsa")) {
01519 mDisabledALSA = true;
01520 cdbg << "ALSA Support Disabled" << endl;
01521 }
01522 if (VarMap.count("no-cpuusage")) {
01523 mDisabledCPUUsage = true;
01524 cdbg << "CPU Usage Reporting Disabled" << endl;
01525 }
01526 if (VarMap.count("no-local")) {
01527 mLocalDisabled = true;
01528 cdbg << "Local Event Processing Disabled" << endl;
01529 }
01530 if (VarMap.count("no-x11")) {
01531 mDisabledX11 = true;
01532 cdbg << "X11 Support Disabled" << endl;
01533 }
01534 if (VarMap.count("remote-control")) {
01535 mUseRemoteControl = true;
01536 cdbg << "Remote Control Mode Enabled" << endl;
01537 }
01538 if (VarMap.count("server")) {
01539 mServerEnabled = !mServerEnabled;
01540 cdbg << "Gizmod Server Enabled" << endl;
01541 }
01542 if (VarMap.count("server-port")) {
01543 mServerPort = VarMap["server-port"].as<int>();
01544 cdbg << "Sever port set to [" << mServerPort << "]" << endl;
01545 }
01546
01547 cout << endl;
01548 return true;
01549 }
01550
01554 void GizmoDaemon::loadUserScripts() {
01555 cout << "Loading User Scripts:" << endl << endl;
01556
01557 path UserScriptPath(mConfigDir + USER_SCRIPT_DIR);
01558 if (!filesystem::exists(UserScriptPath))
01559 throw H::Exception("User script directory [" + mConfigDir + USER_SCRIPT_DIR + "] does NOT exist or permissions are wrong!", __FILE__, __FUNCTION__, __LINE__);
01560
01561
01562
01563 std::vector<string> UserScripts;
01564 directory_iterator endItr;
01565 for (directory_iterator iter(mConfigDir + USER_SCRIPT_DIR); iter != endItr; iter ++) {
01566 if ( (!filesystem::is_directory(*iter)) && (!filesystem::symbolic_link_exists(*iter)) ) {
01567 UserScripts.push_back(iter->leaf());
01568 }
01569 }
01570
01571
01572 sort_all(UserScripts);
01573
01574
01575 mutex::scoped_lock lock(mMutexScript);
01576 apply_func(UserScripts, &GizmoDaemon::loadUserScriptsFunctor, this);
01577 cout << endl;
01578 }
01579
01584 void GizmoDaemon::loadUserScriptsFunctor(std::string UserScript) {
01585
01586
01587
01588 size_t dotPos = UserScript.rfind(".py");
01589 if ( (dotPos == string::npos) || (dotPos != UserScript.length() - 3) )
01590 return;
01591 UserScript = UserScript.substr(0, dotPos);
01592 cdbg1 << "Importing User Script [" << UserScript << "]" << endl;
01593
01594
01595 try {
01596 string ImportModuleString = "__import__(\"" + UserScript + "\")\n";
01597 cdbg2 << "Executing Python Code: " << ImportModuleString << endl;
01598 handle<> ignore_path_exec((PyRun_String(
01599 ImportModuleString.c_str(),
01600 Py_file_input, mPyMainNamespace.ptr(), mPyMainNamespace.ptr())));
01601 } catch (error_already_set) {
01602 PyErr_Print();
01603 throw H::Exception("Failed to Load User Script [" + UserScript + "]", __FILE__, __FUNCTION__, __LINE__);
01604 }
01605 }
01606
01614 void GizmoDaemon::printNiceScriptInit(int Width, std::string Text1, std::string Text2, std::string Text3) {
01615 replace_all(Text1, "\n", "");
01616 replace_all(Text2, "\n", "");
01617 replace_all(Text3, "\n", "");
01618 trim(Text1);
01619 trim(Text2);
01620 trim(Text3);
01621 switch (Width) {
01622 case 0:
01623 Width = 12;
01624 break;
01625 case 1:
01626 Width = 22;
01627 break;
01628 }
01629 int StartPos = Width - Text1.length();
01630 for (int lp = 0; lp < StartPos; lp ++)
01631 cout << " ";
01632 cout << Text1;
01633 if (Text2 != "")
01634 cout << " - " << Text2;
01635 if (Text3 != "")
01636 cout << " [" << Text3 << "]";
01637 cout << endl;
01638 }
01639
01649 void GizmoDaemon::printNiceScriptRegister(int Width, std::string Text1, std::string Text2, std::string Text3, std::string Text4, std::string Text5) {
01650 replace_all(Text1, "\n", "");
01651 replace_all(Text2, "\n", "");
01652 replace_all(Text3, "\n", "");
01653 replace_all(Text4, "\n", "");
01654 replace_all(Text5, "\n", "");
01655 trim(Text1);
01656 trim(Text2);
01657 trim(Text3);
01658 trim(Text4);
01659 trim(Text5);
01660 switch (Width) {
01661 case 0:
01662 Width = 12;
01663 break;
01664 case 1:
01665 Width = 22;
01666 break;
01667 }
01668 int StartPos = Width - Text1.length();
01669 for (int lp = 0; lp < StartPos; lp ++)
01670 cout << " ";
01671 cout << Text1;
01672 if (Text2 != "")
01673 cout << " - " << Text2;
01674 if (Text3 != "") {
01675 size_t lastSPos = Text3.rfind("/");
01676 if (lastSPos != string::npos)
01677 Text3 = Text3.substr(lastSPos + 1);
01678 cout << " [" << Text3 << "]";
01679 }
01680 if ( (Text4 != "") && (Text4 != "-0x1") && (Text4 != "0xffff") )
01681 cout << " vId: " << Text4;
01682 if ( (Text4 != "") && (Text5 != "-0x1") && (Text5 != "0xffff") )
01683 cout << " pId: " << Text5;
01684 cout << endl;
01685 }
01686
01693 void GizmoDaemon::onAlsaEventMixerElementAttach(AlsaEvent const & Event, AlsaSoundCard const & SoundCard, AlsaMixer const & Mixer) {
01694 if (mShuttingDown)
01695 return;
01696
01697 cdbg1 << "Mixer Element Attached [" << Mixer.getName() << "] on Sound Card [" << SoundCard.getCardName() << "]" << endl;
01698 try {
01699 mutex::scoped_lock lock(mMutexScript);
01700 GizmoEventSoundCard EventSoundCard(Event, SoundCard, Mixer);
01701
01702 if (!mLocalDisabled)
01703 mpPyDispatcher->onEvent(&EventSoundCard);
01704 } catch (error_already_set) {
01705 PyErr_Print();
01706 cerr << "Failed to call GizmodDispatcher.onEvent for onAlsaEventMixerElementAttach" << endl;
01707 }
01708 }
01709
01716 void GizmoDaemon::onAlsaEventMixerElementChange(AlsaEvent const & Event, AlsaSoundCard const & SoundCard, AlsaMixer const & Mixer) {
01717 if (mShuttingDown)
01718 return;
01719
01720 if (Event.Type == ALSAEVENT_MIXERELEMENT_CHANGE)
01721 cdbg2 << "Mixer Element Changed [" << Mixer.getName() << "] with Mask [" << Event.IsActiveChanged << Event.ElementsChanged << Event.VolumePlaybackChanged << "] on Sound Card [" << SoundCard.getCardName() << "] " << Mixer.VolumePlaybackPercent << endl;
01722 else
01723 cdbg2 << "Mixer Element Changed [" << Mixer.getName() << "] with Mask [" << Event.Mask << "] on Sound Card [" << SoundCard.getCardName() << "]" << endl;
01724
01725 try {
01726 mutex::scoped_lock lock(mMutexScript);
01727 GizmoEventSoundCard EventSoundCard(Event, SoundCard, Mixer);
01728
01729 if (!mLocalDisabled)
01730 mpPyDispatcher->onEvent(&EventSoundCard);
01731 } catch (error_already_set) {
01732 PyErr_Print();
01733 cerr << "Failed to call GizmodDispatcher.onEvent for onAlsaEventMixerElementChange" << endl;
01734 }
01735 }
01736
01743 void GizmoDaemon::onAlsaEventMixerElementDetach(AlsaEvent const & Event, AlsaSoundCard const & SoundCard, AlsaMixer const & Mixer) {
01744 if (mShuttingDown)
01745 return;
01746
01747 cdbg3 << "Mixer Element Detached [" << Mixer.getName() << "] on Sound Card [" << SoundCard.getCardName() << "]" << endl;
01748 try {
01749 mutex::scoped_lock lock(mMutexScript);
01750 GizmoEventSoundCard EventSoundCard(Event, SoundCard, Mixer);
01751
01752 if (!mLocalDisabled)
01753 mpPyDispatcher->onEvent(&EventSoundCard);
01754 } catch (error_already_set) {
01755 PyErr_Print();
01756 cerr << "Failed to call GizmodDispatcher.onEvent for onAlsaEventMixerElementDetach" << endl;
01757 }
01758 }
01759
01765 void GizmoDaemon::onAlsaEventSoundCardAttach(AlsaEvent const & Event, AlsaSoundCard const & SoundCard) {
01766 if (mShuttingDown)
01767 return;
01768
01769 cdbg << "Attached to Sound Card [" << SoundCard.getCardHardwareID() << "] -- " << SoundCard.getCardName() << endl;
01770 try {
01771 mutex::scoped_lock lock(mMutexScript);
01772 GizmoEventSoundCard EventSoundCard(Event, SoundCard);
01773
01774 if (!mLocalDisabled)
01775 mpPyDispatcher->onEvent(&EventSoundCard);
01776 } catch (error_already_set) {
01777 PyErr_Print();
01778 cerr << "Failed to call GizmodDispatcher.onEvent for onAlsaEventSoundCardAttach" << endl;
01779 }
01780 }
01781
01787 void GizmoDaemon::onAlsaEventSoundCardDetach(AlsaEvent const & Event, AlsaSoundCard const & SoundCard) {
01788 if (mShuttingDown)
01789 return;
01790
01791 cdbg1 << "Sound Card Detached [" << SoundCard.getCardHardwareID() << "] -- " << SoundCard.getCardName() << endl;
01792 try {
01793 mutex::scoped_lock lock(mMutexScript);
01794 GizmoEventSoundCard EventSoundCard(Event, SoundCard);
01795
01796 if (!mLocalDisabled)
01797 mpPyDispatcher->onEvent(&EventSoundCard);
01798 } catch (error_already_set) {
01799 PyErr_Print();
01800 cerr << "Failed to call GizmodDispatcher.onEvent for onAlsaEventSoundCardDetach" << endl;
01801 }
01802 }
01803
01808 void GizmoDaemon::onCPUUsage(std::vector< boost::shared_ptr<CPUUsageInfo> > const & Event) {
01809 if (mShuttingDown)
01810 return;
01811
01812 try {
01813 mutex::scoped_lock lock(mMutexScript);
01814 GizmoEventCPUUsage const EventCPUUsage(Event);
01815
01816
01817 if (!mLocalDisabled)
01818 mpPyDispatcher->onEvent(&EventCPUUsage);
01819
01820
01821 try {
01822 sendEventCPUUsage(Event);
01823 } catch (SocketException const & e) {
01824 cdbg << "Failed to send CPUUsage Message to Server -- " << e.getExceptionMessage() << endl;
01825 }
01826 } catch (error_already_set) {
01827 PyErr_Print();
01828 cerr << "Failed to call GizmodDispatcher.onEvent for onCPUUsage" << endl;
01829 }
01830 }
01831
01838 void GizmoDaemon::onFileEventCreate(boost::shared_ptr<H::FileWatchee> pWatchee, std::string FullPath, std::string FileName) {
01839 if (FileName.find("event") != 0) {
01840 cout << "onFileEventCreate [" << FullPath << "]" << endl;
01841 return;
01842 }
01843 addFileToWatch(FullPath, WATCH_INOUT);
01844 }
01845
01852 void GizmoDaemon::onFileEventDelete(boost::shared_ptr<H::FileWatchee> pWatchee, std::string FullPath, std::string FileName) {
01853 cdbg5 << "onFileEventDelete [" << FullPath << "] -- " << pWatchee->FileName << endl;
01854 deleteGizmo(pWatchee->FileName);
01855 }
01856
01861 void GizmoDaemon::onFileEventDisconnect(boost::shared_ptr<H::FileWatchee> pWatchee) {
01862 cdbg5 << "onFileEventDisconnect [" << pWatchee->FileName << "]: " << pWatchee->DeviceName << endl;
01863 deleteGizmo(pWatchee->FileName);
01864 }
01865
01871 void GizmoDaemon::onFileEventRead(boost::shared_ptr<H::FileWatchee> pWatchee, DynamicBuffer<char> const & ReadBuffer) {
01872 if (mShuttingDown)
01873 return;
01874
01875
01876 shared_ptr<Gizmo> pUnknownGizmo = mGizmos[pWatchee->FileName];
01877 if (!pUnknownGizmo) {
01878 cdbg << "Unknown Event Detected on Device [" << pWatchee->DeviceName << "] of Length [" << (int) ReadBuffer.length() << "]" << endl;
01879 return;
01880 }
01881
01882
01883 try {
01884 switch (pUnknownGizmo->getClass()) {
01885 case GIZMO_CLASS_ATIX10:
01886 handleFileEventReadATIX10(static_cast<GizmoATIX10 &>(*pUnknownGizmo), ReadBuffer);
01887 break;
01888 case GIZMO_CLASS_LIRC:
01889 handleFileEventReadLIRC(static_cast<GizmoLIRC &>(*pUnknownGizmo), ReadBuffer);
01890 break;
01891 case GIZMO_CLASS_POWERMATE:
01892 handleFileEventReadPowermate(static_cast<GizmoPowermate &>(*pUnknownGizmo), ReadBuffer);
01893 break;
01894 case GIZMO_CLASS_STANDARD:
01895 handleFileEventReadStandard(static_cast<GizmoStandard &>(*pUnknownGizmo), ReadBuffer);
01896 break;
01897 }
01898 } catch (error_already_set) {
01899 PyErr_Print();
01900 cerr << "Failed to call GizmodDispatcher.onEvent for onFileEventRead" << endl;
01901 }
01902 }
01903
01908 void GizmoDaemon::onFileEventRegister(boost::shared_ptr<H::FileWatchee> pWatchee) {
01909 if (mShuttingDown)
01910 return;
01911
01912 cdbg1 << "New Device Detected [" << pWatchee->FileName << "]: " << pWatchee->DeviceName << endl;
01913 try {
01914 mutex::scoped_lock lock(mMutexScript);
01915 GizmoClass Class = mpPyDispatcher->onQueryDeviceClass(*pWatchee);
01916 switch (Class) {
01917 case GIZMO_CLASS_ATIX10: {
01918 shared_ptr<GizmoATIX10> pGizmo(new GizmoATIX10(*pWatchee, mGizmos.size(), getGizmoClassID(GIZMO_CLASS_ATIX10)));
01919 mGizmos.insert(make_pair(pWatchee->FileName, pGizmo));
01920 mpPyDispatcher->onRegisterDevice(pGizmo.get());
01921 break; }
01922 case GIZMO_CLASS_LIRC: {
01923 shared_ptr<GizmoLIRC> pGizmo(new GizmoLIRC(*pWatchee, mGizmos.size(), getGizmoClassID(GIZMO_CLASS_LIRC)));
01924 mGizmos.insert(make_pair(pWatchee->FileName, pGizmo));
01925 mpPyDispatcher->onRegisterDevice(pGizmo.get());
01926 break; }
01927 case GIZMO_CLASS_POWERMATE: {
01928 shared_ptr<GizmoPowermate> pGizmo(new GizmoPowermate(*pWatchee, mGizmos.size(), getGizmoClassID(GIZMO_CLASS_POWERMATE)));
01929 mGizmos.insert(make_pair(pWatchee->FileName, pGizmo));
01930 mpPyDispatcher->onRegisterDevice(pGizmo.get());
01931 break; }
01932 case GIZMO_CLASS_STANDARD: {
01933 shared_ptr<GizmoStandard> pGizmo(new GizmoStandard(*pWatchee, mGizmos.size(), getGizmoClassID(GIZMO_CLASS_STANDARD)));
01934 mGizmos.insert(make_pair(pWatchee->FileName, pGizmo));
01935 mpPyDispatcher->onRegisterDevice(pGizmo.get());
01936 break; }
01937 }
01938 } catch (error_already_set) {
01939 PyErr_Print();
01940 throw H::Exception("Failed to call GizmodDispatcher.onRegisterDevice for onFileEventRegister", __FILE__, __FUNCTION__, __LINE__);
01941 }
01942 }
01943
01947 void GizmoDaemon::onFileEventWatchBegin() {
01948 }
01949
01953 void GizmoDaemon::onFileEventWatchEnd() {
01954 }
01955
01960 void GizmoDaemon::onFocusIn(X11FocusEvent const & Event) {
01961 if (mShuttingDown)
01962 return;
01963
01964
01965 try {
01966 mutex::scoped_lock lock(mMutexScript);
01967 mCurrentFocus = Event;
01968 GizmoEventWindowFocus FocusEvent(Event);
01969 if (!mLocalDisabled)
01970 mpPyDispatcher->onEvent(&FocusEvent);
01971 } catch (error_already_set) {
01972 PyErr_Print();
01973 cerr << "Failed to call GizmodDispatcher.onEvent for onFocusIn" << endl;
01974 }
01975 }
01976
01981 void GizmoDaemon::onFocusOut(X11FocusEvent const & Event) {
01982 if (mShuttingDown)
01983 return;
01984
01985
01986 try {
01987 mutex::scoped_lock lock(mMutexScript);
01988 GizmoEventWindowFocus FocusEvent(Event);
01989 if (!mLocalDisabled)
01990 mpPyDispatcher->onEvent(&FocusEvent);
01991 } catch (error_already_set) {
01992 PyErr_Print();
01993 cerr << "Failed to call GizmodDispatcher.onEvent for onFocusOut" << endl;
01994 }
01995 }
01996
02000 void GizmoDaemon::onSignalSegv() {
02001 cerr << "Segmentation Fault Detected" << endl;
02002 signalShutdown();
02003 }
02004
02008 void GizmoDaemon::onSignalInt() {
02009 cdbg << "Keyboard Interrupt Received..." << endl;
02010 signalShutdown();
02011 }
02012
02016 void GizmoDaemon::onSignalHup() {
02017 cout << "HUP signal received, reloading config..." << endl;
02018 mReloadConfig = true;
02019 signalShutdown();
02020 }
02021
02025 void GizmoDaemon::onSignalQuit() {
02026 cdbg << "Request to Quit Received..." << endl;
02027 signalShutdown();
02028 }
02029
02033 void GizmoDaemon::onSignalKill() {
02034 cdbg << "Kill signal Received..." << endl;
02035 signalShutdown();
02036 }
02037
02041 void GizmoDaemon::onSignalTerm() {
02042 cdbg << "Request to Terminate Received..." << endl;
02043 signalShutdown();
02044 }
02045
02049 void GizmoDaemon::onSignalStop() {
02050 cdbg << "Request to Stop Received..." << endl;
02051 signalShutdown();
02052 }
02053
02057 void GizmoDaemon::onSignalUnknown(int Signal) {
02058 cerr << "Unhandled Unknown Signal" << endl;
02059 }
02060
02065 void GizmoDaemon::onSocketClientConnect(Socket const & socket) {
02066 cdbg << "Successfully Connected to [" << mClientHost << "] at Port [" << mClientPort << "]" << endl;
02067 }
02068
02073 void GizmoDaemon::onSocketClientDisconnect(Socket const & socket) {
02074 cdbg << "Disconnected from Server" << endl;
02075 }
02076
02082 void GizmoDaemon::onSocketClientMessage(Socket const & socket, std::string const & Message) {
02083 cdbg << "Client Socket Message [" << Message.length() << "] Bytes -- " << Message << endl;
02084 }
02085
02091 void GizmoDaemon::onSocketClientRead(Socket const & socket, DynamicBuffer<char> & ReadBuffer) {
02092 cdbg << "Client Socket Read [" << ReadBuffer.length() << "] Bytes" << endl;
02093 }
02094
02099 void GizmoDaemon::onSocketServerConnect(boost::shared_ptr<Socket> pSocket) {
02100 cdbg << "Client Connection from [" << pSocket->getAddress() << "]" << endl;
02101 }
02102
02107 void GizmoDaemon::onSocketServerDisconnect(Socket const & socket) {
02108 cdbg << "Client Disconnected [" << socket.getAddress() << "]" << endl;
02109 }
02110
02116 void GizmoDaemon::onSocketServerMessage(Socket const & socket, std::string const & Message) {
02117 if (mShuttingDown)
02118 return;
02119
02120
02121 size_t dPos = Message.find("|");
02122 if (dPos == string::npos) {
02123 cdbg << "Invalid Message Received from Client [" << socket.getAddress() << "]" << endl;
02124 return;
02125 }
02126
02127 int MessageType;
02128 try {
02129 MessageType = lexical_cast<int>(Message.substr(0, dPos));
02130 } catch (bad_lexical_cast const & e) {
02131 cdbg << "Invalid Message Type Received from Client [" << socket.getAddress() << "]" << endl;
02132 return;
02133 }
02134
02135
02136 if ( (MessageType < 0) || (MessageType > GIZMO_EVENTCLASS_MAX) ) {
02137 cdbg << "Improper Message Type Received from Client [" << socket.getAddress() << "]" << endl;
02138 return;
02139 }
02140
02141
02142 deserializeMessage(static_cast<GizmoEventClass>(MessageType), Message.substr(dPos + 1));
02143 }
02144
02150 void GizmoDaemon::onSocketServerRead(Socket const & socket, DynamicBuffer<char> & ReadBuffer) {
02151
02152 }
02153
02160 void GizmoDaemon::registerDevices() {
02161 cout << "Registering Devices:" << endl << endl;
02162
02163
02164 registerInputEventDevices();
02165
02166
02167 registerLircDevice();
02168
02169
02170 cout << endl;
02171 }
02172
02176 void GizmoDaemon::registerInputEventDevices() {
02177 cdbg1 << "Registering Input Event Devices in [" << mEventsDir << "]" << endl;
02178 path EventsDirPath(mEventsDir);
02179 if (!filesystem::exists(EventsDirPath))
02180 throw H::Exception("Input Event dir [" + mEventsDir + "] does NOT exist or permissions are wrong!", __FILE__, __FUNCTION__, __LINE__);
02181
02182
02183 addFileToWatch(mEventsDir, WATCH_INOUT);
02184
02185
02186
02187 std::vector<string> eventsFiles;
02188 directory_iterator endItr;
02189 for (directory_iterator iter(mEventsDir); iter != endItr; iter ++) {
02190 if ( (!filesystem::is_directory(*iter)) && (!filesystem::symbolic_link_exists(*iter)) ) {
02191 if (iter->leaf().find("event") != 0)
02192 continue;
02193 eventsFiles.push_back(mEventsDir + "/" + iter->leaf());
02194 }
02195 }
02196
02197
02198 sort_all(eventsFiles);
02199 apply_func_args(eventsFiles, &FileEventWatcher::addFileToWatch, this, WATCH_INOUT, "Unknown");
02200 }
02201
02205 void GizmoDaemon::registerLircDevice() {
02206 cdbg1 << "Registering LIRC device node [" << mLircDev << "]" << endl;
02207 path LircDevPath(mLircDev);
02208 if (!filesystem::exists(LircDevPath)) {
02209 cdbg << "LIRC device node [" + mLircDev + "] does not exist -- disabling LIRC support" << endl;
02210 return;
02211 }
02212
02213 boost::shared_ptr<FileWatchee> pWatchee = addUnixSocketToWatch(mLircDev, "LIRC");
02214 if (!pWatchee) {
02215 cdbg << "Could not connect to LIRC device node [" + mLircDev + "] -- disabling LIRC support" << endl;
02216 cdbg << " - Check permissions" << endl;
02217 cdbg << " - Ensure lircd is running" << endl;
02218 return;
02219 }
02220 }
02221
02225 void GizmoDaemon::setConfigDir() {
02226
02227 string HomeScriptDir = HOME_SCRIPT_DIR;
02228 char * EnvHome = getenv("HOME");
02229 if (EnvHome)
02230 replace_all(HomeScriptDir, "~", EnvHome);
02231
02232
02233 bool PathsOkay;
02234 try {
02235 path HomeScriptPath(HomeScriptDir);
02236 PathsOkay = true;
02237 } catch (filesystem_error const & e) {
02238 PathsOkay = false;
02239 }
02240
02241
02242 if ( PathsOkay && filesystem::exists(HomeScriptDir) && filesystem::exists(HomeScriptDir + USER_SCRIPT_DIR) ) {
02243 mConfigDir = HomeScriptDir;
02244 } else {
02245 mConfigDir = SCRIPT_DIR;
02246 replace_all(mConfigDir, "${prefix}", PREFIX);
02247 }
02248 }
02249
02253 void GizmoDaemon::setVersionInfo() {
02254 string Version = VERSION;
02255 size_t cPos = Version.find(":");
02256 if (cPos == string::npos)
02257 cPos = Version.find(".");
02258 if (cPos == string::npos) {
02259 mVersionMajor = 0;
02260 mVersionMinor = 0;
02261 } else {
02262 try {
02263 mVersionMajor = lexical_cast<int>(Version.substr(0, cPos));
02264 mVersionMinor = lexical_cast<int>(Version.substr(cPos + 1));
02265 } catch (bad_lexical_cast const & e) {
02266 mVersionMajor = 0;
02267 mVersionMinor = 0;
02268 return;
02269 }
02270 }
02271
02272 mVersion = double(mVersionMajor) + (double(mVersionMinor) / 10.0);
02273 }
02274
02278 void GizmoDaemon::signalShutdown() {
02279 mShuttingDown = true;
02280 FileEventWatcher::shutdown();
02281 }