AmendHub

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 }