Download
cyberslak
/lightsout
/preferences.c
(View History)
cyberslak code cleanup | Latest amendment: 23 on 2025-03-17 |
1 | // SPDX-License-Identifier: MIT |
2 | |
3 | #include <stdlib.h> |
4 | #include <unistd.h> |
5 | #include <string.h> |
6 | #include <stdio.h> |
7 | #include "preferences.h" |
8 | #include "util.h" |
9 | #include "dbuf.h" |
10 | #include "entity.h" |
11 | |
12 | extern PrefHandle gPreferences; |
13 | |
14 | static short preferences_get_fsspec(FSSpec* out) |
15 | { |
16 | short ret = 0; |
17 | char pathBuf[256]; |
18 | short len; |
19 | OSErr err; |
20 | |
21 | getcwd(pathBuf, 256); |
22 | c2pstr(pathBuf); |
23 | |
24 | len = pathBuf[0]; |
25 | len += strlcpy(pathBuf + len + 1, kPreferencesFile, 255 - len); |
26 | if (len > 255) |
27 | die("preferences path too long!"); |
28 | |
29 | pathBuf[0] = len; |
30 | err = FSMakeFSSpec(0, 0, (const u8*)pathBuf, out); |
31 | |
32 | if (!(err == noErr || err == -43 /* file not found */)) |
33 | die("Error during FSMakeFSSpec: %hd", err); |
34 | |
35 | return 0; |
36 | } |
37 | |
38 | /* Generate a new, empty preferences resource. */ |
39 | static Handle preferences_new() |
40 | { |
41 | PrefHandle hnd = (PrefHandle)NewHandle(sizeof(**hnd)); |
42 | if (!hnd) die("out of memory"); |
43 | HLock((Handle)hnd); |
44 | |
45 | (**gPreferences).server_name[0] = 0; |
46 | (**gPreferences).token[0] = 0; |
47 | (**gPreferences).port = 0; |
48 | |
49 | HUnlock((Handle)hnd); |
50 | return (Handle)hnd; |
51 | } |
52 | |
53 | PrefHandle preferences_load() |
54 | { |
55 | Handle prefHandle; |
56 | FSSpec spec; |
57 | OSErr err; |
58 | short refNum; |
59 | |
60 | if (preferences_get_fsspec(&spec) < 0) |
61 | return NULL; |
62 | |
63 | open: |
64 | refNum = FSpOpenResFile(&spec, fsRdWrPerm); |
65 | |
66 | if (refNum < 0) |
67 | { |
68 | // attempt to create a new resource file |
69 | FSpCreateResFile(&spec, 'LitO', 'pref', smRoman); |
70 | err = ResError(); |
71 | if (err != 0) |
72 | die("error while creating resource file: %d", err); |
73 | goto open; |
74 | } |
75 | |
76 | prefHandle = Get1Resource('PREF', kPrefsId); |
77 | |
78 | if (!prefHandle) |
79 | { |
80 | prefHandle = preferences_new(); |
81 | AddResource(prefHandle, 'PREF', kPrefsId, "\pPreferences"); |
82 | UpdateResFile(refNum); |
83 | // todo error handling here |
84 | } |
85 | |
86 | return (PrefHandle)prefHandle; |
87 | } |
88 | |
89 | short preferences_save(PrefHandle prefs) |
90 | { |
91 | short refNum = CurResFile(); |
92 | ChangedResource((Handle)prefs); |
93 | UpdateResFile(refNum); |
94 | return ResError(); |
95 | } |
96 | |
97 | short preferences_dialog() |
98 | { |
99 | DialogPtr dlog; |
100 | GrafPtr oldPort; |
101 | bool dialogDone = false; |
102 | short itemHit; |
103 | Handle addrHnd, portHnd, tokHnd, save, cancel; |
104 | short addrType, portType, tokType, saveType, cancelType; |
105 | short ret = 0; |
106 | unsigned char portBuf[256]; |
107 | |
108 | dlog = GetNewDialog(kPreferencesDialogId, nil, (WindowPtr)-1); |
109 | |
110 | GetDialogItem(dlog, 1, &saveType, &save, nil); |
111 | GetDialogItem(dlog, 2, &cancelType, &cancel, nil); |
112 | GetDialogItem(dlog, 5, &addrType, &addrHnd, nil); |
113 | GetDialogItem(dlog, 7, &portType, &portHnd, nil); |
114 | GetDialogItem(dlog, 9, &tokType, &tokHnd, nil); |
115 | |
116 | SetDialogDefaultItem(dlog, 1); |
117 | SetDialogCancelItem(dlog, 2); |
118 | SetDialogTracksCursor(dlog, true); |
119 | |
120 | ShowWindow(dlog); |
121 | GetPort(&oldPort); |
122 | SetPort(dlog); |
123 | |
124 | while (!dialogDone) |
125 | { |
126 | ModalDialog(nil, &itemHit); |
127 | switch (itemHit) |
128 | { |
129 | case 1: |
130 | dialogDone = true; |
131 | break; |
132 | case 2: // cancel |
133 | ret = -1; |
134 | goto fail; |
135 | break; |
136 | } |
137 | } |
138 | |
139 | HLock((Handle)gPreferences); |
140 | |
141 | GetDialogItemText(addrHnd, (u8*)(**gPreferences).server_name); |
142 | GetDialogItemText(tokHnd, (u8*)(**gPreferences).token); |
143 | GetDialogItemText(portHnd, portBuf); |
144 | p2cstr((u8*)(**gPreferences).server_name); |
145 | p2cstr((u8*)(**gPreferences).token); |
146 | |
147 | if (sscanf(p2cstr(portBuf), "%hu", &(**gPreferences).port) != 1) |
148 | { |
149 | ret = -1; |
150 | } |
151 | |
152 | HUnlock((Handle)gPreferences); |
153 | |
154 | fail: |
155 | DisposeDialog(dlog); |
156 | |
157 | SetPort(oldPort); |
158 | return ret; |
159 | } |
160 | |
161 | short |
162 | preferences_save_entities(list_t *entities) |
163 | { |
164 | DB_INIT(entBuf, 1024); |
165 | list_t *node; |
166 | struct entity *ent; |
167 | Handle entHandle, curHandle; |
168 | short refNum = CurResFile(); |
169 | |
170 | list_foreach(entities, node) |
171 | { |
172 | ent = container_of(node, struct entity, node); |
173 | db_printf(&entBuf, "%s", ent->id); |
174 | entBuf.len += 1; // skip null terminator |
175 | } |
176 | |
177 | entHandle = NewHandle(entBuf.len); |
178 | if (!entHandle) |
179 | die("Unable to save currently active entities"); |
180 | |
181 | HLock(entHandle); |
182 | memcpy(*entHandle, entBuf.buf, entBuf.len); |
183 | HUnlock(entHandle); |
184 | |
185 | db_destroy(&entBuf); |
186 | |
187 | SetResLoad(false); |
188 | |
189 | if ((curHandle = GetResource('ENTR', kEntsId)) != nil) |
190 | RemoveResource(curHandle); |
191 | |
192 | SetResLoad(true); |
193 | AddResource(entHandle, 'ENTR', kEntsId, "\pSaved entries"); |
194 | |
195 | UpdateResFile(refNum); |
196 | |
197 | return ResError(); |
198 | } |
199 | |
200 | Handle preferences_get_entities() |
201 | { |
202 | Handle hnd = GetResource('ENTR', kEntsId); |
203 | return hnd; |
204 | } |