7
|
1 /**
|
|
2 * config.c:
|
|
3 *
|
|
4 * Functions to load/save/edit the config.
|
|
5 **/
|
|
6
|
|
7 /**
|
|
8 * example config:
|
|
9 *
|
|
10 * ----- wgsdk config ----
|
|
11 * display_title=1
|
|
12 * show_elapsed_time=1
|
|
13 **/
|
10
|
14 #include "dirtools.h"
|
|
15 #include "config.h"
|
|
16 #include "resource.h"
|
|
17 #include "utils.h"
|
|
18
|
|
19 #include <shlobj.h>
|
|
20 #include <shlwapi.h>
|
|
21
|
0
|
22 #include <assert.h>
|
|
23 #include <stdio.h>
|
|
24 #include <stdlib.h>
|
|
25 #include <string.h>
|
10
|
26
|
|
27 #define MAX_LINE_LENGTH 256
|
0
|
28
|
7
|
29 /* from main */
|
|
30 extern void update_rich_presence_details(void);
|
|
31 extern struct config config;
|
0
|
32
|
10
|
33 /* must be free'd by the caller */
|
|
34 LPWSTR cfg_get_path() {
|
|
35 /* get location of appdata folder */
|
|
36 LPWSTR appdata_folder;
|
|
37 SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &appdata_folder);
|
|
38
|
|
39 /* compatibility with WACUP, falls back to Winamp */
|
|
40 WCHAR exe_name[MAX_PATH] = {L'\0'};
|
|
41 if (GetModuleFileNameW(NULL, (LPWSTR)&exe_name, MAX_PATH)) {
|
|
42 PathStripPathW(exe_name);
|
|
43 PathRemoveExtensionW(exe_name);
|
|
44 } else { // fail
|
|
45 memset(exe_name, '\0', MAX_PATH * sizeof(WCHAR));
|
|
46 wcscpy(exe_name, L"Winamp");
|
|
47 }
|
|
48
|
|
49 /* concat until we get the final path */
|
|
50 LPWSTR path = dirtools_concat_paths(appdata_folder, exe_name);
|
|
51 CoTaskMemFree(appdata_folder);
|
|
52
|
|
53 LPWSTR final = dirtools_concat_paths(path, L"Plugins\\wgsdk");
|
|
54 free(path);
|
|
55
|
|
56 return final;
|
|
57 }
|
|
58
|
9
|
59 int cfg_load(struct config* restrict config) {
|
10
|
60 LPWSTR fold_path = cfg_get_path();
|
|
61 LPWSTR path = dirtools_concat_paths(fold_path, L"config.txt");
|
|
62 free(fold_path);
|
|
63
|
|
64 /* find some real win32 replacement for this */
|
|
65 FILE* config_fp = _wfopen(path, L"r");
|
0
|
66 if (config_fp == NULL) {
|
|
67 free(path);
|
|
68 return 1;
|
|
69 }
|
10
|
70
|
7
|
71 /* parse the config */
|
10
|
72 char line[MAX_LINE_LENGTH] = {0};
|
0
|
73 while (fgets(line, MAX_LINE_LENGTH, config_fp)) {
|
10
|
74 /* strtok is okay here. */
|
0
|
75 switch (crc32b((unsigned char*)strtok(line, "="))) {
|
|
76 case 0x2a666380: // display_title
|
1
|
77 config->display_title = !!atoi(strtok(NULL, "="));
|
0
|
78 break;
|
|
79 case 0xbb631f7f: // show_elapsed_time
|
1
|
80 config->show_elapsed_time = !!atoi(strtok(NULL, "="));
|
0
|
81 break;
|
|
82 default:
|
|
83 break;
|
|
84 }
|
|
85 }
|
10
|
86
|
0
|
87 free(path);
|
|
88 return 0;
|
|
89 }
|
|
90
|
4
|
91 int cfg_save(struct config config) {
|
10
|
92 LPWSTR fold_path = cfg_get_path();
|
|
93 assert(!dirtools_create_directory(fold_path));
|
|
94
|
|
95 LPWSTR path = dirtools_concat_paths(fold_path, L"config.txt");
|
|
96 free(fold_path);
|
7
|
97
|
10
|
98 FILE* config_fp = _wfopen(path, L"w");
|
|
99 if (config_fp == NULL) {
|
|
100 free(path);
|
0
|
101 return 1;
|
10
|
102 }
|
|
103
|
1
|
104 fprintf(config_fp, "----- wgsdk config ----\n");
|
7
|
105 fprintf(config_fp, "display_title=%d\n", config.display_title);
|
0
|
106 fprintf(config_fp, "show_elapsed_time=%d\n", config.show_elapsed_time);
|
|
107 fclose(config_fp);
|
10
|
108 free(path);
|
0
|
109 return 0;
|
|
110 }
|
1
|
111
|
|
112 /* --------------------------------- */
|
|
113
|
10
|
114 #define conf_item_to_dlg(hwnd, cons, var) \
|
|
115 { \
|
|
116 HWND checkboxHwnd = GetDlgItem(hwnd, cons); \
|
|
117 SendMessage(checkboxHwnd, BM_SETCHECK, (var) ? BST_CHECKED : BST_UNCHECKED, 0); \
|
|
118 }
|
|
119 #define dlg_item_to_conf(hwnd, cons, var) \
|
|
120 { \
|
|
121 HWND checkboxHwnd = GetDlgItem(hwnd, cons); \
|
|
122 (var) = (SendMessage(checkboxHwnd, BM_GETCHECK, 0, 0) == BST_CHECKED); \
|
|
123 }
|
7
|
124 void cfg_get_controls(HWND hWnd) {
|
10
|
125 dlg_item_to_conf(hWnd, TITLE_CHECK, config.display_title);
|
|
126 dlg_item_to_conf(hWnd, ELAPSED_TIME_CHECK, config.show_elapsed_time);
|
1
|
127 }
|
|
128
|
|
129 void cfg_set_controls(HWND hWnd) {
|
10
|
130 conf_item_to_dlg(hWnd, TITLE_CHECK, config.display_title);
|
|
131 conf_item_to_dlg(hWnd, ELAPSED_TIME_CHECK, config.show_elapsed_time);
|
7
|
132 }
|
|
133 #undef conf_item_to_dlg
|
|
134 #undef dlg_item_to_conf
|
|
135
|
|
136 void cfg_on_confirm_settings_dialog(HWND hWnd) {
|
|
137 cfg_get_controls(hWnd);
|
|
138 cfg_save(config);
|
|
139 update_rich_presence_details();
|
1
|
140 }
|
|
141
|
|
142 BOOL CALLBACK cfg_win_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|
143 switch (msg) {
|
7
|
144 case WM_INITDIALOG:
|
|
145 /* do nothing if this is a child window (tab page) callback, pass to the parent */
|
1
|
146 if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
|
|
147 return FALSE;
|
|
148 cfg_set_controls(hWnd);
|
|
149 return TRUE;
|
|
150 case WM_COMMAND:
|
|
151 switch (LOWORD(wParam)) {
|
7
|
152 case IDOK:
|
1
|
153 cfg_on_confirm_settings_dialog(hWnd);
|
|
154 EndDialog(hWnd, 0);
|
|
155 return TRUE;
|
7
|
156 case IDCANCEL:
|
1
|
157 EndDialog(hWnd, 0);
|
|
158 return TRUE;
|
|
159 }
|
|
160 }
|
|
161
|
7
|
162 return FALSE;
|
1
|
163 }
|