ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/truck/SteeringWheelRemote/SteeringWheelRemote.cpp
Revision: 20
Committed: 2007-06-08T19:26:14-07:00 (15 years, 6 months ago) by douglas
File size: 3396 byte(s)
Log Message:
Oops!

File Contents

# Content
1 // Steering Wheel Remote
2 //
3 // Douglas Thrift
4 //
5 // $Id$
6
7 #include <iostream>
8
9 #include <fcntl.h>
10
11 #include <posix.hpp>
12 #include <regex.hpp>
13 #include <truck.hpp>
14 #include <vector.hpp>
15
16 #include "Audacious.hpp"
17
18 bool debug(false);
19
20 enum Button
21 {
22 None = 000,
23 PlayPause = 001,
24 VolumeUp = 002,
25 VolumeDown = 004,
26 Next = 010,
27 Previous = 020
28 };
29
30 const _V<Button> buttons(PlayPause, VolumeUp, VolumeDown, Next, Previous);
31
32 inline std::ostream &operator<<(std::ostream &output, Button button)
33 {
34 switch (button)
35 {
36 case None:
37 return output << _B("None");
38 case PlayPause:
39 return output << _B("PlayPause");
40 case Previous:
41 return output << _B("Previous");
42 case Next:
43 return output << _B("Next");
44 case VolumeDown:
45 return output << _B("VolumeDown");
46 case VolumeUp:
47 return output << _B("VolumeUp");
48 default:
49 return output << _B("Unknown");
50 }
51 }
52
53 class Buttons
54 {
55 uint8_t current, previous;
56 _L<Button> events;
57
58 inline bool Pressed(Button button, bool current_ = true) const
59 {
60 return ((current_ ? current : previous) & button) == button;
61 }
62
63 public:
64 Buttons() : current(0) {}
65
66 inline const _L<Button> &Events() const
67 {
68 return events;
69 }
70
71 inline const _L<Button> &Events(uint8_t bytes[8])
72 {
73 if (debug)
74 {
75 _assert (bytes[0] == 3);
76 _assert (bytes[1] == 2);
77 _assert (bytes[2] == 0);
78 _assert (bytes[3] == -(bytes[4] - 0373));
79 _assert (bytes[5] == 0);
80 _assert (bytes[6] == 0);
81 _assert (bytes[7] == 0);
82 }
83
84 previous = current;
85 current = bytes[3];
86
87 events.clear();
88
89 _foreach (const _V<Button>, button, buttons)
90 if (Pressed(*button, false) && !Pressed(*button))
91 events.push_back(*button);
92
93 return events;
94 }
95
96 template <Button button>
97 inline bool Pressed()
98 {
99 return Pressed(button);
100 }
101 };
102
103 int main(int argc, char *argv[])
104 {
105 std::string device;
106
107 {
108 Pcre::RegEx devicePath(_B("^-device=(/.+)$"));
109 Pcre::RegEx deviceNumber(_B("^-device=([0-9]+)$"));
110 Pcre::RegEx deviceName(_B("^-device=(.+)$"));
111
112 for (char **arg = argv + 1; *arg; ++arg)
113 {
114 Pcre::RegEx::Match match;
115
116 if (*arg == _B("-debug"))
117 debug = true;
118 else if (match = devicePath(*arg))
119 device = match[1];
120 else if (match = deviceNumber(*arg))
121 device = _B("/dev/uhid") + match[1];
122 else if (match = deviceName(*arg))
123 device = _B("/dev/") + match[1];
124 else
125 goto usage;
126 }
127 }
128
129 if (device.empty())
130 {
131 usage: std::cout << _B("Usage: ") << argv[0] << _B(" [-debug] [-device=device]") << std::endl;
132
133 return 1;
134 }
135
136 try
137 {
138 int uhid(Posix::Open(device, O_RDONLY));
139 uint8_t bytes[8];
140 Buttons buttons;
141 Audacious audacious;
142
143 _forever
144 {
145 Posix::ReadMost(uhid, bytes, sizeof (bytes));
146
147 _foreach (const _L<Button>, button, buttons.Events(bytes))
148 {
149 if (debug)
150 std::cerr << _B("button=") << *button << std::endl;
151
152 if (audacious.IsRunning())
153 switch (*button)
154 {
155 default:
156 break;
157
158 case PlayPause:
159 audacious.PlayPause();
160
161 break;
162
163 case Previous:
164 audacious.PlaylistPrevious();
165
166 break;
167
168 case Next:
169 audacious.PlaylistNext();
170
171 break;
172
173 case VolumeDown:
174 case VolumeUp:
175 int volume(audacious.GetMainVolume() + (*button == VolumeUp ? 1 : -1));
176
177 audacious.SetMainVolume(volume);
178 }
179 }
180 }
181 }
182 catch (const Posix::Error &error)
183 {
184 std::cerr << argv[0] << _B(": ") << error.GetMessage() << std::endl;
185
186 return 1;
187 }
188
189 return 0;
190 }

Properties

Name Value
svn:keywords Id