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

Comparing DashInterface/DashInterface.cpp (file contents):
Revision 35 by douglas, 2008-03-04T20:37:13-08:00 vs.
Revision 41 by douglas, 2008-03-06T02:41:40-08:00

# Line 4 | Line 4
4   //
5   // $Id$
6  
7 + #include <algorithm>
8   #include <iomanip>
9   #include <iostream>
10   #include <sstream>
11  
12   #include <foreach.hpp>
13   #include <hash.hpp>
14 + #include <iconv.hpp>
15   #include <regex.hpp>
16 + #include <scopes.hpp>
17 + #include <timing.hpp>
18  
19   #include <Audacious.hpp>
20   #include <GPS.hpp>
# Line 25 | Line 29
29  
30   bool debug(false);
31  
32 < void Uname(Display &display, time_t now = 0, bool change = false)
32 > class DashInterface
33   {
34 <        if (!now || change)
35 <        {
36 <                utsname os;
34 >        enum Mode { Uname, Music, English, Metric, Nautical, Menu } mode, previous;
35 >        enum { Running, Audio };
36 >        enum { Stopped, Paused, Playing } audio;
37 >        enum Level { Top, Artist, Album, Song } level;
38 >        Timing::Time now;
39 >        IConv::IConv ascii;
40 >        Display display;
41 >        Pthreads::ThreadMutex displayLock;
42 >        Audacious::Audacious audacious;
43 >        //GPS::GPS gps;
44  
45 <                ::uname(&os);
45 >        inline std::string Filter(const std::string input)
46 >        {
47 >                std::string output(ascii.Convert(input));
48  
49 <                static Pcre::RegEx version(_B("^(\\d+\\.\\d+)-([A-Z])[A-Z]*(-p\\d+)?.*$"));
37 <                Pcre::RegEx::Match match(version(os.release));
49 >                std::replace(output.begin(), output.end(), '~', char(206));
50  
51 <                display.Set(0, 1, os.sysname + _B(" ") + match[1] + match[2] + match[3]);
51 >                return output;
52          }
53  
54 <        int mib[] = { CTL_KERN, KERN_BOOTTIME };
55 <        timeval boottime;
56 <        size_t size(sizeof (boottime));
54 >        void Mode_(bool change = false)
55 >        {
56 >                switch (mode)
57 >                {
58 >                case Uname:
59 >                        return Uname_(change);
60 >                case Music:
61 >                        if (audacious.IsRunning())
62 >                        {
63 >                                int position(audacious.GetPlaylistPosition());
64 >                                std::string artist(Filter(audacious.GetTupleFieldData(_B("artist"), position)));
65 >
66 >                                display.Set(0, 1, artist.size() > 20 ? artist.erase(20) : artist.append(20 - artist.size(), ' '));
67 >
68 >                                std::string title(Filter(audacious.GetTupleFieldData(_B("title"), position)));
69 >
70 >                                display.Set(0, 2, title.size() > 20 ? title.erase(20) : title.append(20 - title.size(), ' '));
71 >
72 >                                int played(audacious.GetOutputTime() / 1000);
73 >                                int left(audacious.GetPlaylistTime(position) / 1000 - played);
74 >                                char *times;
75 >
76 >                                ::asprintf(&times, "%2i:%02i -%2i:%02i", played / 60, played % 60, left / 60, left % 60);
77 >
78 >                                display.Set(0, 3, times + std::string(20 - std::strlen(times), ' '));
79 >
80 >                                std::free(times);
81 >                        }
82 >                        else
83 >                        {
84 >                                display.Set(0, 1, std::string(20, ' '));
85 >                                display.Set(0, 2, std::string(20, ' '));
86 >                                display.Set(0, 3, _B(" -:-- - -:--       "));
87 >                        }
88 >
89 >                        return;
90 >                case English:
91 >                case Metric:
92 >                case Nautical:
93 >                        display.Set(0, 1, _B("STUB: GPS ") + (mode == English ? _B("English   ") : mode == Metric ? _B("Metric    ") : _B("Nautical  ")));
94 >                        display.Set(0, 2, std::string(20, ' '));
95 >                        display.Set(0, 3, std::string(20, ' '));
96 >
97 >                        return;
98 >                case Menu:
99 >                        if (change)
100 >                                level = Top;
101 >                }
102 >        }
103  
104 <        if (now && ::sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0)
104 >        void Uname_(bool change = false)
105          {
106 <                time_t uptime(now - boottime.tv_sec);
106 >                if (!now || change)
107 >                {
108 >                        utsname os;
109 >
110 >                        ::uname(&os);
111  
112 <                if (uptime > 60)
113 <                        uptime += 30;
112 >                        static Pcre::RegEx version(_B("^(\\d+\\.\\d+)-([A-Z])[A-Z]*(-p\\d+)?.*$"));
113 >                        Pcre::RegEx::Match match(version(os.release));
114 >                        std::string name(os.sysname + _B(" ") + match[1] + match[2] + match[3]);
115  
116 <                char *when;
117 <                int days(uptime / 86400);
116 >                        display.Set(0, 1, name.append(20 - name.size(), ' '));
117 >                }
118 >
119 >                int mib[] = { CTL_KERN, KERN_BOOTTIME };
120 >                timeval boottime;
121 >                size_t size(sizeof (boottime));
122  
123 <                uptime %= 86400;
123 >                if (now && ::sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0)
124 >                {
125 >                        time_t uptime(now - boottime.tv_sec);
126  
127 <                int hours(uptime / 3600);
127 >                        if (uptime > 60)
128 >                                uptime += 30;
129  
130 <                uptime %= 3600;
130 >                        char *when;
131 >                        int days(uptime / 86400);
132  
133 <                int minutes(uptime / 60), seconds(uptime % 60);
133 >                        uptime %= 86400;
134  
135 <                ::asprintf(&when, "%i+%02i:%02i:%02i", days, hours, minutes, seconds);
135 >                        int hours(uptime / 3600);
136  
137 <                std::string then(when);
137 >                        uptime %= 3600;
138  
139 <                then.append(17 - std::strlen(when), ' ');
139 >                        int minutes(uptime / 60), seconds(uptime % 60);
140  
141 <                std::free(when);
141 >                        ::asprintf(&when, "%i+%02i:%02i:%02i", days, hours, minutes, seconds);
142  
143 <                if (change)
144 <                        display.Set(0, 2, _B("up ") + then);
143 >                        std::string then(when);
144 >
145 >                        then.append(17 - std::strlen(when), ' ');
146 >
147 >                        std::free(when);
148 >
149 >                        if (change)
150 >                                display.Set(0, 2, _B("up ") + then);
151 >                        else
152 >                                display.Set(3, 2, then);
153 >                }
154 >                else
155 >                        display.Set(0, 2, _B("up -+--:--:--       "));
156 >
157 >                double averages[3];
158 >
159 >                if (::getloadavg(averages, 3) == -1 || !now)
160 >                        display.Set(0, 3, _B("-.--, -.--, -.--    "));
161                  else
162 <                        display.Set(3, 2, then);
162 >                {
163 >                        char *load;
164 >
165 >                        ::asprintf(&load, "%.2f, %.2f, %.2f", averages[0], averages[1] , averages[2]);
166 >
167 >                        display.Set(0, 3, load + std::string(20 - std::strlen(load), ' '));
168 >
169 >                        std::free(load);
170 >                }
171          }
77        else
78                display.Set(0, 2, _B("up -+--:--:--       "));
172  
173 <        double averages[3];
173 >        void Buttons(Display::KeyActivity activity)
174 >        {
175 >                _synchronized (displayLock)
176 >                        if (mode != Menu)
177 >                        {
178 >                                bool change(false);
179 >
180 >                                switch (activity)
181 >                                {
182 >                                case Display::UpPress:
183 >                                        --mode;
184 >
185 >                                        goto change;
186 >                                case Display::DownPress:
187 >                                        ++mode;
188 >
189 >                                        goto change;
190 >                                case Display::LeftPress:
191 >                                        if (audacious.IsRunning())
192 >                                                audacious.PlaylistPrevious();
193 >
194 >                                        goto update;
195 >                                case Display::RightPress:
196 >                                        if (audacious.IsRunning())
197 >                                                audacious.PlaylistNext();
198 >
199 >                                        goto update;
200 >                                case Display::EnterPress:
201 >                                        previous = mode;
202 >                                        mode = Menu;
203 >
204 >                                        goto change;
205 >                                case Display::ExitPress:
206 >                                        if (audacious.IsRunning())
207 >                                                audacious.PlayPause();
208 >
209 >                                        goto update;
210 >                                default:
211 >                                        return;
212 >                                }
213 >
214 > change:                 change = true;
215 >
216 > update:                 Mode_(change);
217 >                        }
218 >                        else
219 >                                switch (activity)
220 >                                {
221 >                                case Display::UpPress:
222 >                                case Display::DownPress:
223 >                                case Display::LeftPress:
224 >                                case Display::RightPress:
225 >                                case Display::EnterPress:
226 >                                        return;
227 >                                case Display::ExitPress:
228 >                                        mode = previous;
229 >
230 >                                        display.Set(0, 0, _B("  "));
231 >                                        display.Set(18, 0, _B("  "));
232 >
233 >                                        Mode_(true);
234 >                                default:
235 >                                        return;
236 >                                }
237 >        }
238 >
239 > public:
240 >        DashInterface(const std::string &device) : mode(Uname), audio(Stopped), ascii(_B("ASCII//TRANSLIT//IGNORE"), _B("UTF-8")), display(device, reinterpret_cast<Display::Callback>(::Buttons), this)
241 >        {
242 >                _synchronized (displayLock)
243 >                {
244 >                        display.Clear();
245 >                        display.SetBacklight(100);
246 >                        display.Set(2, 0, _B("--:--:-- -- ---"));
247 >
248 >                        display.Set(Running, Display::Green, 0);
249 >                        display.Set(Running, Display::Red, 100);
250 >                        display.Set(Audio, Display::Green, 0);
251 >                        display.Set(Audio, Display::Red, 100);
252 >
253 >                        uint8_t mask(Display::Up | Display::Enter | Display::Cancel | Display::Left | Display::Right | Display::Down);
254 >
255 >                        display.KeyReporting(mask, mask);
256 >
257 >                        Uname_();
258  
259 <        if (::getloadavg(averages, 3) == -1 || !now)
260 <                display.Set(0, 3, _B("-.--, -.--, -.--    "));
261 <        else
259 >                        display.Store();
260 >                        display.Set(Running, Display::Green, 100);
261 >                        display.Set(Running, Display::Red, 0);
262 >                }
263 >        }
264 >
265 >        void Run()
266          {
267 <                char *load;
267 >                _forever
268 >                {
269 >                        _synchronized (displayLock)
270 >                        {
271 >                                now = Timing::GetTimeOfDay();
272  
273 <                ::asprintf(&load, "%.2f, %.2f, %.2f", averages[0], averages[1] , averages[2]);
273 >                                if (mode != Menu)
274 >                                {
275 >                                        char when[16];
276 >
277 >                                        std::strftime(when, sizeof (when), "%l:%M:%S %p %Z", std::localtime(now));
278 >
279 >                                        display.Set(2, 0, when);
280 >                                }
281 >
282 >                                if (audacious.IsRunning() && audacious.IsPlaying())
283 >                                        if (audacious.IsPaused())
284 >                                        {
285 >                                                if (audio != Paused)
286 >                                                {
287 >                                                        display.Set(Audio, Display::Green, 100);
288 >                                                        display.Set(Audio, Display::Red, 100);
289 >
290 >                                                        audio = Paused;
291 >                                                }
292 >                                        }
293 >                                        else
294 >                                        {
295 >                                                if (audio != Playing)
296 >                                                {
297 >                                                        display.Set(Audio, Display::Green, 100);
298 >                                                        display.Set(Audio, Display::Red, 0);
299 >
300 >                                                        audio = Playing;
301 >                                                }
302 >                                        }
303 >                                else if (audio != Stopped)
304 >                                {
305 >                                        display.Set(Audio, Display::Green, 0);
306 >                                        display.Set(Audio, Display::Red, 100);
307  
308 <                display.Set(0, 3, load + std::string(20 - std::strlen(load), ' '));
308 >                                        audio = Stopped;
309 >                                }
310  
311 <                std::free(load);
311 >                                Mode_();
312 >                        }
313 >
314 >                        Timing::NanoSleep(Timing::Time(1) -= Timing::GetTimeOfDay().GetNanoseconds());
315 >                }
316 >        }
317 >
318 >        friend void Buttons(Display::KeyActivity activity, DashInterface *interface)
319 >        {
320 >                interface->Buttons(activity);
321 >        }
322 >
323 >        inline friend Mode &operator ++(Mode &mode)
324 >        {
325 >                return mode = Mode((mode + 1) % Menu);
326 >        }
327 >
328 >        inline friend Mode &operator --(Mode &mode)
329 >        {
330 >                return mode = Mode((Menu + mode - 1) % Menu);
331          }
332 < }
332 > };
333  
334   int main(int argc, char *argv[])
335   {
# Line 128 | Line 366 | usage: std::cout << _B("Usage: ") << arg
366  
367          try
368          {
369 <                Display display(device);
369 >                DashInterface interface(device);
370  
371 <                display.Clear();
134 <                display.SetBacklight(100);
135 <                display.Set(2, 0, _B("--:--:-- -- ---"));
136 <                display.Set(0, Display::Green, 0);
137 <                display.Set(0, Display::Red, 100);
138 <
139 <                {
140 <                        uint8_t mask(Display::Up | Display::Enter | Display::Cancel | Display::Left | Display::Right | Display::Down);
141 <
142 <                        display.KeyReporting(mask, mask);
143 <                }
144 <
145 <                ::Uname(display);
146 <
147 <                display.Store();
148 <
149 <                enum Mode { Uname, Music, English, Metric, Nautical, Last } mode(Uname);
150 <                //Audacious::Audacious audacious;
151 <                //GPS::GPS gps;
152 <
153 <                _forever
154 <                {
155 <                        time_t now(std::time(NULL));
156 <
157 <                        {
158 <                                char when[16];
159 <
160 <                                std::strftime(when, sizeof (when), "%l:%M:%S %p %Z", std::localtime(&now));
161 <
162 <                                display.Set(2, 0, when);
163 <                        }
164 <
165 <                        switch (mode)
166 <                        {
167 <                        default:
168 <                                ::Uname(display, now);
169 <
170 <                                break;
171 <                        case Music:
172 <                        case English:
173 <                        case Metric:
174 <                        case Nautical:
175 <                                break;
176 <                        }
177 <
178 <                        ::sleep(1);
179 <                }
371 >                interface.Run();
372          }
373          catch (const std::exception &exception)
374          {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines