ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/truck/SteeringWheelRemote/SteeringWheelRemote.cpp
Revision: 6
Committed: 2007-05-06T21:04:16-07:00 (15 years, 8 months ago) by douglas
File size: 3492 byte(s)
Log Message:
Worky with Audacious (BMP's true successor?)!

File Contents

# User Rev Content
1 douglas 1 // Steering Wheel Remote
2     //
3     // Douglas Thrift
4     //
5     // $Id$
6    
7     #include <iostream>
8     #include <string>
9    
10 douglas 2 #include <err.h>
11 douglas 1 #include <fcntl.h>
12 douglas 4 #include <sys/ioctl.h>
13 douglas 1
14 douglas 3 #include <common.hpp>
15 douglas 4 #include <fdstream.hpp>
16 douglas 2 #include <foreach.hpp>
17     #include <posix.hpp>
18 douglas 3 #include <regex.hpp>
19 douglas 2
20 douglas 6 #include "Audacious.hpp"
21    
22     // XXX: this is probably little endian!
23     enum Button
24 douglas 5 {
25 douglas 6 None = 0xfb00,
26     PlayPause = 0x0101,
27     Previous = 0x1010,
28     Next = 0x0808,
29     VolumeDown = 0x0c04,
30     VolumeUp = 0x0202
31     }
32     const buttons[] = { PlayPause, Previous, Next, VolumeDown, VolumeUp };
33    
34     inline std::ostream &operator<<(std::ostream &output, Button button)
35     {
36     switch (button)
37 douglas 5 {
38 douglas 6 case None:
39     return output << _B("None");
40     case PlayPause:
41     return output << _B("PlayPause");
42     case Previous:
43     return output << _B("Previous");
44     case Next:
45     return output << _B("Next");
46     case VolumeDown:
47     return output << _B("VolumeDown");
48     case VolumeUp:
49     return output << _B("VolumeUp");
50     default:
51     return output << _B("Unknown");
52     }
53     }
54 douglas 5
55 douglas 6 class Buttons
56     {
57     uint16_t current, previous;
58     mutable std::vector<Button> events;
59 douglas 5
60 douglas 6 inline bool Pressed(Button button, uint16_t buttons) const
61 douglas 5 {
62 douglas 6 return ((buttons ^ None) & button) == button;
63 douglas 5 }
64    
65 douglas 6 public:
66     Buttons() : current(None) {}
67    
68     const std::vector<Button> &Events() const
69 douglas 5 {
70 douglas 6 if (events.empty())
71     _forall (uint8_t, index, 0, sizeof (buttons) / sizeof (*buttons))
72     if (!Pressed(buttons[index], current) && Pressed(buttons[index], previous))
73     events.push_back(buttons[index]);
74    
75     return events;
76 douglas 5 }
77    
78     friend std::istream &operator>>(std::istream &, Buttons &);
79     };
80    
81     inline std::istream &operator>>(std::istream &input, Buttons &buttons)
82     {
83     if (!input.ignore(3))
84     return input;
85    
86 douglas 6 buttons.previous = buttons.current;
87    
88     buttons.events.clear();
89    
90     if (!input.read(reinterpret_cast<char *>(&buttons.current), sizeof (buttons.current)))
91 douglas 5 return input;
92    
93     return input.ignore(3);
94     }
95    
96 douglas 3 int Usage(const std::string &program)
97 douglas 1 {
98 douglas 3 std::cout << _B("Usage: ") << program << _B(" [-debug] [-device=device]") << std::endl;
99    
100     return 1;
101 douglas 2 }
102    
103 douglas 3 int main(int argc, char *argv[])
104 douglas 2 {
105 douglas 3 bool debug(false);
106     std::string device;
107 douglas 2
108 douglas 1 {
109 douglas 3 Pcre::RegEx devicePath(_B("^-device=(/.+)$"));
110     Pcre::RegEx deviceNumber(_B("^-device=([0-9]+)$"));
111     Pcre::RegEx deviceName(_B("^-device=(.+)$"));
112 douglas 1
113 douglas 3 _forall (int, index, 1, argc)
114     if (argv[index] == _B("-debug"))
115     debug = true;
116     else if (Pcre::RegEx::Match match = devicePath(argv[index]))
117     device = match[1];
118     else if (Pcre::RegEx::Match match = deviceNumber(argv[index]))
119     device = _B("/dev/uhid") + match[1];
120     else if (Pcre::RegEx::Match match = deviceName(argv[index]))
121     device = _B("/dev/") + match[1];
122     else
123     return Usage(argv[0]);
124 douglas 1 }
125    
126 douglas 3 if (device.empty())
127     return Usage(argv[0]);
128 douglas 2
129 douglas 4 ext::ifdstream uhid(Posix::CheckError(::open(device.c_str(), O_RDONLY)));
130 douglas 5 Buttons buttons;
131 douglas 6 Audacious audacious;
132 douglas 4
133 douglas 6 if (!debug)
134     Posix::CheckError(::daemon(0, 1));
135    
136 douglas 5 while (uhid >> buttons)
137 douglas 6 _foreach (const std::vector<Button>, button, buttons.Events())
138 douglas 5 {
139 douglas 6 if (debug)
140     std::cout << _B("button=") << *button << std::endl;
141 douglas 4
142 douglas 6 if (audacious.IsRunning())
143     switch (*button)
144     {
145     default:
146     break;
147 douglas 5
148 douglas 6 case PlayPause:
149     audacious.PlayPause();
150 douglas 5
151 douglas 6 break;
152 douglas 5
153 douglas 6 case Previous:
154     audacious.PlaylistPrevious();
155 douglas 5
156 douglas 6 break;
157    
158     case Next:
159     audacious.PlaylistNext();
160    
161     break;
162    
163     case VolumeDown:
164     case VolumeUp:
165     int volume(audacious.GetMainVolume() + (*button == VolumeUp ? 1 : -1));
166    
167     audacious.SetMainVolume(volume);
168     }
169 douglas 5 }
170    
171 douglas 1 return 0;
172     }

Properties

Name Value
svn:keywords Id