Download
jcs
/wifi_da
/main.c
(View History)
jcs main: Make debug logging suck much less | Latest amendment: 28 on 2024-09-19 |
1 | /* |
2 | * Copyright (c) 2023 joshua stein <jcs@jcs.org> |
3 | * |
4 | * Permission to use, copy, modify, and distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above |
6 | * copyright notice and this permission notice appear in all copies. |
7 | * |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ |
16 | |
17 | #include <stdarg.h> |
18 | #include <stdio.h> |
19 | #include <string.h> |
20 | #include "wi-fi.h" |
21 | |
22 | /* device control entry */ |
23 | DCtlPtr dce = NULL; |
24 | |
25 | SysEnvRec world; |
26 | #define ON_SYSTEM_7 (world.systemVersion >= 0x0700) |
27 | |
28 | short da_state = STATE_CLOSED; |
29 | short wifi_scsi_id = WIFI_SCSI_ID_FINDING; |
30 | unsigned long wifi_scan_started = 0; |
31 | struct wifi_network_entry wifi_cur_info = { 0 }; |
32 | struct wifi_network_entry wifi_scan_networks[10] = { 0 }; |
33 | MenuHandle menu, apple_menu; |
34 | short menuID = 0; |
35 | WindowPtr win = 0L; |
36 | Cursor watch; |
37 | WindowPtr logger = 0; |
38 | |
39 | short main(cntrlParam *p, DCtlPtr d, short n); |
40 | void da_open(void); |
41 | void da_control(short code, short *parm); |
42 | void da_close(void); |
43 | bool handle_menu(short i); |
44 | void handle_event(EventRecord *e); |
45 | void handle_timer(void); |
46 | #ifdef DEBUG_LOGGING |
47 | void logger_vprintf(const char *format, va_list ap); |
48 | #endif |
49 | |
50 | short |
51 | main(cntrlParam *p, DCtlPtr d, short n) |
52 | { |
53 | if (d->dCtlStorage == 0) { |
54 | /* open */ |
55 | if (n == 0) { |
56 | SysBeep(3); |
57 | CloseDriver(d->dCtlRefNum); |
58 | } |
59 | return 0; |
60 | } |
61 | |
62 | if (dce == NULL) { |
63 | util_init(d); |
64 | SysEnvirons(1, &world); |
65 | } |
66 | |
67 | dce = d; |
68 | dce->dCtlFlags &= ~dCtlEnable; |
69 | |
70 | switch (n) { |
71 | case 0: |
72 | da_open(); |
73 | break; |
74 | case 2: |
75 | da_control(p->csCode, p->csParam); |
76 | break; |
77 | case 4: |
78 | da_close(); |
79 | break; |
80 | } |
81 | |
82 | dce->dCtlFlags |= dCtlEnable; |
83 | |
84 | return 0; |
85 | } |
86 | |
87 | /* |
88 | * This is called each time the DA is selected from the Apple menu, |
89 | * even if we're already open. However, the Device Manager resets |
90 | * the "dCtlFlags", "dCtlMenu", "dCtlDelay", and "dCtlEMask" fields |
91 | * of the device control entry from the corresponding fields of the |
92 | * device header each time the desk accessory is opened. |
93 | */ |
94 | void |
95 | da_open(void) |
96 | { |
97 | CursHandle h; |
98 | Rect bounds; |
99 | bool dispose; |
100 | |
101 | dce->dCtlFlags |= dNeedLock | dNeedTime | dNeedGoodBye; |
102 | dce->dCtlDelay = 61; |
103 | |
104 | #ifdef DEBUG_LOGGING |
105 | if (!logger) { |
106 | bounds.top = 150; |
107 | bounds.bottom = 320; |
108 | bounds.left = 20; |
109 | bounds.right = 400; |
110 | logger = NewWindow(0L, &bounds, "\pLogger", true, rDocProc, 0L, |
111 | true, 0L); |
112 | ((WindowPeek)logger)->windowKind = dce->dCtlRefNum; |
113 | } |
114 | #endif |
115 | |
116 | if (win) |
117 | SelectWindow(win); |
118 | |
119 | if (da_state != STATE_CLOSED) { |
120 | dce->dCtlMenu = menuID; |
121 | return; |
122 | } |
123 | |
124 | da_state = STATE_INIT; |
125 | |
126 | SetResLoad(false); |
127 | h = GetCursor(watchCursor); |
128 | dispose = (GetHandleSize((Handle)h) == 0); |
129 | SetResLoad(true); |
130 | BlockMove(*(h = GetCursor(watchCursor)), &watch, sizeof(Cursor)); |
131 | if (dispose) |
132 | ReleaseResource((Handle)h); |
133 | |
134 | if (!ON_SYSTEM_7) { |
135 | dce->dCtlMenu = menuID = OwnedResourceID(MAIN_MENU_ID); |
136 | menu = GetMenu(menuID); |
137 | (**menu).menuID = menuID; |
138 | InsertMenu(menu = GetMenu(menuID), 0); |
139 | DrawMenuBar(); |
140 | } |
141 | |
142 | dce->dCtlWindow = create_window(dce->dCtlRefNum); |
143 | |
144 | HiliteMenu(0); |
145 | } |
146 | |
147 | void |
148 | da_control(short code, short *param) |
149 | { |
150 | switch (code) { |
151 | case accMenu: |
152 | handle_menu(param[1]); |
153 | break; |
154 | case accEvent: |
155 | handle_event(*((EventRecord **)param)); |
156 | break; |
157 | case accRun: |
158 | handle_timer(); |
159 | break; |
160 | case goodbye: |
161 | break; |
162 | } |
163 | } |
164 | |
165 | void |
166 | da_close(void) |
167 | { |
168 | if (!ON_SYSTEM_7) { |
169 | DeleteMenu(dce->dCtlMenu); |
170 | DrawMenuBar(); |
171 | DisposeMenu(menu); |
172 | } |
173 | |
174 | dce->dCtlMenu = 0; |
175 | destroy_window(); |
176 | if (logger) { |
177 | DisposeWindow(logger); |
178 | logger = 0; |
179 | } |
180 | dce->dCtlWindow = 0; |
181 | da_state = STATE_CLOSED; |
182 | } |
183 | |
184 | bool |
185 | handle_menu(short i) |
186 | { |
187 | bool ret = true; |
188 | |
189 | switch (i) { |
190 | case MAIN_MENU_ABOUT_ID: |
191 | wifi_about(); |
192 | break; |
193 | case MAIN_MENU_QUIT_ID: |
194 | CloseDriver(dce->dCtlRefNum); |
195 | break; |
196 | default: |
197 | ret = false; |
198 | } |
199 | |
200 | HiliteMenu(0); |
201 | return ret; |
202 | } |
203 | |
204 | void |
205 | handle_event(EventRecord *e) |
206 | { |
207 | short key, mk; |
208 | |
209 | switch (e->what) { |
210 | case updateEvt: |
211 | update_window(false); |
212 | break; |
213 | case mouseDown: |
214 | window_mousedown(e->where); |
215 | update_window(false); |
216 | break; |
217 | case activateEvt: |
218 | activate_window((bool)(e->modifiers & activeFlag)); |
219 | break; |
220 | case keyDown: |
221 | case autoKey: |
222 | key = e->message & charCodeMask; |
223 | if ((e->modifiers & cmdKey) != 0) { |
224 | mk = MenuKey(key); |
225 | if (mk != 0 && handle_menu(mk)) |
226 | break; |
227 | } |
228 | break; |
229 | } |
230 | } |
231 | |
232 | void |
233 | handle_timer(void) |
234 | { |
235 | static long last_update = 0; |
236 | static long last_scan = 0; |
237 | |
238 | if (!win) |
239 | return; |
240 | |
241 | switch (da_state) { |
242 | case STATE_SCANNING: |
243 | /* check every second */ |
244 | if ((Ticks - last_update) < (60 * 1)) |
245 | break; |
246 | DEBUG_LOG(("%ld - handle_timer - checking for scan completion", |
247 | Ticks)); |
248 | last_update = Ticks; |
249 | if (!scsi_wifi_scan_finished(wifi_scsi_id)) { |
250 | DEBUG_LOG(("%ld - handle_timer - scan not done", Ticks)); |
251 | if (Time - wifi_scan_started <= 5) |
252 | break; |
253 | DEBUG_LOG(("Wi-Fi scan failed to finish, canceling")); |
254 | } |
255 | last_scan = Ticks; |
256 | da_state = STATE_IDLE; |
257 | DEBUG_LOG(("%ld - handle_timer - scan done, updating list", Ticks)); |
258 | update_wifi_ssid_list(true); |
259 | break; |
260 | case STATE_IDLE: |
261 | /* refresh SSID/RSSI every 5 seconds, scan every 30 */ |
262 | if ((Ticks - last_update) < (60 * 5)) |
263 | break; |
264 | last_update = Ticks; |
265 | |
266 | if ((Ticks - last_scan) > (60 * 30)) { |
267 | da_state = STATE_SCANNING; |
268 | DEBUG_LOG(("%ld - handle_timer - idle, scanning", Ticks)); |
269 | scsi_wifi_scan(wifi_scsi_id); |
270 | } else { |
271 | DEBUG_LOG(("%ld - handle_timer - idle, updating info", Ticks)); |
272 | update_wifi_cur_info(); |
273 | } |
274 | break; |
275 | } |
276 | } |
277 | |
278 | #ifdef DEBUG_LOGGING |
279 | void |
280 | logger_printf(const char *format, ...) |
281 | { |
282 | va_list va; |
283 | |
284 | if (!logger) |
285 | return; |
286 | |
287 | va_start(va, format); |
288 | logger_vprintf(format, va); |
289 | va_end(va); |
290 | } |
291 | |
292 | void |
293 | logger_vprintf(const char *format, va_list ap) |
294 | { |
295 | static char buf[512]; |
296 | GrafPtr savePort; |
297 | ssize_t len; |
298 | RgnHandle clip; |
299 | |
300 | len = vsnprintf(buf, sizeof(buf), format, ap); |
301 | |
302 | GetPort(&savePort); |
303 | SetPort(logger); |
304 | |
305 | clip = NewRgn(); |
306 | ScrollRect(&logger->portRect, 0, -11, clip); |
307 | DisposeRgn(clip); |
308 | |
309 | MoveTo(4, logger->portRect.bottom - 4); |
310 | TextFont(geneva); |
311 | TextSize(9); |
312 | DrawText(buf, 0, len); |
313 | |
314 | ValidRect(&logger->portRect); |
315 | SetPort(savePort); |
316 | } |
317 | #endif |