AmendHub

Download

jcs

/

wifi_da

/

main.c

 

(View History)

jcs   *: Make some warnings less warny Latest amendment: 22 on 2023-10-25

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 short logger_y = 12;
38 WindowPtr logger = 0;
39
40 short main(cntrlParam *p, DCtlPtr d, short n);
41 void da_open(void);
42 void da_control(short code, short *parm);
43 void da_close(void);
44 bool handle_menu(short i);
45 void handle_event(EventRecord *e);
46 void handle_timer(void);
47 #ifdef DEBUG_LOGGING
48 void logger_vprintf(const char *format, va_list ap);
49 #endif
50
51 short
52 main(cntrlParam *p, DCtlPtr d, short n)
53 {
54 if (d->dCtlStorage == 0) {
55 /* open */
56 if (n == 0) {
57 SysBeep(3);
58 CloseDriver(d->dCtlRefNum);
59 }
60 return 0;
61 }
62
63 if (dce == NULL) {
64 util_init(d);
65 SysEnvirons(1, &world);
66 }
67
68 dce = d;
69 dce->dCtlFlags &= ~dCtlEnable;
70
71 switch (n) {
72 case 0:
73 da_open();
74 break;
75 case 2:
76 da_control(p->csCode, p->csParam);
77 break;
78 case 4:
79 da_close();
80 break;
81 }
82
83 dce->dCtlFlags |= dCtlEnable;
84
85 return 0;
86 }
87
88 /*
89 * This is called each time the DA is selected from the Apple menu,
90 * even if we're already open. However, the Device Manager resets
91 * the "dCtlFlags", "dCtlMenu", "dCtlDelay", and "dCtlEMask" fields
92 * of the device control entry from the corresponding fields of the
93 * device header each time the desk accessory is opened.
94 */
95 void
96 da_open(void)
97 {
98 CursHandle h;
99 Rect bounds;
100 bool dispose;
101
102 dce->dCtlFlags |= dNeedLock | dNeedTime | dNeedGoodBye;
103 dce->dCtlDelay = 61;
104
105 #ifdef DEBUG_LOGGING
106 if (!logger) {
107 bounds.top = 150;
108 bounds.bottom = 320;
109 bounds.left = 20;
110 bounds.right = 400;
111 logger = NewWindow(0L, &bounds, "\pLogger", true, rDocProc, 0L,
112 true, 0L);
113 ((WindowPeek)logger)->windowKind = dce->dCtlRefNum;
114 }
115 #endif
116
117 if (win)
118 SelectWindow(win);
119
120 if (da_state != STATE_CLOSED) {
121 dce->dCtlMenu = menuID;
122 return;
123 }
124
125 da_state = STATE_INIT;
126
127 SetResLoad(false);
128 h = GetCursor(watchCursor);
129 dispose = (GetHandleSize((Handle)h) == 0);
130 SetResLoad(true);
131 BlockMove(*(h = GetCursor(watchCursor)), &watch, sizeof(Cursor));
132 if (dispose)
133 ReleaseResource((Handle)h);
134
135 if (!ON_SYSTEM_7) {
136 dce->dCtlMenu = menuID = OwnedResourceID(MAIN_MENU_ID);
137 menu = GetMenu(menuID);
138 (**menu).menuID = menuID;
139 InsertMenu(menu = GetMenu(menuID), 0);
140 DrawMenuBar();
141 }
142
143 dce->dCtlWindow = create_window(dce->dCtlRefNum);
144
145 HiliteMenu(0);
146 }
147
148 void
149 da_control(short code, short *param)
150 {
151 switch (code) {
152 case accMenu:
153 handle_menu(param[1]);
154 break;
155 case accEvent:
156 handle_event(*((EventRecord **)param));
157 break;
158 case accRun:
159 handle_timer();
160 break;
161 case goodbye:
162 break;
163 }
164 }
165
166 void
167 da_close(void)
168 {
169 if (!ON_SYSTEM_7) {
170 DeleteMenu(dce->dCtlMenu);
171 DrawMenuBar();
172 DisposeMenu(menu);
173 }
174
175 dce->dCtlMenu = 0;
176 destroy_window();
177 if (logger) {
178 DisposeWindow(logger);
179 logger = 0;
180 }
181 dce->dCtlWindow = 0;
182 da_state = STATE_CLOSED;
183 }
184
185 bool
186 handle_menu(short i)
187 {
188 bool ret = true;
189
190 switch (i) {
191 case MAIN_MENU_ABOUT_ID:
192 wifi_about();
193 break;
194 case MAIN_MENU_QUIT_ID:
195 CloseDriver(dce->dCtlRefNum);
196 break;
197 default:
198 ret = false;
199 }
200
201 HiliteMenu(0);
202 return ret;
203 }
204
205 void
206 handle_event(EventRecord *e)
207 {
208 short key, mk;
209
210 switch (e->what) {
211 case updateEvt:
212 update_window(false);
213 break;
214 case mouseDown:
215 window_mousedown(e->where);
216 update_window(false);
217 break;
218 case activateEvt:
219 activate_window((bool)(e->modifiers & activeFlag));
220 break;
221 case keyDown:
222 case autoKey:
223 key = e->message & charCodeMask;
224 if ((e->modifiers & cmdKey) != 0) {
225 mk = MenuKey(key);
226 if (mk != 0 && handle_menu(mk))
227 break;
228 }
229 break;
230 }
231 }
232
233 void
234 handle_timer(void)
235 {
236 static long last_update = 0;
237 static long last_scan = 0;
238
239 if (!win)
240 return;
241
242 switch (da_state) {
243 case STATE_SCANNING:
244 /* check every second */
245 if ((Ticks - last_update) < (60 * 1))
246 break;
247 DEBUG_LOG(("%ld - handle_timer - checking for scan completion",
248 Ticks));
249 last_update = Ticks;
250 if (!scsi_wifi_scan_finished(wifi_scsi_id)) {
251 DEBUG_LOG(("%ld - handle_timer - scan not done", Ticks));
252 if (Time - wifi_scan_started <= 5)
253 break;
254 DEBUG_LOG(("Wi-Fi scan failed to finish, canceling"));
255 }
256 last_scan = Ticks;
257 da_state = STATE_IDLE;
258 DEBUG_LOG(("%ld - handle_timer - scan done, updating list", Ticks));
259 update_wifi_ssid_list(true);
260 break;
261 case STATE_IDLE:
262 /* refresh SSID/RSSI every 5 seconds, scan every 30 */
263 if ((Ticks - last_update) < (60 * 5))
264 break;
265 last_update = Ticks;
266
267 if ((Ticks - last_scan) > (60 * 30)) {
268 da_state = STATE_SCANNING;
269 DEBUG_LOG(("%ld - handle_timer - idle, scanning", Ticks));
270 scsi_wifi_scan(wifi_scsi_id);
271 } else {
272 DEBUG_LOG(("%ld - handle_timer - idle, updating info", Ticks));
273 update_wifi_cur_info();
274 }
275 break;
276 }
277 }
278
279 #ifdef DEBUG_LOGGING
280 void
281 logger_printf(const char *format, ...)
282 {
283 va_list va;
284
285 if (!logger)
286 return;
287
288 va_start(va, format);
289 logger_vprintf(format, va);
290 va_end(va);
291 }
292
293 void
294 logger_vprintf(const char *format, va_list ap)
295 {
296 static char buf[512];
297 GrafPtr savePort;
298 ssize_t len;
299
300 len = vsnprintf(buf, sizeof(buf), format, ap);
301
302 GetPort(&savePort);
303 SetPort(logger);
304
305 if (logger_y >= (logger->portRect.bottom - logger->portRect.top)) {
306 EraseRect(&logger->portRect);
307 logger_y = 12;
308 }
309
310 MoveTo(4, logger_y);
311 TextFont(geneva);
312 TextSize(9);
313 DrawText(buf, 0, len);
314 logger_y += 10;
315
316 ValidRect(&logger->portRect);
317 SetPort(savePort);
318 }
319 #endif