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 30 by douglas, 2008-02-28T17:01:10-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>
21  
22 + #include <sys/types.h>
23 + #include <sys/sysctl.h>
24 + #include <sys/utsname.h>
25 +
26   #include <sqlite3.h>
27  
28   #include "Display.hpp"
29  
30   bool debug(false);
31  
32 + class DashInterface
33 + {
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 +        inline std::string Filter(const std::string input)
46 +        {
47 +                std::string output(ascii.Convert(input));
48 +
49 +                std::replace(output.begin(), output.end(), '~', char(206));
50 +
51 +                return output;
52 +        }
53 +
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 +        void Uname_(bool change = false)
105 +        {
106 +                if (!now || change)
107 +                {
108 +                        utsname os;
109 +
110 +                        ::uname(&os);
111 +
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 +                        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 +                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 +                        if (uptime > 60)
128 +                                uptime += 30;
129 +
130 +                        char *when;
131 +                        int days(uptime / 86400);
132 +
133 +                        uptime %= 86400;
134 +
135 +                        int hours(uptime / 3600);
136 +
137 +                        uptime %= 3600;
138 +
139 +                        int minutes(uptime / 60), seconds(uptime % 60);
140 +
141 +                        ::asprintf(&when, "%i+%02i:%02i:%02i", days, hours, minutes, seconds);
142 +
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 +                {
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 +        }
172 +
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 +                        display.Store();
260 +                        display.Set(Running, Display::Green, 100);
261 +                        display.Set(Running, Display::Red, 0);
262 +                }
263 +        }
264 +
265 +        void Run()
266 +        {
267 +                _forever
268 +                {
269 +                        _synchronized (displayLock)
270 +                        {
271 +                                now = Timing::GetTimeOfDay();
272 +
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 +                                        audio = Stopped;
309 +                                }
310 +
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 + };
333 +
334   int main(int argc, char *argv[])
335   {
336          std::string device;
# Line 54 | Line 366 | usage: std::cout << _B("Usage: ") << arg
366  
367          try
368          {
369 <                //enum Mode { Uname, Music, English, Metric, Nautical, Last } mode(Uname);
58 <                //Audacious audacious;
59 <                Display display(device);
60 <
61 <                display.Ping("Hello!");
62 <
63 <                std::cout << display.Version() << std::endl;
64 <
65 <                display.Store();
66 <                display.Clear();
67 <                display.SetBacklight(100);
68 <                display.KeyReporting(Display::Up | Display::Enter | Display::Cancel | Display::Left | Display::Right | Display::Down, Display::Up | Display::Enter | Display::Cancel | Display::Left | Display::Right | Display::Down);
69 <                display.Set(0, 0, _B("Hello, World!"));
70 <                display.Set(0, Display::Green, 0);
71 <                display.Set(0, Display::Red, 100);
72 <
73 <                /*GPS::GPS gps;
74 <
75 <                gps.Query(_B("o"));
369 >                DashInterface interface(device);
370  
371 <                std::cout << gps.GetLatitude() << std::endl;*/
371 >                interface.Run();
372          }
373          catch (const std::exception &exception)
374          {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines