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 6 by douglas, 2007-05-06T21:04:16-07:00 vs.
Revision 12 by douglas, 2007-05-13T04:38:16-07:00

# Line 4 | Line 4
4   //
5   // $Id$
6  
7 < #include <iostream>
8 < #include <string>
7 > #include <cxx/standard.hh>
8  
9 < #include <err.h>
10 < #include <fcntl.h>
11 < #include <sys/ioctl.h>
12 <
13 < #include <common.hpp>
15 < #include <fdstream.hpp>
16 < #include <foreach.hpp>
17 < #include <posix.hpp>
18 < #include <regex.hpp>
9 > #include <api/exename.hpp>
10 > #include <api/pcre/regex.hpp>
11 > #include <api/files.hpp>
12 > #include <app/simple.hpp>
13 > #include <ext/helpers.hpp>
14  
15   #include "Audacious.hpp"
16  
17 < // XXX: this is probably little endian!
17 > bool debug(false);
18 >
19   enum Button
20   {
21 <        None = 0xfb00,
22 <        PlayPause = 0x0101,
23 <        Previous = 0x1010,
24 <        Next = 0x0808,
25 <        VolumeDown = 0x0c04,
26 <        VolumeUp = 0x0202
27 < }
28 < const buttons[] = { PlayPause, Previous, Next, VolumeDown, VolumeUp };
21 >        None            = 000,
22 >        PlayPause       = 001,
23 >        VolumeUp        = 002,
24 >        VolumeDown      = 004,
25 >        Next            = 010,
26 >        Previous        = 020
27 > };
28 >
29 > const _V<Button> buttons(PlayPause, VolumeUp, VolumeDown, Next, Previous);
30  
31 < inline std::ostream &operator<<(std::ostream &output, Button button)
31 > inline ios::PrintWriter &operator<<(ios::PrintWriter &output, Button button)
32   {
33          switch (button)
34          {
# Line 54 | Line 51 | inline std::ostream &operator<<(std::ost
51  
52   class Buttons
53   {
54 <        uint16_t current, previous;
55 <        mutable std::vector<Button> events;
54 >        byte_t current, previous;
55 >        _L<Button> events;
56  
57 <        inline bool Pressed(Button button, uint16_t buttons) const
57 >        inline bool Pressed(Button button, bool current_ = true) const
58          {
59 <                return ((buttons ^ None) & button) == button;
59 >                return ((current_ ? current : previous) & button) == button;
60          }
61  
62   public:
63 <        Buttons() : current(None) {}
67 <
68 <        const std::vector<Button> &Events() const
63 >        inline const _L<Button> &Events() const
64          {
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
65                  return events;
66          }
67  
68 <        friend std::istream &operator>>(std::istream &, Buttons &);
69 < };
70 <
71 < inline std::istream &operator>>(std::istream &input, Buttons &buttons)
72 < {
73 <        if (!input.ignore(3))
74 <                return input;
75 <
76 <        buttons.previous = buttons.current;
68 >        inline const _L<Button> &Events(byte_t bytes[8])
69 >        {
70 >                if (debug)
71 >                {
72 >                        _assert (bytes[0] == 3);
73 >                        _assert (bytes[1] == 2);
74 >                        _assert (bytes[2] == 0);
75 >                        _assert (bytes[3] == -(bytes[4] - 0373));
76 >                        _assert (bytes[5] == 0);
77 >                        _assert (bytes[6] == 0);
78 >                        _assert (bytes[7] == 0);
79 >                }
80  
81 <        buttons.events.clear();
81 >                previous = current;
82 >                current = bytes[3];
83  
84 <        if (!input.read(reinterpret_cast<char *>(&buttons.current), sizeof (buttons.current)))
91 <                return input;
84 >                events.Clear();
85  
86 <        return input.ignore(3);
87 < }
86 >                _foreach (const _V<Button>, button, buttons)
87 >                        if (Pressed(*button, false) && !Pressed(*button))
88 >                                events.InsertLast(*button);
89  
90 < int Usage(const std::string &program)
91 < {
98 <        std::cout << _B("Usage: ") << program << _B(" [-debug] [-device=device]") << std::endl;
90 >                return events;
91 >        }
92  
93 <        return 1;
94 < }
93 >        template <Button button>
94 >        inline bool Pressed()
95 >        {
96 >                return Pressed(button);
97 >        }
98 > };
99  
100 < int main(int argc, char *argv[])
100 > int Main(const app::Options &options)
101   {
102 <        bool debug(false);
106 <        std::string device;
102 >        cse::String device;
103  
104          {
105 <                Pcre::RegEx devicePath(_B("^-device=(/.+)$"));
106 <                Pcre::RegEx deviceNumber(_B("^-device=([0-9]+)$"));
107 <                Pcre::RegEx deviceName(_B("^-device=(.+)$"));
105 >                api::Pcre::RegEx devicePath(_B("^-device=(/.+)$"));
106 >                api::Pcre::RegEx deviceNumber(_B("^-device=([0-9]+)$"));
107 >                api::Pcre::RegEx deviceName(_B("^-device=(.+)$"));
108 >
109 >                _foreach (const app::ArgumentList, arg, app::GetArguments())
110 >                {
111 >                        api::Pcre::RegEx::Match match;
112  
113 <                _forall (int, index, 1, argc)
114 <                        if (argv[index] == _B("-debug"))
113 >                        if (*arg == _B("-debug"))
114                                  debug = true;
115 <                        else if (Pcre::RegEx::Match match = devicePath(argv[index]))
115 >                        else if (match = devicePath(*arg))
116                                  device = match[1];
117 <                        else if (Pcre::RegEx::Match match = deviceNumber(argv[index]))
118 <                                device = _B("/dev/uhid") + match[1];
119 <                        else if (Pcre::RegEx::Match match = deviceName(argv[index]))
120 <                                device = _B("/dev/") + match[1];
117 >                        else if (match = deviceNumber(*arg))
118 >                                device = _S<ios::String>() << _B("/dev/uhid") << match[1];
119 >                        else if (match = deviceName(*arg))
120 >                                device = _S<ios::String>() << _B("/dev/") << match[1];
121                          else
122 <                                return Usage(argv[0]);
122 >                                goto usage;
123 >                }
124          }
125  
126 <        if (device.empty())
127 <                return Usage(argv[0]);
126 >        if (device.IsEmpty())
127 >        {
128 > usage:  api::Cout << _B("Usage: ") << api::GetExecutablePath().GetName() << _B(" [-debug] [-device=device]") << ios::NewLine;
129  
130 <        ext::ifdstream uhid(Posix::CheckError(::open(device.c_str(), O_RDONLY)));
131 <        Buttons buttons;
131 <        Audacious audacious;
130 >                return 1;
131 >        }
132  
133 <        if (!debug)
134 <                Posix::CheckError(::daemon(0, 1));
133 >        try
134 >        {
135 >                _S<api::FileReader> uhid(device);
136 >                byte_t bytes[8];
137 >                Buttons buttons;
138 >                Audacious audacious;
139  
140 <        while (uhid >> buttons)
137 <                _foreach (const std::vector<Button>, button, buttons.Events())
140 >                _forever
141                  {
142 <                        if (debug)
143 <                                std::cout << _B("button=") << *button << std::endl;
142 >                        uhid.ReadFully(bytes, sizeof (bytes));
143 >
144 >                        _foreach (const _L<Button>, button, buttons.Events(bytes))
145 >                        {
146 >                                if (debug)
147 >                                        api::Cerr << _B("button=") << *button << ios::NewLine;
148  
149 <                        if (audacious.IsRunning())
150 <                                switch (*button)
151 <                                {
152 <                                default:
153 <                                        break;
149 >                                if (audacious.IsRunning())
150 >                                        switch (*button)
151 >                                        {
152 >                                        default:
153 >                                                break;
154  
155 <                                case PlayPause:
156 <                                        audacious.PlayPause();
155 >                                        case PlayPause:
156 >                                                audacious.PlayPause();
157  
158 <                                        break;
158 >                                                break;
159  
160 <                                case Previous:
161 <                                        audacious.PlaylistPrevious();
160 >                                        case Previous:
161 >                                                audacious.PlaylistPrevious();
162  
163 <                                        break;
163 >                                                break;
164  
165 <                                case Next:
166 <                                        audacious.PlaylistNext();
165 >                                        case Next:
166 >                                                audacious.PlaylistNext();
167  
168 <                                        break;
168 >                                                break;
169  
170 <                                case VolumeDown:
171 <                                case VolumeUp:
172 <                                        int volume(audacious.GetMainVolume() + (*button == VolumeUp ? 1 : -1));
170 >                                        case VolumeDown:
171 >                                        case VolumeUp:
172 >                                                int volume(audacious.GetMainVolume() + (*button == VolumeUp ? 1 : -1));
173  
174 <                                        audacious.SetMainVolume(volume);
175 <                                }
174 >                                                audacious.SetMainVolume(volume);
175 >                                        }
176 >                        }
177                  }
178 +        }
179 +        catch (const api::Error &error)
180 +        {
181 +                api::Cerr << api::GetExecutablePath().GetName() << _B(": ") << error.GetMessage() << ios::NewLine;
182 +
183 +                return 1;
184 +        }
185  
186          return 0;
187   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines