ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/truck/SteeringWheelRemote/SteeringWheelRemote.cpp
Revision: 14
Committed: 2007-05-14T18:24:34-07:00 (15 years, 6 months ago) by douglas
File size: 3369 byte(s)
Log Message:
Switch back from Menes C++ to stl and hacks.

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 <common.hpp>
12 #include <posix.hpp>
13 #include <regex.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 inline const _L<Button> &Events() const
65 {
66 return events;
67 }
68
69 inline const _L<Button> &Events(uint8_t bytes[8])
70 {
71 if (debug)
72 {
73 _assert (bytes[0] == 3);
74 _assert (bytes[1] == 2);
75 _assert (bytes[2] == 0);
76 _assert (bytes[3] == -(bytes[4] - 0373));
77 _assert (bytes[5] == 0);
78 _assert (bytes[6] == 0);
79 _assert (bytes[7] == 0);
80 }
81
82 previous = current;
83 current = bytes[3];
84
85 events.clear();
86
87 _foreach (const _V<Button>, button, buttons)
88 if (Pressed(*button, false) && !Pressed(*button))
89 events.push_back(*button);
90
91 return events;
92 }
93
94 template <Button button>
95 inline bool Pressed()
96 {
97 return Pressed(button);
98 }
99 };
100
101 int main(int argc, char *argv[])
102 {
103 std::string device;
104
105 {
106 Pcre::RegEx devicePath(_B("^-device=(/.+)$"));
107 Pcre::RegEx deviceNumber(_B("^-device=([0-9]+)$"));
108 Pcre::RegEx deviceName(_B("^-device=(.+)$"));
109
110 for (char **arg = argv + 1; *arg; ++arg)
111 {
112 Pcre::RegEx::Match match;
113
114 if (*arg == _B("-debug"))
115 debug = true;
116 else if (match = devicePath(*arg))
117 device = match[1];
118 else if (match = deviceNumber(*arg))
119 device = _B("/dev/uhid") + match[1];
120 else if (match = deviceName(*arg))
121 device = _B("/dev/") + match[1];
122 else
123 goto usage;
124 }
125 }
126
127 if (device.empty())
128 {
129 usage: std::cout << _B("Usage: ") << argv[0] << _B(" [-debug] [-device=device]") << std::endl;
130
131 return 1;
132 }
133
134 try
135 {
136 int uhid(Posix::Open(device, O_RDONLY));
137 uint8_t bytes[8];
138 Buttons buttons;
139 Audacious audacious;
140
141 _forever
142 {
143 Posix::ReadMost(uhid, bytes, sizeof (bytes));
144
145 _foreach (const _L<Button>, button, buttons.Events(bytes))
146 {
147 if (debug)
148 std::cerr << _B("button=") << *button << std::endl;
149
150 if (audacious.IsRunning())
151 switch (*button)
152 {
153 default:
154 break;
155
156 case PlayPause:
157 audacious.PlayPause();
158
159 break;
160
161 case Previous:
162 audacious.PlaylistPrevious();
163
164 break;
165
166 case Next:
167 audacious.PlaylistNext();
168
169 break;
170
171 case VolumeDown:
172 case VolumeUp:
173 int volume(audacious.GetMainVolume() + (*button == VolumeUp ? 1 : -1));
174
175 audacious.SetMainVolume(volume);
176 }
177 }
178 }
179 }
180 catch (const Posix::Error &error)
181 {
182 std::cerr << argv[0] << _B(": ") << error.GetMessage() << std::endl;
183
184 return 1;
185 }
186
187 return 0;
188 }

Properties

Name Value
svn:keywords Id