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 40 by douglas, 2008-03-05T20:23:58-08:00

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines