1 // machinestate.h
2 // (c) G. Finch 2019 - 2020 <salsaman+lives@gmail.com>
3 // released under the GNU GPL 3 or later
4 // see file ../COPYING for licensing details
5
6 // functions for dealing with externalities
7
8 /// TODO - split into: memory, files, sysops, threads
9
10 #ifndef _MACHINESTATE_H_
11 #define _MACHINESTATE_H_
12
13 #include <sys/time.h>
14 #include <time.h>
15
16 #define EXTRA_BYTES DEF_ALIGN
17
18 typedef void *(*malloc_f)(size_t);
19 typedef void (*free_f)(void *);
20 typedef void *(*free_and_return_f)(void *); // like free() but returns NULL
21 typedef void *(*memcpy_f)(void *, const void *, size_t);
22 typedef int (*memcmp_f)(const void *, const void *, size_t);
23 typedef void *(*memset_f)(void *, int, size_t);
24 typedef void *(*memmove_f)(void *, const void *, size_t);
25 typedef void *(*realloc_f)(void *, size_t);
26 typedef void *(*calloc_f)(size_t, size_t);
27 typedef void *(*malloc_and_copy_f)(size_t, const void *);
28 typedef void (*unmalloc_and_copy_f)(size_t, void *);
29
30 #define USE_RPMALLOC
31
32 #ifdef USE_RPMALLOC
33 #include "rpmalloc.h"
34 #endif
35
36 boolean init_memfuncs(void);
37
38 void lives_free_check(void *p);
39
40 #ifdef USE_RPMALLOC
41 void *quick_calloc(size_t n, size_t s);
42 void quick_free(void *p);
43 #endif
44
45 #ifndef lives_malloc
46 #define lives_malloc malloc
47 #endif
48 #ifndef lives_realloc
49 #define lives_realloc realloc
50 #endif
51 #ifndef lives_free
52 #define lives_free free
53 #endif
54 #ifndef lives_memcpy
55 #define lives_memcpy memcpy
56 #endif
57 #ifndef lives_memcmp
58 #define lives_memcmp memcmp
59 #endif
60 #ifndef lives_memset
61 #define lives_memset memset
62 #endif
63 #ifndef lives_memmove
64 #define lives_memmove memmove
65 #endif
66 #ifndef lives_calloc
67 #define lives_calloc calloc
68 #endif
69
70 #ifdef _lives_malloc
71 #undef _lives_malloc
72 #endif
73 #ifdef _lives_malloc_and_copy
74 #undef _lives_malloc_and_copy
75 #endif
76 #ifdef _lives_realloc
77 #undef _lives_realloc
78 #endif
79 #ifdef _lives_free
80 #undef _lives_free
81 #endif
82 #ifdef _lives_memcpy
83 #undef _lives_memcpy
84 #endif
85 #ifdef _lives_memcmp
86 #undef _lives_memcmp
87 #endif
88 #ifdef _lives_memset
89 #undef _lives_memset
90 #endif
91 #ifdef _lives_memmove
92 #undef _lives_memmove
93 #endif
94 #ifdef _lives_calloc
95 #undef _lives_calloc
96 #endif
97
98 #ifndef USE_STD_MEMFUNCS
99 // here we can define optimised mem ory functions to used by setting the symbols _lives_malloc, _lives_free, etc.
100 // at the end of the header we check if the values have been set and update lives_malloc from _lives_malloc, etc.
101 // the same values are passed into realtime fx plugins via Weed function overloading
102 #if defined (HAVE_OPENCV) || defined (HAVE_OPENCV4)
103 #ifndef NO_OPENCV_MEMFUNCS
104 #define _lives_malloc(sz) alignPtr(sz, DEF_ALIGN);
105 #define _lives_free fastFree
106 #define _lives_realloc proxy_realloc
107 #endif
108 #endif
109
110 #ifndef __cplusplus
111
112 #ifdef ENABLE_ORC
113 #ifndef NO_ORC_MEMFUNCS
114 #define _lives_memcpy lives_orc_memcpy
115 #endif
116 #endif
117
118 #else
119
120 #ifdef ENABLE_OIL
121 #ifndef NO_OIL_MEMFUNCS
122 #define _lives_memcpy(dest, src, n) {if (n >= 32 && n <= OIL_MEMCPY_MAX_BYTES) { \
123 oil_memcpy((uint8_t *)dest, (const uint8_t *)src, n); \
124 return dest;\ \
125 }
126 #endif
127 #endif
128
129 #endif // __cplusplus
130 #endif // USE_STD_MEMFUNCS
131
132 #define __STDC_FORMAT_MACROS
133 #include <inttypes.h>
134
135 #undef PRId64
136 #undef PRIu64
137
138 #ifdef IS_MINGW
139 #define LONGSIZE 32
140 #else
141
142 #ifdef __WORDSIZE
143 #define LONGSIZE __WORDSIZE
144 #else
145 #if defined __x86_64__
146 # define LONGSIZE 64
147 #ifndef __WORDSIZE_COMPAT32
148 # define __WORDSIZE_COMPAT32 1
149 #endif
150 #else
151 # define LONGSIZE 32
152 #endif // x86
153 #endif // __WORDSIZE
154 #endif // mingw
155
156 #ifdef __PRI64_PREFIX
157 #undef __PRI64_PREFIX
158 #endif
159
160 # if LONGSIZE == 64
161 # define __PRI64_PREFIX "l"
162 # else
163 # define __PRI64_PREFIX "ll"
164 # endif
165
166 #undef PRId64
167 #undef PRIu64
168
169 # define PRId64 __PRI64_PREFIX "d"
170 # define PRIu64 __PRI64_PREFIX "u"
171
172 /// TODO: this file should be split into at least: memory functions, thread functions, file utils
173
174 void *lives_free_and_return(void *p);
175 void *lives_calloc_safety(size_t nmemb, size_t xsize) GNU_ALIGNED(DEF_ALIGN);
176 void *lives_recalloc(void *p, size_t nmemb, size_t omemb, size_t xsize) GNU_ALIGNED(DEF_ALIGN);
177
178 size_t get_max_align(size_t req_size, size_t align_max);
179
180 /// disk/storage status values
181 typedef enum {
182 LIVES_STORAGE_STATUS_UNKNOWN = 0,
183 LIVES_STORAGE_STATUS_NORMAL,
184 LIVES_STORAGE_STATUS_WARNING,
185 LIVES_STORAGE_STATUS_CRITICAL,
186 LIVES_STORAGE_STATUS_OVERFLOW,
187 LIVES_STORAGE_STATUS_OVER_QUOTA,
188 LIVES_STORAGE_STATUS_OFFLINE
189 } lives_storage_status_t;
190
191 //void shoatend(void);
192
193 #define WEED_LEAF_MD5SUM "md5sum"
194
195 // weed plants with type >= 16384 are reserved for custom use, so let's take advantage of that
196 #define WEED_PLANT_LIVES 31337
197
198 #define WEED_LEAF_LIVES_SUBTYPE "subtype"
199 #define WEED_LEAF_LIVES_MESSAGE_STRING "message_string"
200
201 #define LIVES_WEED_SUBTYPE_MESSAGE 1
202 #define LIVES_WEED_SUBTYPE_WIDGET 2
203 #define LIVES_WEED_SUBTYPE_TUNABLE 3
204 #define LIVES_WEED_SUBTYPE_PROC_THREAD 4
205
206 typedef weed_plantptr_t lives_proc_thread_t;
207
208 weed_plant_t *lives_plant_new(int subtype);
209 weed_plant_t *lives_plant_new_with_index(int subtype, int64_t index);
210
211 void *_ext_malloc(size_t n) GNU_MALLOC;
212 void *_ext_malloc_and_copy(size_t, const void *) GNU_MALLOC_SIZE(1);
213 void _ext_unmalloc_and_copy(size_t, void *);
214 void _ext_free(void *);
215 void *_ext_free_and_return(void *);
216 void *_ext_memcpy(void *, const void *, size_t);
217 void *_ext_memset(void *, int, size_t);
218 void *_ext_memmove(void *, const void *, size_t);
219 void *_ext_realloc(void *, size_t) GNU_MALLOC_SIZE(2);
220 void *_ext_calloc(size_t, size_t) GNU_MALLOC_SIZE2(1, 2) GNU_ALIGN(2);
221
222 #define OVERRIDE_MEMFUNCS
223 static void *(*_lsd_memcpy)(void *dest, const void *src, size_t n) = _ext_memcpy;
224 static void *(*_lsd_memset)(void *s, int c, size_t n) = _ext_memset;
225 static void (*_lsd_free)(void *ptr) = rpfree;
226 #define OVERRIDE_CALLOC_ALIGNED
_lsd_calloc_aligned_(void ** memptr,size_t nmemb,size_t size)227 static int _lsd_calloc_aligned_(void **memptr, size_t nmemb, size_t size) {
228 return !memptr ? 0 : (!(*memptr = (rpaligned_calloc)(64, nmemb, size))) ? ENOMEM : 0;
229 }
230
231 void lives_get_randbytes(void *ptr, size_t size);
232
233 #if !HAVE_GETENTROPY
234 #define LSD_RANDFUNC(ptr, size) (lives_get_randbytes((ptr), (size)))
235 #endif
236
237 #include "lsd.h"
238 #undef OVERRIDE_MEMFUNCS
239
240 #ifdef __GNUC__
241 #define LIVES_GNU
242 #define lives_malloc_auto(size) __builtin_alloc(size)
243 #define lives_malloc_auto_aligned(size, align) __builtin_alloc_with_align(size, align)
244 #endif
245
246 size_t lives_strlen(const char *) GNU_HOT GNU_PURE;
247 boolean lives_strcmp(const char *, const char *) GNU_HOT GNU_PURE;
248 boolean lives_strncmp(const char *, const char *, size_t) GNU_HOT GNU_PURE;
249 char *lives_strdup_quick(const char *s);
250 int lives_strcmp_ordered(const char *, const char *) GNU_HOT GNU_PURE;
251 char *lives_concat(char *, char *) GNU_HOT;
252 char *lives_concat_sep(char *st, const char *sep, char *x);
253 char *lives_strstop(char *, const char term) GNU_HOT;
254 int lives_strappend(const char *string, int len, const char *xnew);
255 const char *lives_strappendf(const char *string, int len, const char *fmt, ...);
256
257 void swab2(const void *from, const void *to, size_t granularity) GNU_HOT;
258 void swab4(const void *from, const void *to, size_t granularity) GNU_HOT;
259 void swab8(const void *from, const void *to, size_t granularity) GNU_HOT;
260 void reverse_bytes(char *buff, size_t count, size_t granularity) GNU_HOT GNU_FLATTEN;
261 boolean reverse_buffer(uint8_t *buff, size_t count, size_t chunk) GNU_HOT;
262
263 uint64_t nxtval(uint64_t val, uint64_t lim, boolean less);
264 uint64_t autotune_u64_end(weed_plant_t **tuner, uint64_t val);
265 void autotune_u64(weed_plant_t *tuner, uint64_t min, uint64_t max, int ntrials, double cost);
266
267 void init_random(void);
268 void lives_srandom(unsigned int seed);
269 uint64_t lives_random(void);
270
271 uint64_t fastrand(void) GNU_HOT;
272 void fastrand_add(uint64_t entropy);
273 double fastrand_dbl(double range);
274 uint32_t fastrand_int(uint32_t range);
275
276 uint64_t gen_unique_id(void);
277
278 #ifdef ENABLE_ORC
279 void *lives_orc_memcpy(void *dest, const void *src, size_t n);
280 #endif
281
282 #ifdef ENABLE_OIL
283 void *lives_oil_memcpy(void *dest, const void *src, size_t n);
284 #endif
285
286 void *proxy_realloc(void *ptr, size_t new_size);
287
288 char *get_md5sum(const char *filename);
289
290 char *lives_format_storage_space_string(uint64_t space);
291 lives_storage_status_t get_storage_status(const char *dir, uint64_t warn_level, int64_t *dsval, int64_t resvd);
292 uint64_t get_ds_free(const char *dir);
293
294 lives_proc_thread_t disk_monitor_start(const char *dir);
295 boolean disk_monitor_running(const char *dir);
296 int64_t disk_monitor_check_result(const char *dir);
297 int64_t disk_monitor_wait_result(const char *dir, ticks_t timeout);
298 void disk_monitor_forget(void);
299
300 char *get_mountpoint_for(const char *dir);
301
302 ticks_t lives_get_relative_ticks(ticks_t origsecs, ticks_t orignsecs);
303 ticks_t lives_get_current_ticks(void);
304 char *lives_datetime(uint64_t secs, boolean use_local);
305 char *lives_datetime_rel(const char *datetime);
306
307 #define lives_nanosleep(nanosec) {struct timespec ts; ts.tv_sec = (uint64_t)nanosec / ONE_BILLION; \
308 ts.tv_nsec = (uint64_t)nanosec - ts.tv_sec * ONE_BILLION; while (nanosleep(&ts, &ts) == -1 && \
309 errno != ETIMEDOUT);}
310 #define lives_nanosleep_until_nonzero(condition) {while (!(condition)) lives_nanosleep(1000);}
311
312 int check_dev_busy(char *devstr);
313
314 off_t get_file_size(int fd);
315 off_t sget_file_size(const char *name);
316
317 void reget_afilesize(int fileno);
318 off_t reget_afilesize_inner(int fileno);
319
320 off_t get_dir_size(const char *dirname);
321
322 boolean compress_files_in_dir(const char *dir, int method, void *data);
323 LiVESResponseType send_to_trash(const char *item);
324
325 /// extras we can check for, may consume more time
326 #define EXTRA_DETAILS_CHECK_MISSING (1ul << 0)
327 #define EXTRA_DETAILS_DIRSIZE (1ul << 1)
328 #define EXTRA_DETAILS_EMPTY_DIRS (1ul << 2)
329 #define EXTRA_DETAILS_SYMLINK (1ul << 3)
330 #define EXTRA_DETAILS_ACCESSIBLE (1ul << 4)
331 #define EXTRA_DETAILS_WRITEABLE (1ul << 5)
332 #define EXTRA_DETAILS_EXECUTABLE (1ul << 6)
333 #define EXTRA_DETAILS_CLIPHDR (1ul << 7)
334
335 /// derived values
336 #define EXTRA_DETAILS_MD5SUM (1ul << 33)
337
338 typedef struct {
339 ///< if we can retrieve some kind of uinque id, we set it here
340 ///< may be useful in future for dictionary lookups
341 uint64_t uniq;
342 lives_struct_def_t *lsd;
343 char *name;
344 uint64_t type; /// e.g. LIVES_FILE_TYPE_FILE
345 off_t size; // -1 not checked, -2 unreadable
346 uint64_t mode;
347 uint64_t uid; /// userid as uint64_t
348 uint64_t gid;
349 uint64_t blk_size;
350 uint64_t atime_sec;
351 uint64_t atime_nsec;
352 uint64_t mtime_sec;
353 uint64_t mtime_nsec;
354 uint64_t ctime_sec;
355 uint64_t ctime_nsec;
356 char *md5sum; /// only filled if EXTRA_DETAILS_MD5 is set, otherwis NULL
357 char *extra_details; /// intialized to NULL, set to at least ""
358 LiVESWidget *widgets[16]; ///< caller set widgets for presentation, e.g. labels, spinners. final entry must be followed by NULL
359 } lives_file_dets_t;
360
361 #ifdef PRODUCE_LOG
362 // disabled by default
363 void lives_log(const char *what);
364 #endif
365
366 uint32_t lives_string_hash(const char *string) GNU_PURE GNU_HOT;
367 uint32_t fast_hash(const char *key) GNU_PURE GNU_HOT;
368 char *lives_chomp(char *string);
369 char *lives_strtrim(const char *buff);
370
371 int check_for_bad_ffmpeg(void);
372
373 void update_effort(int nthings, boolean badthings);
374 void reset_effort(void);
375
376 //// threadpool API
377
378 typedef void *(*lives_funcptr_t)(void *);
379
380 typedef struct _lives_thread_data_t lives_thread_data_t;
381
382 typedef struct {
383 lives_proc_thread_t var_tinfo;
384 lives_thread_data_t *var_mydata;
385 boolean var_com_failed;
386 int var_write_failed, var_read_failed;
387 boolean var_chdir_failed;
388 char *var_read_failed_file, *var_write_failed_file, *var_bad_aud_file;
389 int var_rowstride_alignment; // used to align the rowstride bytesize in create_empty_pixel_data
390 int var_rowstride_alignment_hint;
391 int var_last_sws_block;
392 boolean var_no_gui;
393 } lives_threadvars_t;
394
395 struct _lives_thread_data_t {
396 LiVESWidgetContext *ctx;
397 int64_t idx;
398 lives_threadvars_t vars;
399 };
400
401 typedef struct {
402 lives_funcptr_t func;
403 void *arg;
404 uint64_t flags;
405 volatile uint64_t busy;
406 volatile uint64_t done;
407 void *ret;
408 volatile boolean sync_ready;
409 } thrd_work_t;
410
411 #define WEED_LEAF_NOTIFY "notify"
412 #define WEED_LEAF_DONE "done"
413 #define WEED_LEAF_THREADFUNC "tfunction"
414 #define WEED_LEAF_THREAD_PROCESSING "t_processing"
415 #define WEED_LEAF_THREAD_CANCELLABLE "t_can_cancel"
416 #define WEED_LEAF_THREAD_CANCELLED "t_cancelled"
417 #define WEED_LEAF_RETURN_VALUE "return_value"
418 #define WEED_LEAF_DONTCARE "dontcare" ///< tell proc_thread with return value that we n o longer need return val.
419 #define WEED_LEAF_DONTCARE_MUTEX "dontcare_mutex" ///< ensures we can set dontcare without it finishing while doing so
420
421 #define WEED_LEAF_SIGNALLED "signalled"
422 #define WEED_LEAF_SIGNAL_DATA "signal_data"
423
424 #define WEED_LEAF_THREAD_PARAM "thrd_param"
425 #define _WEED_LEAF_THREAD_PARAM(n) WEED_LEAF_THREAD_PARAM n
426 #define WEED_LEAF_THREAD_PARAM0 _WEED_LEAF_THREAD_PARAM("0")
427 #define WEED_LEAF_THREAD_PARAM1 _WEED_LEAF_THREAD_PARAM("1")
428 #define WEED_LEAF_THREAD_PARAM2 _WEED_LEAF_THREAD_PARAM("2")
429
430 #define LIVES_THRDFLAG_AUTODELETE (1 << 0)
431 #define LIVES_THRDFLAG_TUNING (1 << 1)
432 #define LIVES_THRDFLAG_WAIT_SYNC (1 << 2)
433
434 typedef LiVESList lives_thread_t;
435 typedef uint64_t lives_thread_attr_t;
436
437 #define LIVES_THRDATTR_NONE 0
438 #define LIVES_THRDATTR_AUTODELETE (1 << 0)
439 #define LIVES_THRDATTR_PRIORITY (1 << 1)
440 #define LIVES_THRDATTR_WAIT_SYNC (1 << 2)
441 #define LIVES_THRDATTR_FG_THREAD (1 << 3)
442 #define LIVES_THRDATTR_NO_GUI (1 << 4)
443
444 void lives_threadpool_init(void);
445 void lives_threadpool_finish(void);
446 int lives_thread_create(lives_thread_t *thread, lives_thread_attr_t attr, lives_funcptr_t func, void *arg);
447 uint64_t lives_thread_join(lives_thread_t work, void **retval);
448
449 // lives_proc_thread_t //////////////////////////////////////////////////////////////////////////////////////////////////////////
450
451 #define _RV_ WEED_LEAF_RETURN_VALUE
452
453 typedef uint64_t funcsig_t;
454
455 typedef int(*funcptr_int_t)();
456 typedef double(*funcptr_dbl_t)();
457 typedef int(*funcptr_bool_t)();
458 typedef char *(*funcptr_string_t)();
459 typedef int64_t(*funcptr_int64_t)();
460 typedef weed_funcptr_t(*funcptr_funcptr_t)();
461 typedef void *(*funcptr_voidptr_t)();
462 typedef weed_plant_t(*funcptr_plantptr_t)();
463
464 #define GETARG(type, n) WEED_LEAF_GET(info, _WEED_LEAF_THREAD_PARAM(n), type)
465
466 #define ARGS1(t1) GETARG(t1, "0")
467 #define ARGS2(t1, t2) ARGS1(t1), GETARG(t2, "1")
468 #define ARGS3(t1, t2, t3) ARGS2(t1, t2), GETARG(t3, "2")
469 #define ARGS4(t1, t2, t3, t4) ARGS3(t1, t2, t3), GETARG(t4, "3")
470 #define ARGS5(t1, t2, t3, t4, t5) ARGS4(t1, t2, t3, t4), GETARG(t5, "4")
471 #define ARGS6(t1, t2, t3, t4, t5, t6) ARGS5(t1, t2, t3, t4, t5), GETARG(t6, "5")
472 #define ARGS7(t1, t2, t3, t4, t5, t6, t7) ARGS6(t1, t2, t3, t4, t5, t6), GETARG(t7, "6")
473 #define ARGS8(t1, t2, t3, t4, t5, t6, t7, t8) ARGS7(t1, t2, t3, t4, t5, t6, t7), GETARG(t8, "7")
474 #define ARGS9(t1, t2, t3, t4, t5, t6, t7, t8, t9) ARGS8(t1, t2, t3, t4, t5, t6, t7. t8), GETARG(t9, "8")
475 #define ARGS10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) ARGS9(t1, t2, t3, t4, t5, t6, t7, t8, t9), GETARG(t10, "9")
476
477 #define CALL_VOID_10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) (*thefunc->func)(ARGS10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10))
478 #define CALL_VOID_9(t1, t2, t3, t4, t5, t6, t7, t8, t9) (*thefunc->func)(ARGS9(t1, t2, t3, t4, t5, t6, t7, t8, t9))
479 #define CALL_VOID_8(t1, t2, t3, t4, t5, t6, t7, t8) (*thefunc->func)(ARGS8(t1, t2, t3, t4, t5, t6, t7, t8))
480 #define CALL_VOID_7(t1, t2, t3, t4, t5, t6, t7) (*thefunc->func)(ARGS7(t1, t2, t3, t4, t5, t6, t7))
481 #define CALL_VOID_6(t1, t2, t3, t4, t5, t6) (*thefunc->func)(ARGS6(t1, t2, t3, t4, t5, t6))
482 #define CALL_VOID_5(t1, t2, t3, t4, t5) (*thefunc->func)(ARGS5(t1, t2, t3, t4, t5))
483 #define CALL_VOID_4(t1, t2, t3, t4) (*thefunc->func)(ARGS4(t1, t2, t3, t4))
484 #define CALL_VOID_3(t1, t2, t3) (*thefunc->func)(ARGS3(t1, t2, t3))
485 #define CALL_VOID_2(t1, t2) (*thefunc->func)(ARGS2(t1, t2))
486 #define CALL_VOID_1(t1) (*thefunc->func)(ARGS1(t1))
487 #define CALL_VOID_0() (*thefunc->func)()
488
489 #define CALL_10(ret, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) weed_set_##ret##_value(info, _RV_, \
490 (*thefunc->func##ret)(ARGS10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t19)))
491 #define CALL_9(ret, t1, t2, t3, t4, t5, t6, t7, t8, t9) weed_set_##ret##_value(info, _RV_, \
492 (*thefunc->func##ret)(ARGS9(t1, t2, t3, t4, t5, t6, t7, t8, t9)))
493 #define CALL_8(ret, t1, t2, t3, t4, t5, t6, t7, t8) weed_set_##ret##_value(info, _RV_, \
494 (*thefunc->func##ret)(ARGS8(t1, t2, t3, t4, t5, t6, t7, t7)))
495 #define CALL_7(ret, t1, t2, t3, t4, t5, t6, t7) weed_set_##ret##_value(info, _RV_, \
496 (*thefunc->func##ret)(ARGS7(t1, t2, t3, t4, t5, t6, t7)))
497 #define CALL_6(ret, t1, t2, t3, t4, t5, t6) weed_set_##ret##_value(info, _RV_, (*thefunc->func##ret)(ARGS6(t1, t2, t3, t4, t5, t6)))
498 #define CALL_5(ret, t1, t2, t3, t4, t5) weed_set_##ret##_value(info, _RV_, (*thefunc->func##ret)(ARGS5(t1, t2, t3, t4, t5)))
499 #define CALL_4(ret, t1, t2, t3, t4) weed_set_##ret##_value(info, _RV_, (*thefunc->func##ret)(ARGS4(t1, t2, t3, t4)))
500 #define CALL_3(ret, t1, t2, t3) weed_set_##ret##_value(info, _RV_, (*thefunc->func##ret)(ARGS3(t1, t2, t3)))
501 #define CALL_2(ret, t1, t2) weed_set_##ret##_value(info, _RV_, (*thefunc->func##ret)(ARGS2(t1, t2)))
502 #define CALL_1(ret, t1) weed_set_##ret##_value(info, _RV_, (*thefunc->func##ret)(ARGS1(t1)))
503 #define CALL_0(ret) weed_set_##ret##_value(info, _RV_, (*thefunc->func##ret)())
504
505 typedef union {
506 weed_funcptr_t func;
507 funcptr_int_t funcint;
508 funcptr_dbl_t funcdouble;
509 funcptr_bool_t funcboolean;
510 funcptr_int64_t funcint64;
511 funcptr_string_t funcstring;
512 funcptr_funcptr_t funcfuncptr;
513 funcptr_voidptr_t funcvoidptr;
514 funcptr_plantptr_t funcplantptr;
515 } allfunc_t;
516
517 lives_proc_thread_t lives_proc_thread_create(lives_thread_attr_t, lives_funcptr_t, int return_type, const char *args_fmt,
518 ...);
519
520 void lives_proc_thread_free(lives_proc_thread_t lpt);
521
522 /// returns FALSE while the thread is running, TRUE once it has finished
523 boolean lives_proc_thread_check(lives_proc_thread_t);
524 int lives_proc_thread_signalled(lives_proc_thread_t tinfo);
525 int64_t lives_proc_thread_signalled_idx(lives_proc_thread_t tinfo);
526
527 lives_thread_data_t *get_thread_data(void);
528 lives_threadvars_t *get_threadvars(void);
529 lives_thread_data_t *lives_thread_data_create(uint64_t idx);
530
531 #define THREADVAR(var) (get_threadvars()->var_##var)
532
533 /// only threads with no return value can possibly be cancellable. For threads with a value, use
534 /// lives_proc_thread_dontcare()
535 void lives_proc_thread_set_cancellable(lives_proc_thread_t);
536 boolean lives_proc_thread_get_cancellable(lives_proc_thread_t);
537 boolean lives_proc_thread_cancel(lives_proc_thread_t);
538 boolean lives_proc_thread_cancelled(lives_proc_thread_t);
539
540 /// tell a threead with return value that we no longer need the value so it can free itself
541 boolean lives_proc_thread_dontcare(lives_proc_thread_t);
542
543 void lives_proc_thread_sync_ready(lives_proc_thread_t);
544
545 // WARNING !! version without a return value will free tinfo !
546 void lives_proc_thread_join(lives_proc_thread_t);
547
548 // with return value should free proc_thread
549 int lives_proc_thread_join_int(lives_proc_thread_t);
550 double lives_proc_thread_join_double(lives_proc_thread_t);
551 int lives_proc_thread_join_boolean(lives_proc_thread_t);
552 char *lives_proc_thread_join_string(lives_proc_thread_t);
553 weed_funcptr_t lives_proc_thread_join_funcptr(lives_proc_thread_t);
554 void *lives_proc_thread_join_voidptr(lives_proc_thread_t);
555 weed_plantptr_t lives_proc_thread_join_plantptr(lives_proc_thread_t) ;
556 int64_t lives_proc_thread_join_int64(lives_proc_thread_t);
557
558 void resubmit_proc_thread(lives_proc_thread_t, lives_thread_attr_t);
559
560 void *fg_run_func(lives_proc_thread_t lpt, void *retval);
561 void *main_thread_execute(lives_funcptr_t func, int return_type, void *retval, const char *args_fmt, ...);
562
563 void free_fdets_list(LiVESList **);
564 lives_proc_thread_t dir_to_file_details(LiVESList **, const char *dir,
565 const char *orig_loc, uint64_t extra);
566 lives_proc_thread_t ordfile_to_file_details(LiVESList **listp, const char *ofname,
567 const char *orig_loc, uint64_t extra);
568
569 ///// cmdline
570 char *grep_in_cmd(const char *cmd, int mstart, int npieces, const char *mphrase, int ridx, int rlen);
571
572 /// x11
573 char *get_wid_for_name(const char *wname);
574 boolean hide_x11_window(const char *wid);
575 boolean unhide_x11_window(const char *wid);
576 boolean activate_x11_window(const char *wid);
577 boolean show_desktop_panel(void);
578 boolean hide_desktop_panel(void);
579 boolean get_x11_visible(const char *wname);
580
581 int get_window_stack_level(LiVESXWindow *, int *nwins);
582
583 #define WM_XFWM4 "Xfwm4"
584 #define WM_XFCE4_PANEL "xfce4-panel"
585 #define WM_XFCE4_SSAVE "xfce4-ssave"
586 #define WM_XFCE4_COLOR "xfce4-color-settings"
587 #define WM_XFCE4_DISP "xfce4-display-settings"
588 #define WM_XFCE4_POW "xfce4-power-manager-settings"
589 #define WM_XFCE4_SETTINGS "xfce4-settings-manager"
590 #define WM_XFCE4_TERMINAL "xfce4-terminal"
591 #define WM_XFCE4_TASKMGR "xfce4-taskmanager"
592 #define WM_XFCE4_SSHOT "xfce4-screenshooter"
593
594 #define WM_KWIN "KWin"
595 #define WM_KWIN_PANEL ""
596 #define WM_KWIN_SSAVE ""
597 #define WM_KWIN_COLOR ""
598 #define WM_KWIN_DISP ""
599 #define WM_KWIN_POW ""
600 #define WM_KWIN_SETTINGS "systemseettings5"
601 #define WM_KWIN_TERMINAL "Konsole"
602 #define WM_KWIN_TASKMGR "systemmonitor"
603 #define WM_KWIN_SSHOT ""
604
605 #define XDG_CURRENT_DESKTOP "XDG_CURRENT_DESKTOP"
606 #define XDG_SESSION_TYPE "XDG_SESSION_TYPE"
607
608 boolean get_wm_caps(void);
609 boolean get_distro_dets(void);
610 boolean get_machine_dets(void);
611 int get_num_cpus(void);
612 double get_disk_load(const char *mp);
613 int64_t get_cpu_load(int cpun); ///< percent * 1 million
614
615 char *get_systmp(const char *suff, boolean is_dir);
616 char *get_worktmp(const char *prefix);
617 char *get_worktmpfile(const char *prefix);
618
619 boolean check_snap(const char *prog);
620
621 #endif
622