Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
dtwin.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2016-2018 Peter Budai.
4 Copyright (C) 2020 Pascal Obry.
5 Copyright (C) 2020 U-GAMERTRON-3000\zack.
6 Copyright (C) 2022 Martin Bařinka.
7 Copyright (C) 2022 Miloš Komarčević.
8
9 darktable is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 darktable is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with darktable. If not, see <http://www.gnu.org/licenses/>.
21*/
22#include "system/macros.h"
23#include "system/mem_alloc.h"
24#include "dtwin.h"
25#include <setjmp.h>
26#include <windows.h>
27
28// Required by (at least) clang 10.0 as packaged by MSYS2 MinGW64.
29// This platform combination is needed for dt appveyor build.
30#ifdef __clang__
31#ifdef __MINGW32__ // 64-bit subsystem also sets this symbol
32#include <errno.h>
33#endif
34#endif
35
36const wchar_t *dtwin_get_locale()
37{
38 wchar_t *posix = NULL;
39 LCID lcid;
40
41 lcid = GetUserDefaultLCID();
42 int lang_id = PRIMARYLANGID(lcid);
43 int sub_id = SUBLANGID(lcid);
44
45 switch(lang_id)
46 {
47 case LANG_AFRIKAANS:
48 posix = L"af";
49 break;
50 case LANG_ARABIC:
51 posix = L"ar";
52 break;
53 case LANG_AZERI:
54 posix = L"az";
55 break;
56 case LANG_BENGALI:
57 posix = L"bn";
58 break;
59 case LANG_BULGARIAN:
60 posix = L"bg";
61 break;
62 case LANG_CATALAN:
63 posix = L"ca";
64 break;
65 case LANG_CZECH:
66 posix = L"cs";
67 break;
68 case LANG_DANISH:
69 posix = L"da";
70 break;
71 case LANG_ESTONIAN:
72 posix = L"et";
73 break;
74 case LANG_PERSIAN:
75 posix = L"fa";
76 break;
77 case LANG_GERMAN:
78 posix = L"de";
79 break;
80 case LANG_GREEK:
81 posix = L"el";
82 break;
83 case LANG_ENGLISH:
84 switch(sub_id)
85 {
86 case SUBLANG_ENGLISH_UK:
87 posix = L"en_GB";
88 break;
89 case SUBLANG_ENGLISH_AUS:
90 posix = L"en_AU";
91 break;
92 case SUBLANG_ENGLISH_CAN:
93 posix = L"en_CA";
94 break;
95 default:
96 posix = L"en";
97 break;
98 }
99 break;
100 case LANG_SPANISH:
101 posix = L"es";
102 break;
103 case LANG_BASQUE:
104 posix = L"eu";
105 break;
106 case LANG_FINNISH:
107 posix = L"fi";
108 break;
109 case LANG_FRENCH:
110 posix = L"fr";
111 break;
112 case LANG_GALICIAN:
113 posix = L"gl";
114 break;
115 case LANG_GUJARATI:
116 posix = L"gu";
117 break;
118 case LANG_HEBREW:
119 posix = L"he";
120 break;
121 case LANG_HINDI:
122 posix = L"hi";
123 break;
124 case LANG_HUNGARIAN:
125 posix = L"hu";
126 break;
127 case LANG_ICELANDIC:
128 break;
129 case LANG_INDONESIAN:
130 posix = L"id";
131 break;
132 case LANG_ITALIAN:
133 posix = L"it";
134 break;
135 case LANG_JAPANESE:
136 posix = L"ja";
137 break;
138 case LANG_GEORGIAN:
139 posix = L"ka";
140 break;
141 case LANG_KANNADA:
142 posix = L"kn";
143 break;
144 case LANG_KOREAN:
145 posix = L"ko";
146 break;
147 case LANG_LITHUANIAN:
148 posix = L"lt";
149 break;
150 case LANG_MACEDONIAN:
151 posix = L"mk";
152 break;
153 case LANG_DUTCH:
154 posix = L"nl";
155 break;
156 case LANG_NEPALI:
157 posix = L"ne";
158 break;
159 case LANG_NORWEGIAN:
160 switch(sub_id)
161 {
162 case SUBLANG_NORWEGIAN_BOKMAL:
163 posix = L"nb";
164 break;
165 case SUBLANG_NORWEGIAN_NYNORSK:
166 posix = L"nn";
167 break;
168 }
169 break;
170 case LANG_PUNJABI:
171 posix = L"pa";
172 break;
173 case LANG_POLISH:
174 posix = L"pl";
175 break;
176 case LANG_PASHTO:
177 posix = L"ps";
178 break;
179 case LANG_PORTUGUESE:
180 switch(sub_id)
181 {
182 case SUBLANG_PORTUGUESE_BRAZILIAN:
183 posix = L"pt_BR";
184 break;
185 default:
186 posix = L"pt";
187 break;
188 }
189 break;
190 case LANG_ROMANIAN:
191 posix = L"ro";
192 break;
193 case LANG_RUSSIAN:
194 posix = L"ru";
195 break;
196 case LANG_SLOVAK:
197 posix = L"sk";
198 break;
199 case LANG_SLOVENIAN:
200 posix = L"sl";
201 break;
202 case LANG_ALBANIAN:
203 posix = L"sq";
204 break;
205 /* LANG_CROATIAN == LANG_SERBIAN == LANG_BOSNIAN */
206 case LANG_SERBIAN:
207 switch(sub_id)
208 {
209 case SUBLANG_SERBIAN_LATIN:
210 posix = L"sr@Latn";
211 break;
212 case SUBLANG_SERBIAN_CYRILLIC:
213 posix = L"sr";
214 break;
215 case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC:
216 case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN:
217 posix = L"bs";
218 break;
219 case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN:
220 posix = L"hr";
221 break;
222 }
223 break;
224 case LANG_SWEDISH:
225 posix = L"sv";
226 break;
227 case LANG_TAMIL:
228 posix = L"ta";
229 break;
230 case LANG_TELUGU:
231 posix = L"te";
232 break;
233 case LANG_THAI:
234 posix = L"th";
235 break;
236 case LANG_TURKISH:
237 posix = L"tr";
238 break;
239 case LANG_UKRAINIAN:
240 posix = L"uk";
241 break;
242 case LANG_VIETNAMESE:
243 posix = L"vi";
244 break;
245 case LANG_XHOSA:
246 posix = L"xh";
247 break;
248 case LANG_CHINESE:
249 switch(sub_id)
250 {
251 case SUBLANG_CHINESE_SIMPLIFIED:
252 posix = L"zh_CN";
253 break;
254 case SUBLANG_CHINESE_TRADITIONAL:
255 posix = L"zh_TW";
256 break;
257 default:
258 posix = L"zh";
259 break;
260 }
261 break;
262 case LANG_URDU:
263 break;
264 case LANG_BELARUSIAN:
265 break;
266 case LANG_LATVIAN:
267 break;
268 case LANG_ARMENIAN:
269 break;
270 case LANG_FAEROESE:
271 break;
272 case LANG_MALAY:
273 break;
274 case LANG_KAZAK:
275 break;
276 case LANG_KYRGYZ:
277 break;
278 case LANG_SWAHILI:
279 break;
280 case LANG_UZBEK:
281 break;
282 case LANG_TATAR:
283 break;
284 case LANG_ORIYA:
285 break;
286 case LANG_MALAYALAM:
287 break;
288 case LANG_ASSAMESE:
289 break;
290 case LANG_MARATHI:
291 break;
292 case LANG_SANSKRIT:
293 break;
294 case LANG_MONGOLIAN:
295 break;
296 case LANG_KONKANI:
297 break;
298 case LANG_MANIPURI:
299 break;
300 case LANG_SINDHI:
301 break;
302 case LANG_SYRIAC:
303 break;
304 case LANG_KASHMIRI:
305 break;
306 case LANG_DIVEHI:
307 break;
308 }
309
310 /* Deal with exceptions */
311 if(IS_NULL_PTR(posix))
312 {
313 switch(lcid)
314 {
315 case 0x0455:
316 posix = L"my_MM";
317 break; /* Myanmar (Burmese) */
318 case 9999:
319 posix = L"ku";
320 break; /* Kurdish (from NSIS) */
321 default:
322 posix = L"en";
323 }
324 }
325
326 return posix;
327}
328
329typedef struct tagTHREADNAME_INFO
330{
331 DWORD dwType; // must be 0x1000
332 LPCSTR szName; // pointer to name (in user addr space)
333 DWORD dwThreadID; // thread ID (-1=caller thread)
334 DWORD dwFlags; // reserved for future use, must be zero
336
337const DWORD MS_VC_EXCEPTION = 0x406D1388;
338
339void dtwin_set_thread_name(DWORD dwThreadID, const char *threadName)
340{
341 THREADNAME_INFO info;
342 info.dwType = 0x1000;
343 info.szName = threadName;
344 info.dwThreadID = dwThreadID;
345 info.dwFlags = 0;
346
347 // Yes, don't get heart attack, naming of thread is done by raising a special exception on Windows
348 // https://msdn.microsoft.com/en-us/library/xcb2z8hs(v=vs.71).aspx
349 RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (const ULONG_PTR *)&info);
350}
351
352// This is taken from: https://git.gnome.org/browse/glib/tree/gio/glocalfile.c#n2269
353// The glib version of this function unfortunately shows always confirmation dialog boxes
354// This version does thrashing silently, without dialog boxes: FOF_SILENT | FOF_NOCONFIRMATION
355// When glib version on Windows will do silent trashing we can remove this function
356boolean dt_win_file_trash(GFile *file, GCancellable *cancellable, GError **error)
357{
358 SHFILEOPSTRUCTW op = { 0 };
359 gboolean success;
360 wchar_t *wfilename;
361 long len;
362
363 wfilename = g_utf8_to_utf16(g_file_get_parse_name(file), -1, NULL, &len, NULL);
364 /* SHFILEOPSTRUCT.pFrom is double-zero-terminated */
365 wfilename = g_renew(wchar_t, wfilename, len + 2);
366 wfilename[len + 1] = 0;
367
368 op.wFunc = FO_DELETE;
369 op.pFrom = wfilename;
370 op.fFlags = FOF_ALLOWUNDO | FOF_SILENT | FOF_NOCONFIRMATION;
371
372 success = SHFileOperationW(&op) == 0;
373
374 if(success && op.fAnyOperationsAborted)
375 {
376 if(cancellable && !g_cancellable_is_cancelled(cancellable)) g_cancellable_cancel(cancellable);
377 g_set_error(error, G_IO_ERROR, g_io_error_from_errno(ECANCELED), "Unable to trash file %s: %s",
378 g_file_get_parse_name(file), g_strerror(ECANCELED));
379 success = FALSE;
380 }
381 else if(!success)
382 g_set_error(error, G_IO_ERROR, g_io_error_from_errno(0), "Unable to trash file %s",
383 g_file_get_parse_name(file));
384
385 dt_free(wfilename);
386 return success;
387}
388// clang-format off
389// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
390// vim: shiftwidth=2 expandtab tabstop=2 cindent
391// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
392// clang-format on
393
static void error(char *msg)
Definition ashift_lsd.c:202
#define FALSE
Definition ashift_lsd.c:158
boolean dt_win_file_trash(GFile *file, GCancellable *cancellable, GError **error)
Definition dtwin.c:356
const DWORD MS_VC_EXCEPTION
Definition dtwin.c:337
struct tagTHREADNAME_INFO THREADNAME_INFO
void dtwin_set_thread_name(DWORD dwThreadID, const char *threadName)
Definition dtwin.c:339
const wchar_t * dtwin_get_locale()
Definition dtwin.c:36
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:96
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
Definition mem_alloc.h:171