AmendHub

Download

jcs

/

wifi_da

/

main.c

 

(View History)

jcs   *: Don't rely on our static wifi_da persisting Latest amendment: 40 on 2025-01-07

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