Skip to content

Commit

Permalink
WIP: Add monitor function to Illumination tool
Browse files Browse the repository at this point in the history
  • Loading branch information
hadess committed Sep 16, 2024
1 parent 4652167 commit 2ad1d20
Showing 1 changed file with 150 additions and 1 deletion.
151 changes: 150 additions & 1 deletion src/tools/hidpp20-illumination-light-control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,148 @@
#include <hidpp20/Device.h>
#include <hidpp20/Error.h>
#include <hidpp20/IIllumination.h>
#include <hidpp20/UnsupportedFeature.h>
#include <cstdio>
#include <iostream>
#include <memory>

#include "common/common.h"
#include "common/Option.h"
#include "common/CommonOptions.h"
#include "common/EventQueue.h"

extern "C" {
#include <unistd.h>
#include <signal.h>
#include <string.h>
}

using namespace HIDPP20;

class EventHandler
{
public:
virtual const HIDPP20::FeatureInterface *feature () const = 0;
virtual void handleEvent (const HIDPP::Report &event) = 0;
};

class IlluminationEventHandler: public EventHandler
{
HIDPP20::IIllumination _ill;
bool _state;
uint16_t _brightness;
uint16_t _color;
uint16_t _min, _max, _res;
public:
IlluminationEventHandler (HIDPP20::Device *dev):
_ill (dev),
_state (_ill.getIllumination ()),
_brightness (_ill.getBrightness())
{
printf ("Light is %s\n", _state ? "on" : "off");
}

const HIDPP20::FeatureInterface *feature () const
{
return &_ill;
}

void handleEvent (const HIDPP::Report &event)
{
switch (event.function ()) {
case IIllumination::IlluminationChangeEvent:
bool new_state = IIllumination::illuminationChangeEvent (event);
if (new_state != _state) {
printf ("Light turned %s\n", new_state ? "on" : "off");
_state = new_state;
}
break;
}
}
};

class EventListener
{
HIDPP::Dispatcher *dispatcher;
HIDPP::DeviceIndex index;
std::map<uint8_t, std::unique_ptr<EventHandler>> handlers;
std::map<uint8_t, HIDPP::Dispatcher::listener_iterator> iterators;
public:
EventListener (HIDPP::Dispatcher *dispatcher, HIDPP::DeviceIndex index):
dispatcher (dispatcher),
index (index)
{
}

virtual ~EventListener ()
{
removeEventHandlers ();
}

virtual void addEventHandler (std::unique_ptr<EventHandler> &&handler)
{
uint8_t feature = handler->feature ()->index ();
EventHandler *ptr = handler.get ();
handlers.emplace (feature, std::move (handler));
auto it = dispatcher->registerEventHandler (index, feature, [ptr] (const HIDPP::Report &report) {
ptr->handleEvent (report);
return true;
});
iterators.emplace (feature, it);
}

virtual void removeEventHandlers ()
{
for (const auto &p: iterators)
dispatcher->unregisterEventHandler (p.second);
handlers.clear ();
iterators.clear ();
}

virtual void start () = 0;
virtual void stop () = 0;

protected:
virtual bool event (EventHandler *handler, const HIDPP::Report &report) = 0;
};

class SimpleListener: public EventListener
{
HIDPP::SimpleDispatcher *dispatcher;
public:
SimpleListener (HIDPP::SimpleDispatcher *dispatcher, HIDPP::DeviceIndex index):
EventListener (dispatcher, index),
dispatcher (dispatcher)
{
}

virtual void start ()
{
dispatcher->listen ();
}

virtual void stop ()
{
dispatcher->stop ();
}

protected:
virtual bool event (EventHandler *handler, const HIDPP::Report &report)
{
handler->handleEvent (report);
return true;
}
};

EventListener *listener;

void sigint (int)
{
listener->stop ();
}



int main (int argc, char *argv[])
{
static const char *args = "device_path state|toggle|brightness|temp [params...]";
Expand Down Expand Up @@ -64,7 +196,7 @@ int main (int argc, char *argv[])
std::cerr << "Failed to open device: " << e.what () << "." << std::endl;
return EXIT_FAILURE;
}
Device dev (dispatcher.get (), device_index);
HIDPP20::Device dev (dispatcher.get (), device_index);
try {
IIllumination ill (&dev);
if (op == "state") {
Expand Down Expand Up @@ -122,6 +254,23 @@ int main (int argc, char *argv[])
ill.setColorTemperature(new_value);
}
}
else if (op == "monitor") {
struct sigaction sa, oldsa;
memset (&sa, 0, sizeof (struct sigaction));
sa.sa_handler = sigint;
sigaction (SIGINT, &sa, &oldsa);
try {
listener->addEventHandler (std::make_unique<IlluminationEventHandler> (dev.get ()));
}
catch (HIDPP20::UnsupportedFeature &e) {
printf ("%s\n", e.what ());
}

listener->start();
listener->removeEventHandlers ();
sigaction (SIGINT, &oldsa, nullptr);
delete listener;
}
else {
std::cerr << "Invalid operation: " << op << "." << std::endl;
return EXIT_FAILURE;
Expand Down

0 comments on commit 2ad1d20

Please sign in to comment.