ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/truck/SteeringWheelRemote/SteeringWheelRemote.cpp
(Generate patch)

Comparing SteeringWheelRemote/SteeringWheelRemote.cpp (file contents):
Revision 1 by douglas, 2007-04-25T18:29:45-07:00 vs.
Revision 6 by douglas, 2007-05-06T21:04:16-07:00

# Line 4 | Line 4
4   //
5   // $Id$
6  
7 #include <cassert>
7   #include <iostream>
9 #include <sstream>
8   #include <string>
9  
10 < #include <dev/usb/usb.h>
13 < #include <dev/usb/usbhid.h>
10 > #include <err.h>
11   #include <fcntl.h>
12   #include <sys/ioctl.h>
16 #include <usbhid.h>
13  
14 < int main(int argc, char *argv[])
14 > #include <common.hpp>
15 > #include <fdstream.hpp>
16 > #include <foreach.hpp>
17 > #include <posix.hpp>
18 > #include <regex.hpp>
19 >
20 > #include "Audacious.hpp"
21 >
22 > // XXX: this is probably little endian!
23 > enum Button
24 > {
25 >        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 >        {
38 >        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 >
55 > class Buttons
56   {
57 <        for (unsigned number(0); true; ++number)
57 >        uint16_t current, previous;
58 >        mutable std::vector<Button> events;
59 >
60 >        inline bool Pressed(Button button, uint16_t buttons) const
61 >        {
62 >                return ((buttons ^ None) & button) == button;
63 >        }
64 >
65 > public:
66 >        Buttons() : current(None) {}
67 >
68 >        const std::vector<Button> &Events() const
69          {
70 <                std::ostringstream device;
70 >                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 >        }
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 <                device << "/dev/usb" << number;
86 >        buttons.previous = buttons.current;
87  
88 <                int usb(::open(device.str().c_str(), O_RDONLY));
88 >        buttons.events.clear();
89  
90 <                if (usb == -1)
91 <                        break;
90 >        if (!input.read(reinterpret_cast<char *>(&buttons.current), sizeof (buttons.current)))
91 >                return input;
92  
93 <                usb_device_info info;
93 >        return input.ignore(3);
94 > }
95  
96 <                info.udi_addr = 1;
96 > int Usage(const std::string &program)
97 > {
98 >        std::cout << _B("Usage: ") << program << _B(" [-debug] [-device=device]") << std::endl;
99  
100 <                assert(::ioctl(usb, USB_DEVICEINFO, &info) != -1);
100 >        return 1;
101 > }
102  
103 <                for (unsigned port(0); port != info.udi_nports; ++port)
104 <                        std::cerr << unsigned(info.udi_ports[port]) << std::endl;
103 > int main(int argc, char *argv[])
104 > {
105 >        bool debug(false);
106 >        std::string device;
107  
108 <                ::close(usb);
108 >        {
109 >                Pcre::RegEx devicePath(_B("^-device=(/.+)$"));
110 >                Pcre::RegEx deviceNumber(_B("^-device=([0-9]+)$"));
111 >                Pcre::RegEx deviceName(_B("^-device=(.+)$"));
112 >
113 >                _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          }
125  
126 +        if (device.empty())
127 +                return Usage(argv[0]);
128 +
129 +        ext::ifdstream uhid(Posix::CheckError(::open(device.c_str(), O_RDONLY)));
130 +        Buttons buttons;
131 +        Audacious audacious;
132 +
133 +        if (!debug)
134 +                Posix::CheckError(::daemon(0, 1));
135 +
136 +        while (uhid >> buttons)
137 +                _foreach (const std::vector<Button>, button, buttons.Events())
138 +                {
139 +                        if (debug)
140 +                                std::cout << _B("button=") << *button << std::endl;
141 +
142 +                        if (audacious.IsRunning())
143 +                                switch (*button)
144 +                                {
145 +                                default:
146 +                                        break;
147 +
148 +                                case PlayPause:
149 +                                        audacious.PlayPause();
150 +
151 +                                        break;
152 +
153 +                                case Previous:
154 +                                        audacious.PlaylistPrevious();
155 +
156 +                                        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 +                }
170 +
171          return 0;
172   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines