C · 7388 bytes Raw Blame History
1 // Platform wrapper - cross-platform utilities for clipboard and paths
2 // Windows uses native APIs, Unix uses shell commands/POSIX
3
4 #ifdef _WIN32
5 // Windows implementation
6 #include <windows.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <shlobj.h>
11
12 // Get temp directory path
13 void get_temp_dir_f(char* buffer, int buffer_len, int* result_len) {
14 char temp_path[MAX_PATH];
15 DWORD len = GetTempPathA(MAX_PATH, temp_path);
16
17 if (len == 0 || len > MAX_PATH) {
18 // Fallback
19 strncpy(temp_path, "C:\\Temp\\", MAX_PATH);
20 len = 8;
21 }
22
23 // Ensure it ends with backslash
24 if (temp_path[len-1] != '\\') {
25 temp_path[len] = '\\';
26 temp_path[len+1] = '\0';
27 len++;
28 }
29
30 int copy_len = (int)len < buffer_len ? (int)len : buffer_len - 1;
31 strncpy(buffer, temp_path, copy_len);
32 buffer[copy_len] = '\0';
33 *result_len = copy_len;
34 }
35
36 // Get home directory path
37 void get_home_dir_f(char* buffer, int buffer_len, int* result_len) {
38 char home_path[MAX_PATH];
39
40 // Try USERPROFILE first
41 DWORD len = GetEnvironmentVariableA("USERPROFILE", home_path, MAX_PATH);
42 if (len == 0 || len > MAX_PATH) {
43 // Try HOMEDRIVE + HOMEPATH
44 char drive[MAX_PATH], path[MAX_PATH];
45 GetEnvironmentVariableA("HOMEDRIVE", drive, MAX_PATH);
46 GetEnvironmentVariableA("HOMEPATH", path, MAX_PATH);
47 snprintf(home_path, MAX_PATH, "%s%s", drive, path);
48 len = (DWORD)strlen(home_path);
49 }
50
51 int copy_len = (int)len < buffer_len ? (int)len : buffer_len - 1;
52 strncpy(buffer, home_path, copy_len);
53 buffer[copy_len] = '\0';
54 *result_len = copy_len;
55 }
56
57 // Get path separator character
58 char get_path_separator_f(void) {
59 return '\\';
60 }
61
62 // Copy text to clipboard
63 int copy_to_clipboard_f(const char* text, int text_len) {
64 if (!text || text_len <= 0) return 0;
65
66 if (!OpenClipboard(NULL)) return 0;
67
68 EmptyClipboard();
69
70 // Allocate global memory for the text
71 HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, text_len + 1);
72 if (!hGlobal) {
73 CloseClipboard();
74 return 0;
75 }
76
77 // Copy text to global memory
78 char* pGlobal = (char*)GlobalLock(hGlobal);
79 if (!pGlobal) {
80 GlobalFree(hGlobal);
81 CloseClipboard();
82 return 0;
83 }
84
85 memcpy(pGlobal, text, text_len);
86 pGlobal[text_len] = '\0';
87 GlobalUnlock(hGlobal);
88
89 // Set clipboard data
90 if (!SetClipboardData(CF_TEXT, hGlobal)) {
91 GlobalFree(hGlobal);
92 CloseClipboard();
93 return 0;
94 }
95
96 CloseClipboard();
97 return 1;
98 }
99
100 // Paste text from clipboard
101 int paste_from_clipboard_f(char* buffer, int buffer_len, int* result_len) {
102 *result_len = 0;
103
104 if (!IsClipboardFormatAvailable(CF_TEXT)) return 0;
105 if (!OpenClipboard(NULL)) return 0;
106
107 HGLOBAL hGlobal = GetClipboardData(CF_TEXT);
108 if (!hGlobal) {
109 CloseClipboard();
110 return 0;
111 }
112
113 char* pGlobal = (char*)GlobalLock(hGlobal);
114 if (!pGlobal) {
115 CloseClipboard();
116 return 0;
117 }
118
119 int text_len = (int)strlen(pGlobal);
120 int copy_len = text_len < buffer_len - 1 ? text_len : buffer_len - 1;
121
122 memcpy(buffer, pGlobal, copy_len);
123 buffer[copy_len] = '\0';
124 *result_len = copy_len;
125
126 GlobalUnlock(hGlobal);
127 CloseClipboard();
128
129 return 1;
130 }
131
132 // Check if running on Windows
133 int is_windows_f(void) {
134 return 1;
135 }
136
137 // Get config directory (Windows: %APPDATA%)
138 void get_config_dir_f(char* buffer, int buffer_len, int* result_len) {
139 char config_path[MAX_PATH];
140
141 // Use APPDATA environment variable
142 DWORD len = GetEnvironmentVariableA("APPDATA", config_path, MAX_PATH);
143 if (len == 0 || len > MAX_PATH) {
144 // Fallback to home directory
145 get_home_dir_f(config_path, MAX_PATH, (int*)&len);
146 }
147
148 int copy_len = (int)len < buffer_len ? (int)len : buffer_len - 1;
149 strncpy(buffer, config_path, copy_len);
150 buffer[copy_len] = '\0';
151 *result_len = copy_len;
152 }
153
154 // Get current working directory
155 void get_cwd_f(char* buffer, int buffer_len, int* result_len) {
156 DWORD len = GetCurrentDirectoryA(buffer_len, buffer);
157 *result_len = (int)len;
158 }
159
160 #else
161 // Unix implementation
162 #include <stdio.h>
163 #include <stdlib.h>
164 #include <string.h>
165 #include <unistd.h>
166 #include <pwd.h>
167 #include <sys/types.h>
168
169 // Get temp directory path
170 void get_temp_dir_f(char* buffer, int buffer_len, int* result_len) {
171 const char* tmp = getenv("TMPDIR");
172 if (!tmp) tmp = getenv("TMP");
173 if (!tmp) tmp = getenv("TEMP");
174 if (!tmp) tmp = "/tmp";
175
176 int len = strlen(tmp);
177
178 // Ensure it ends with slash
179 int needs_slash = (tmp[len-1] != '/') ? 1 : 0;
180 int copy_len = len + needs_slash;
181 if (copy_len >= buffer_len) copy_len = buffer_len - 1;
182
183 int bytes_to_copy = len < buffer_len - 1 ? len : buffer_len - 1;
184 memcpy(buffer, tmp, bytes_to_copy);
185 if (needs_slash && len < buffer_len - 1) {
186 buffer[len] = '/';
187 buffer[len + 1] = '\0';
188 *result_len = len + 1;
189 } else {
190 buffer[copy_len] = '\0';
191 *result_len = copy_len;
192 }
193 }
194
195 // Get home directory path
196 void get_home_dir_f(char* buffer, int buffer_len, int* result_len) {
197 const char* home = getenv("HOME");
198 if (!home) {
199 struct passwd* pw = getpwuid(getuid());
200 if (pw) home = pw->pw_dir;
201 }
202 if (!home) home = "/tmp";
203
204 int len = strlen(home);
205 int copy_len = len < buffer_len - 1 ? len : buffer_len - 1;
206 strncpy(buffer, home, copy_len);
207 buffer[copy_len] = '\0';
208 *result_len = copy_len;
209 }
210
211 // Get path separator character
212 char get_path_separator_f(void) {
213 return '/';
214 }
215
216 // Copy text to clipboard (uses shell commands)
217 int copy_to_clipboard_f(const char* text, int text_len) {
218 // This is a fallback - the Fortran code handles this via shell commands
219 // Return 0 to indicate Fortran should handle it
220 (void)text;
221 (void)text_len;
222 return 0;
223 }
224
225 // Paste text from clipboard (uses shell commands)
226 int paste_from_clipboard_f(char* buffer, int buffer_len, int* result_len) {
227 // This is a fallback - the Fortran code handles this via shell commands
228 // Return 0 to indicate Fortran should handle it
229 (void)buffer;
230 (void)buffer_len;
231 *result_len = 0;
232 return 0;
233 }
234
235 // Check if running on Windows
236 int is_windows_f(void) {
237 return 0;
238 }
239
240 // Get config directory (Unix: ~/.config or XDG_CONFIG_HOME)
241 void get_config_dir_f(char* buffer, int buffer_len, int* result_len) {
242 const char* config = getenv("XDG_CONFIG_HOME");
243 if (config && strlen(config) > 0) {
244 int len = strlen(config);
245 int copy_len = len < buffer_len - 1 ? len : buffer_len - 1;
246 memcpy(buffer, config, copy_len);
247 buffer[copy_len] = '\0';
248 *result_len = copy_len;
249 return;
250 }
251
252 // Default to ~/.config
253 const char* home = getenv("HOME");
254 if (!home) {
255 struct passwd* pw = getpwuid(getuid());
256 if (pw) home = pw->pw_dir;
257 }
258 if (!home) home = "/tmp";
259
260 int len = snprintf(buffer, buffer_len, "%s/.config", home);
261 *result_len = len < buffer_len ? len : buffer_len - 1;
262 }
263
264 // Get current working directory
265 void get_cwd_f(char* buffer, int buffer_len, int* result_len) {
266 if (getcwd(buffer, buffer_len)) {
267 *result_len = strlen(buffer);
268 } else {
269 buffer[0] = '\0';
270 *result_len = 0;
271 }
272 }
273
274 #endif
275