4 Created: 03/26/07 20:07:56
8 #include <linux/input.h>
16 #include <pbd/xml++.h>
17 #include <pbd/error.h>
20 #include "powermate.h"
22 using namespace ARDOUR;
27 #define NUM_VALID_PREFIXES 2
29 static const char *valid_prefix[NUM_VALID_PREFIXES] = {
34 #define NUM_EVENT_DEVICES 16
36 int open_powermate(const char *dev, int mode)
38 if (!Glib::file_test (dev, Glib::FILE_TEST_EXISTS)) {
41 int fd = open(dev, mode);
46 if (errno != EACCES) {
47 error << string_compose ("Unable to open \"%1\": %2", dev, strerror(errno)) << endmsg;
52 if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0){
53 error << string_compose ("\"%1\": EVIOCGNAME failed: %2", dev, strerror(errno)) << endmsg;
58 // it's the correct device if the prefix matches what we expect it to be:
59 for(i=0; i<NUM_VALID_PREFIXES; i++)
60 if(!strncasecmp(name, valid_prefix[i], strlen(valid_prefix[i])))
67 int find_powermate(int mode)
72 for(i=0; i<NUM_EVENT_DEVICES; i++){
73 sprintf(devname, "/dev/input/event%d", i);
74 r = open_powermate(devname, mode);
82 PowermateControlProtocol::PowermateControlProtocol (Session& s)
83 : ControlProtocol (s, "powermate")
87 PowermateControlProtocol::~PowermateControlProtocol ()
93 PowermateControlProtocol::probe ()
95 int port = find_powermate( O_RDONLY );
98 printf ("powermate: Opening of powermate failed - %s\n", strerror(errno));
108 PowermateControlProtocol::set_active (bool inActivate)
110 if (inActivate != _active) {
114 mPort = find_powermate(O_RDONLY);
120 if (pthread_create (&mThread, 0, SerialThreadEntry, this) == 0) {
126 printf("Powermate Control Protocol activated\n");
129 pthread_cancel (mThread);
132 printf("Powermate Control Protocol deactivated\n");
140 PowermateControlProtocol::get_state ()
142 XMLNode* node = new XMLNode (X_("Protocol"));
143 node->add_property (X_("name"), _name);
148 PowermateControlProtocol::set_state (const XMLNode& node)
155 PowermateControlProtocol::SerialThreadEntry (void* arg)
157 return static_cast<PowermateControlProtocol*>(arg)->SerialThread ();
160 #define BUFFER_SIZE 32
163 bool skippingMarkers = false;
166 PowermateControlProtocol::ProcessEvent(struct input_event *ev)
169 fprintf(stderr, "type=0x%04x, code=0x%04x, value=%d\n",
170 ev->type, ev->code, (int)ev->value);
175 printf("The LED pulse settings were changed; code=0x%04x, value=0x%08x\n", ev->code, ev->value);
178 if(ev->code != REL_DIAL)
179 fprintf(stderr, "Warning: unexpected rotation event; ev->code = 0x%04x\n", ev->code);
182 //click and hold to skip forward and back by markers
183 skippingMarkers = true;;
189 //scale the range so that we can go from +/-8x within 180 degrees, with less precision at the higher speeds
190 float speed = get_transport_speed();
191 speed += (float)ev->value * 0.05;
192 if (speed > 1.5 || speed < -1.5 )
194 set_transport_speed( speed );
199 if(ev->code != BTN_0)
200 fprintf(stderr, "Warning: unexpected key event; ev->code = 0x%04x\n", ev->code);
206 if (skippingMarkers) {
207 skippingMarkers = false;
209 if (get_transport_speed() == 0.0) {
210 set_transport_speed(1.0);
212 set_transport_speed(0.0);
223 PowermateControlProtocol::SerialThread ()
225 struct input_event ibuffer[BUFFER_SIZE];
229 r = read(mPort, ibuffer, sizeof(struct input_event) * BUFFER_SIZE);
231 events = r / sizeof(struct input_event);
232 for(i=0; i<events; i++)
233 ProcessEvent(&ibuffer[i]);
235 fprintf(stderr, "read() failed: %s\n", strerror(errno));