ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/truck/DashInterface/DashInterface.cpp
Revision: 39
Committed: 2008-03-05T14:39:41-08:00 (17 years, 3 months ago) by douglas
File size: 5278 byte(s)
Log Message:
Supar refactor; hopefully it works!

File Contents

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

Properties

Name Value
svn:keywords Id