Go to the documentation of this file.
9 #include <sys/statvfs.h>
10 #ifdef HAVE_LIBEXPLAIN
11 #include <libexplain/system.h>
12 #include <libexplain/read.h>
21 #define ASPECT_ALLOWANCE 0.005
27 } lives_speed_cache_t;
29 static boolean omute, osepwin, ofs, ofaded, odouble;
31 static int get_hex_digit(
const char c)
GNU_CONST;
63 return lives_strdup(fbuff->
pathname);
68 struct stat stb0, stb1;
72 if (fstat(fd, &stb0))
return val;
75 fdpath = lives_build_filename(
"/proc",
"self",
"fd", fidi, NULL);
83 if (stat(rfdpath, &stb1))
return val;
84 if (stb0.st_dev != stb1.st_dev)
return val;
85 if (stb0.st_ino != stb1.st_ino)
return val;
87 return lives_strdup(rfdpath);
95 return open(pathname, flags, mode);
100 return open(pathname, flags);
105 return readlink(path, buf, bufsiz);
116 for (
int i = 0; i < times; i++) sync();
124 boolean ret = !putenv(env);
128 return !setenv(name, value, 1);
136 boolean ret = !putenv(env);
140 return !unsetenv(name);
146 LiVESResponseType response;
148 boolean cnorm =
FALSE;
162 response = LIVES_RESPONSE_NONE;
163 retval = system(com);
169 #ifdef HAVE_LIBEXPLAIN
178 #ifndef LIVES_NO_DEBUG
180 msg =
lives_strdup_printf(
"lives_system failed with code %d: %s (not an error)", retval, com);
186 }
while (response == LIVES_RESPONSE_RETRY);
194 ssize_t
lives_popen(
const char *com,
boolean allow_error,
char *buff, ssize_t buflen) {
205 LiVESResponseType response;
206 ssize_t totlen = 0, xtotlen = 0;
208 LiVESTextBuffer *tbuff = NULL;
209 LiVESTextIter end_iter;
210 boolean cnorm =
FALSE;
214 tbuff = (LiVESTextBuffer *)buff;
233 response = LIVES_RESPONSE_NONE;
236 fp = popen(com,
"r");
241 strg = fgets(xbuff + totlen, tbuff ? buflen : buflen - totlen, fp);
243 if (err != 0 || !strg || !(*strg))
break;
252 if (slen >= buflen - 1)
break;
272 #ifndef LIVES_NO_DEBUG
280 }
while (response == LIVES_RESPONSE_RETRY);
283 if (err != 0)
return -
ABS(err);
298 if (!(ret = fork())) {
309 ssize_t
lives_write(
int fd,
const void *buf, ssize_t count,
boolean allow_fail) {
311 if (count <= 0)
return 0;
313 retval = write(fd, buf, count);
315 if (retval < count) {
331 #ifndef LIVES_NO_DEBUG
336 (uint64_t)count, ffile);
350 ssize_t
lives_write_le(
int fd,
const void *buf, ssize_t count,
boolean allow_fail) {
351 if (count <= 0)
return 0;
360 int retval = fputs(s, stream);
362 THREADVAR(write_failed) = fileno(stream) + 1;
370 if (!size)
return NULL;
371 retval = fgets(s, size, stream);
372 if (!retval && ferror(stream)) {
373 THREADVAR(read_failed) = fileno(stream) + 1;
379 size_t lives_fread(
void *ptr,
size_t size,
size_t nmemb, FILE *stream) {
380 size_t bytes_read = fread(ptr, size, nmemb, stream);
381 if (ferror(stream)) {
382 THREADVAR(read_failed) = fileno(stream) + 1;
391 if (!stlen)
return 0;
392 infofile = fopen(fname,
"r");
393 if (!infofile)
return 0;
409 if (fbuff->
fd == fd)
break;
437 static void do_file_read_error(
int fd, ssize_t errval,
void *buff, ssize_t count) {
448 #ifdef HAVE_LIBEXPLAIN
449 buff ? explain_read(fd, buff, count) :
""
460 ssize_t
lives_read(
int fd,
void *buf, ssize_t count,
boolean allow_less) {
461 ssize_t retval = read(fd, buf, count);
462 if (count <= 0)
return 0;
464 if (retval < count) {
465 if (!allow_less || retval < 0) {
466 do_file_read_error(fd, retval, buf, count);
469 #ifndef LIVES_NO_DEBUG
475 (uint64_t)count, ffile);
486 ssize_t
lives_read_le(
int fd,
void *buf, ssize_t count,
boolean allow_less) {
488 if (count <= 0)
return 0;
489 retval =
lives_read(fd, buf, count, allow_less);
490 if (retval < count)
return retval;
541 if (!fbuff->
allow_fail && res < fbuff->bytes) {
567 file_buffer_flush(fbuff);
578 static int lives_open_real_buffered(
const char *pathname,
int flags,
int mode,
boolean isread) {
580 boolean is_append =
FALSE;
583 if (flags & O_APPEND) {
592 fbuff->
read = isread;
593 fbuff->
pathname = lives_strdup(pathname);
597 char *msg =
lives_strdup_printf(
"Duplicate fd (%d) in file buffers !\n%s was not removed, and\n%s will be added.", fd,
605 if (!isread && !(flags & O_TRUNC)) {
606 if (is_append) fbuff->
offset = fbuff->
orig_size = lseek(fd, 0, SEEK_END);
625 static weed_plant_t *tunerl = NULL;
626 static boolean tunedl =
FALSE;
627 static weed_plant_t *tunerm = NULL;
628 static boolean tunedm =
FALSE;
629 static weed_plant_t *tunersm = NULL;
630 static boolean tunedsm =
FALSE;
631 static weed_plant_t *tuners = NULL;
632 static boolean tuneds =
FALSE;
637 return lives_open_real_buffered(pathname, O_RDONLY, 0,
TRUE);
643 off_t fsize =
get_file_size(fd) - skip, bufsize = smbytes, res;
645 lseek(fd, skip, SEEK_SET);
650 if (bufsize > fsize) bufsize = fsize;
657 if (res > fsize) res = fsize;
660 if (fsize >= bigbytes && bufsize >= medbytes) bufsize = bigbytes;
661 else if (fsize >= medbytes && bufsize >= smedbytes) bufsize = medbytes;
662 else if (fsize >= smedbytes) bufsize = smedbytes;
673 if (!fbuff || fbuff->
slurping)
return;
685 LIVES_DEBUG(
"lives_buffered_readonly_set_reversed: no file buffer found");
694 #define O_DSYNC O_SYNC
699 return lives_open_real_buffered(pathname, O_CREAT | O_WRONLY | O_TRUNC |
O_DSYNC, mode,
FALSE);
703 return lives_open_real_buffered(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode,
FALSE);
707 return lives_open_real_buffered(pathname, O_CREAT | O_WRONLY |
O_DSYNC | (append ? O_APPEND : 0), mode,
FALSE);
718 boolean should_close =
TRUE;
725 should_close =
FALSE;
733 LIVES_DEBUG(
"lives_close_buffered: no file buffer found");
734 if (should_close) ret = close(fd);
738 if (!fbuff->
read && should_close) {
740 ssize_t bytes = fbuff->
bytes;
743 ret = file_buffer_flush(fbuff);
745 if (!allow_fail && ret < bytes)
return ret;
747 #ifdef HAVE_POSIX_FALLOCATE
754 if (should_close && fbuff->
fd >= 0) ret = close(fbuff->
fd);
762 if (fbuff->buffer && !fbuff->invalid) {
787 if (min < 0) min = 0;
792 bufsize = fbuff->
bytes;
797 if (fbuff->
reversed) delta = (bufsize >> 2) * 3;
799 if (bufsize - delta < min) bufsize = min + delta;
815 fbuff->
bytes = res - delta;
818 if (res < bufsize) fbuff->
eof =
TRUE;
821 #if defined HAVE_POSIX_FADVISE || (defined _GNU_SOURCE && defined __linux__)
823 #if defined HAVE_POSIX_FADVISE
824 posix_fadvise(fbuff->
fd, 0, fbuff->
offset - (bufsize >> 2) * 3, POSIX_FADV_RANDOM);
825 posix_fadvise(fbuff->
fd, fbuff->
offset - (bufsize >> 2) * 3, bufsize, POSIX_FADV_WILLNEED);
828 readahead(fbuff->
fd, fbuff->
offset - (bufsize >> 2) * 3, bufsize);
831 #if defined HAVE_POSIX_FADVISE
832 posix_fadvise(fbuff->
fd, fbuff->
offset, 0, POSIX_FADV_SEQUENTIAL);
833 posix_fadvise(fbuff->
fd, fbuff->
offset, bufsize, POSIX_FADV_WILLNEED);
836 readahead(fbuff->
fd, fbuff->
offset, bufsize);
845 static off_t _lives_lseek_buffered_rdonly_relative(
lives_file_buffer_t *fbuff, off_t offset) {
847 if (offset == 0)
return fbuff->
offset - fbuff->
bytes;
852 if (offset < fbuff->bytes) {
853 fbuff->
ptr += offset;
854 fbuff->
bytes -= offset;
857 offset -= fbuff->
bytes;
865 if (offset <= fbuff->ptr - fbuff->
buffer) {
866 fbuff->
ptr -= offset;
867 fbuff->
bytes += offset;
882 #ifdef HAVE_POSIX_FADVISE
884 posix_fadvise(fbuff->
fd, 0, fbuff->
offset - fbuff->
bytes, POSIX_FADV_RANDOM);
886 posix_fadvise(fbuff->
fd, fbuff->
offset, 0, POSIX_FADV_SEQUENTIAL);
889 lseek(fbuff->
fd, fbuff->
offset, SEEK_SET);
899 LIVES_DEBUG(
"lives_lseek_buffered_rdonly: no file buffer found");
900 return lseek(fd, offset, SEEK_CUR);
903 return _lives_lseek_buffered_rdonly_relative(fbuff, offset);
911 LIVES_DEBUG(
"lives_lseek_buffered_rdonly_absolute: no file buffer found");
912 return lseek(fd, offset, SEEK_SET);
920 return _lives_lseek_buffered_rdonly_relative(fbuff, offset);
926 ssize_t retval = 0, res = 0;
927 size_t ocount = count;
928 uint8_t *ptr = (uint8_t *)buf;
934 if (count <= 0)
return retval;
937 LIVES_DEBUG(
"lives_read_buffered: no file buffer found");
938 return lives_read(fd, buf, count, allow_less);
942 LIVES_ERROR(
"lives_read_buffered: wrong buffer type");
950 cost = 1. / (1. + (double)fbuff->
nseqreads);
959 autotune_u64(tunerm, smedbytes * 4, 65536 * 2, 32, cost);
962 autotune_u64(tunerl, medbytes * 4, 8192 * 1024, 256, cost);
977 fbuff->
bytes = count;
979 return file_buffer_fill(fbuff, count);
990 if (nbytes == 0)
goto rd_exit;
992 while ((nbytes = fbuff->
offset - fbuff->
bytes) < count) {
996 }
else nbytes = fbuff->
bytes;
997 if (nbytes > count) nbytes = count;
1008 file_buffer_fill(fbuff, fbuff->
bytes);
1016 fbuff->
ptr += nbytes;
1021 else fbuff->
bytes -= nbytes;
1025 if (count == 0)
goto rd_done;
1050 file_buffer_fill(fbuff, fbuff->
bytes);
1059 res = file_buffer_fill(fbuff, count);
1066 if (res > count) res = count;
1070 fbuff->
bytes -= res;
1091 if (res < count) fbuff->
eof =
TRUE;
1149 if (!allow_less && count > 0) {
1150 do_file_read_error(fd, retval, NULL, ocount);
1160 if (count <= 0)
return 0;
1162 if (retval < count)
return retval;
1173 LIVES_DEBUG(
"lives_read_buffered: no file buffer found");
1178 LIVES_ERROR(
"lives_read_buffered_eof: wrong buffer type");
1186 static ssize_t lives_write_buffered_direct(
lives_file_buffer_t *fbuff,
const char *buf, ssize_t count,
boolean allow_fail) {
1188 ssize_t bytes = fbuff->
bytes;
1190 if (count <= 0)
return 0;
1193 res = file_buffer_flush(fbuff);
1195 if (!allow_fail && res < bytes)
return 0;
1203 size_t bigbsize = count;
1207 if (bigbsize > count) bigbsize = count;
1208 bytes =
lives_write(fbuff->
fd, buf + res, bigbsize, allow_fail);
1209 if (bytes == bigbsize) {
1214 LIVES_ERROR(
"lives_write_buffered: error in bigblock writer");
1228 ssize_t retval = 0, res;
1234 LIVES_DEBUG(
"lives_write_buffered: no file buffer found");
1239 LIVES_ERROR(
"lives_write_buffered: wrong buffer type");
1243 if (count <= 0)
return 0;
1259 if (bufsztype < fbuff->bufsztype) bufsztype = fbuff->
bufsztype;
1283 #ifdef HAVE_POSIX_FALLOCATE
1286 posix_fallocate(fbuff->
fd, fbuff->
offset, buffsize);
1291 space_left = buffsize - fbuff->
bytes;
1292 if (space_left > count) {
1295 fbuff->
ptr += count;
1296 fbuff->
bytes += count;
1300 fbuff->
bytes = buffsize;
1301 res = file_buffer_flush(fbuff);
1302 retval += space_left;
1303 if (res < buffsize)
return (res < 0 ? res : retval);
1304 count -= space_left;
1320 va_start(xargs, fmt);
1321 text = lives_strdup_vprintf(fmt, xargs);
1330 if (count <= 0)
return 0;
1342 LIVES_DEBUG(
"lives_lseek_buffered_writer: no file buffer found");
1343 return lseek(fd, offset, SEEK_SET);
1347 LIVES_ERROR(
"lives_lseek_buffered_writer: wrong buffer type");
1351 if (fbuff->
bytes > 0) {
1352 ssize_t res = file_buffer_flush(fbuff);
1353 if (res < 0)
return res;
1354 if (res < fbuff->bytes && !fbuff->
allow_fail) {
1359 fbuff->
offset = lseek(fbuff->
fd, offset, SEEK_SET);
1368 LIVES_DEBUG(
"lives_buffered_offset: no file buffer found");
1369 return lseek(fd, 0, SEEK_CUR);
1381 LIVES_DEBUG(
"lives_buffered_offset: no file buffer found");
1382 return lseek(fd, 0, SEEK_CUR);
1396 int retval = chdir(path);
1401 if (!no_error_dlg) {
1428 return kill(pid,
sig);
1441 for (i = 0; i < pow; i++) res *= 10;
1448 if (val >= 0.)
return (
double)((int)(val * factor + 0.5)) / factor;
1449 return (
double)((int)(val * factor - 0.5)) / factor;
1454 x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16);
1459 x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); x |= (x >> 32);
1465 if (high < low || (val - low < high - val))
return low;
1486 ticks_t clock_ticks, current = -1;
1487 static ticks_t lclock_ticks, interticks;
1489 if (time_source) tsource = time_source;
1490 else tsource = &xtsource;
1499 current = clock_ticks;
1503 #ifdef ENABLE_JACK_TRANSPORT
1508 current = jack_transport_get_current_ticks();
1541 #ifdef HAVE_PULSE_AUDIO
1549 else current = lives_pulse_get_time(
mainw->
pulsed);
1557 current = clock_ticks;
1595 mainw->
cadjticks = clock_ticks - interticks - (clock_ticks - lclock_ticks);
1601 mainw->
adjticks = interticks - current + (clock_ticks - lclock_ticks);
1610 lclock_ticks = clock_ticks;
1624 break_me(
"inv alarm handle in lives_alarm_reset");
1632 alarm->
tleft = ticks;
1633 return ++alarm_handle;
1694 break_me(
"inv alarm handle in lives_alarm_check");
1714 return alarm->
tleft;
1720 if (alarm->
tleft <= 0) {
1728 return alarm->
tleft;
1764 return (frame < mainw->files[filenum]->frames) ? frame :
mainw->
files[filenum]->
frames;
1774 return (frame < mainw->files[filenum]->frames + 1) ? frame :
mainw->
files[filenum]->
frames + 1;
1784 return (frame < mainw->files[filenum]->frames + 1) ? frame :
mainw->
files[filenum]->
frames + 1;
1797 static boolean check_for_audio_stop(
int fileno,
frames_t first_frame,
frames_t last_frame) {
1814 >=
cfile->laudio_time - 0.0001)) {
1821 #ifdef HAVE_PULSE_AUDIO
1834 >=
cfile->laudio_time - 0.0001)) {
1854 #ifdef HAVE_PULSE_AUDIO
1890 static boolean norecurse =
FALSE;
1893 ticks_t ddtc = *ntc - last_ntc;
1895 int64_t first_frame, last_frame, selrange;
1901 int aplay_file = fileno;
1903 if (!sfile)
return 0;
1906 if (norecurse)
return cframe;
1909 #ifdef HAVE_PULSE_AUDIO
1921 if (fileno != aplay_file) {
1925 else sfile->
aseek_pos -= aseek_pos_delta;
1948 if (fps < 0.001 && fps > -0.001) {
1970 if (nframe != cframe) {
1994 if (nframe != cframe) {
1996 if (delval <= -1 || delval >= 1) {
1998 frames64_t xnframe = cframe + (int64_t)delval;
2001 if (xnframe != nframe) {
2005 if (nframe != cframe) {
2017 last_frame = sfile->
frames;
2036 if (last_frame > sfile->
frames) last_frame = sfile->
frames;
2038 if (first_frame > sfile->
frames) first_frame = sfile->
frames;
2045 if (nframe > cframe + 1) {
2047 cfile->last_frameno -= (nframe - cframe - 1);
2048 nframe = cframe + 1;
2049 }
else if (nframe < cframe - 1) {
2050 cfile->last_frameno += (cframe - 1 - nframe);
2051 nframe = cframe - 1;
2056 while (
IS_NORMAL_CLIP(fileno) && (nframe < first_frame || nframe > last_frame)) {
2078 if (first_frame == last_frame) {
2079 nframe = first_frame;
2088 nframe = first_frame;
2095 nframe = last_frame;
2101 nframe -= first_frame;
2102 selrange = (1 + last_frame - first_frame);
2103 if (nframe < 0) nframe = -nframe;
2104 nloops = nframe / selrange;
2106 dir += nloops + dir + 1;
2112 nframe -= nloops * selrange;
2115 nframe += first_frame;
2130 nframe = last_frame - nframe;
2152 if (!check_for_audio_stop(fileno, first_frame + 1, last_frame - 1)) {
2179 if (*cwidth <= 0 || *cheight <= 0 || rwidth <= 0 || rheight <= 0)
return;
2181 aspect = (double)(*cwidth) / (double)(*cheight);
2184 *cheight = (double)(*cwidth) / aspect;
2185 if (*cheight > rheight) {
2188 *cwidth = (double)(*cheight) * aspect;
2190 *cwidth = ((*cwidth + 1) >> 1) << 1;
2191 *cheight = ((*cheight + 1) >> 1) << 1;
2199 double aspect, dheight;
2201 if (*cwidth <= 0 || *cheight <= 0 || rwidth <= 0 || rheight <= 0)
return;
2203 aspect = (double)(rwidth) / (double)(rheight);
2204 dheight = (double)(*cwidth) / aspect;
2207 *cheight = (
int)dheight;
2209 *cwidth = (int)((
double)(*cheight * aspect));
2211 *cwidth = ((*cwidth + 1) >> 1) << 1;
2212 *cheight = ((*cheight + 1) >> 1) << 1;
2220 double aspect, dheight;
2222 if (*cwidth <= 0 || *cheight <= 0 || rwidth <= 0 || rheight <= 0)
return;
2224 aspect = (double)(rwidth) / (double)(rheight);
2225 dheight = (double)(*cwidth) / aspect;
2228 *cheight = (
int)dheight;
2230 *cwidth = (int)((
double)(*cheight * aspect));
2232 *cwidth = ((*cwidth + 1) >> 1) << 1;
2233 *cheight = ((*cheight + 1) >> 1) << 1;
2254 if (lives_file_test(clipd, LIVES_FILE_TEST_EXISTS)) {
2271 cfile->cb_src = current_file;
2310 if (n < 0)
return NULL;
2327 msg = weed_get_plantptr_value(msg, leaf, &
error);
2328 if (
error != WEED_SUCCESS)
return NULL;
2340 char *text = lives_strdup(
""), *tmp, *msgtext;
2341 boolean needs_newline =
FALSE;
2347 if (
error != WEED_SUCCESS)
break;
2348 if (msgno >= start) {
2349 #ifdef SHOW_MSG_LINENOS
2356 needs_newline =
TRUE;
2359 if (++msgno > end)
if (end > -1)
break;
2361 if (
error != WEED_SUCCESS)
break;
2367 static weed_plant_t *make_msg(
const char *text) {
2370 if (!msg)
return NULL;
2383 weed_plant_t *next, *end;
2385 if (frval <= 0)
return WEED_SUCCESS;
2389 if (
error != WEED_SUCCESS) {
2395 if (
error != WEED_SUCCESS) {
2412 return WEED_SUCCESS;
2420 weed_plant_t *msg, *end;;
2422 int error, i, numlines;
2425 if (!text || !*text)
return WEED_SUCCESS;
2429 lines = lives_strsplit(text,
"\n", numlines);
2431 for (i = 0; i < numlines; i++) {
2436 lives_strfreev(lines);
2437 return WEED_ERROR_MEMORY_ALLOCATION;
2444 if (
error != WEED_SUCCESS) {
2445 lives_strfreev(lines);
2453 if (
error != WEED_SUCCESS) {
2454 lives_strfreev(lines);
2467 if (
error != WEED_SUCCESS) {
2468 lives_strfreev(lines);
2477 msg = make_msg(lines[i]);
2479 lives_strfreev(lines);
2480 return WEED_ERROR_MEMORY_ALLOCATION;
2492 lives_strfreev(lines);
2493 return WEED_SUCCESS;
2502 va_start(xargs, fmt);
2503 text = lives_strdup_vprintf(fmt, xargs);
2527 va_start(xargs, fmt);
2528 text = lives_strdup_vprintf(fmt, xargs);
2558 va_start(xargs, fmt);
2559 text = lives_strdup_vprintf(fmt, xargs);
2565 char *swtext =
lives_strdup_printf(
_(
"\n==============================\nSwitched to clip %s\n"),
2598 static void d_print_utility(
const char *text,
int osc_note,
const char *osc_detail) {
2621 d_print_utility(
_(
"done.\n"), 0, NULL);
2626 d_print_utility(
_(
"error in file. Failed.\n"), 0, NULL);
2633 char *msg =
lives_strdup_printf(
P_(
"%d frame is enough !\n",
"%d frames are enough !\n", frames), frames);
2634 d_print_utility(msg, 0, NULL);
2641 int frameno,
double atime,
boolean affects_current) {
2645 if (name) err->
name = lives_strdup(name);
2646 else err->
name = NULL;
2647 err->
data = user_data;
2651 err->
current = affects_current;
2674 int frameno,
double atime,
boolean affects_current) {
2676 LiVESTextIter end_iter;
2685 int resampled_frame;
2689 if (affects_current && !user_data) {
2697 if (!(*name)) name2 = (
_(
"(blank)"));
2698 else name2 = lives_strdup(name);
2700 (
_(
"The set name has been changed from %s to %s. Affected layouts have been updated accordingly\n"),
2701 name2, (
char *)user_data);
2708 text =
lives_strdup_printf(
_(
"The clip %s is missing from this set.\nIt is required by the following layouts:\n"), name);
2712 text =
lives_strdup_printf(
_(
"The clip %s has been closed.\nIt is required by the following layouts:\n"), name);
2717 text =
lives_strdup_printf(
_(
"Frames have been shifted in the clip %s.\nThe following layouts are affected:\n"), name);
2722 text =
lives_strdup_printf(
_(
"Frames have been deleted from the clip %s.\nThe following layouts are affected:\n"), name);
2727 text =
lives_strdup_printf(
_(
"Audio has been deleted from the clip %s.\nThe following layouts are affected:\n"), name);
2732 text =
lives_strdup_printf(
_(
"Audio has been shifted in clip %s.\nThe following layouts are affected:\n"), name);
2737 text =
lives_strdup_printf(
_(
"Audio has been altered in the clip %s.\nThe following layouts are affected:\n"), name);
2742 text =
lives_strdup_printf(
_(
"Frames have been altered in the clip %s.\nThe following layouts are affected:\n"), name);
2748 if (affects_current && user_data) {
2758 array = lives_strsplit((
char *)lmap->data,
"|", -1);
2764 lives_strfreev(array);
2770 if (affects_current) {
2779 NULL, &end_iter,
TRUE));
2782 lmap = (LiVESList *)user_data;
2784 array = lives_strsplit((
char *)lmap->data,
"|", -1);
2789 lives_strfreev(array);
2796 if (affects_current) {
2805 NULL, &end_iter,
TRUE));
2807 lmap = (LiVESList *)user_data;
2809 array = lives_strsplit((
char *)lmap->data,
"|", -1);
2810 orig_fps = strtod(array[3], NULL);
2812 if (resampled_frame <= atoi(array[2])) {
2818 lives_strfreev(array);
2825 if (affects_current) {
2834 NULL, &end_iter,
TRUE));
2836 lmap = (LiVESList *)user_data;
2838 array = lives_strsplit((
char *)lmap->data,
"|", -1);
2839 max_time = strtod(array[4], NULL);
2840 if (max_time > 0. && atime <= max_time) {
2846 lives_strfreev(array);
2859 LiVESTextIter start_iter, end_iter;
2872 lives_list_free(lmap);
2916 do_error_dialogf(
_(
"Set %s\ncannot be opened, as it is in use\nby another copy of LiVES.\n"), set_name);
2919 }
else if (type == 1) {
2921 "Please choose another set name.\n"), set_name);
2929 boolean do_std_checks(
const char *type_name,
const char *type,
size_t maxlen,
const char *nreject) {
2930 char *xtype = lives_strdup(type), *msg;
2931 const char *reject =
" /\\*\"";
2932 size_t slen = strlen(type_name);
2934 if (nreject) reject = nreject;
2945 msg =
lives_strdup_printf(
_(
"\n%s names may not be longer than %d characters.\n"), xtype, (
int)maxlen);
2952 if (strcspn(type_name, reject) != slen) {
2953 msg =
lives_strdup_printf(
_(
"\n%s names may not contain spaces or the characters%s.\n"), xtype, reject);
2960 for (
int i = 0; i < slen; i++) {
2961 if (type_name[i] ==
'.' && (i == 0 || type_name[i - 1] ==
'.')) {
2999 if ((set_name[0] <
'a' || set_name[0] >
'z') && (set_name[0] <
'A' || set_name[0] >
'Z')) {
3002 do_warning_dialog(
_(
"As of LiVES 3.2.0 all set names must begin with alphabetical character\n"
3003 "(A - Z or a - z)\nYou will need to give a new name for the set when saving it.\n"));
3005 do_error_dialog(
_(
"All set names must begin with an alphabetical character\n(A - Z or a - z)\n"));
3012 char *set_dir = lives_build_filename(
prefs->
workdir, set_name, NULL);
3013 if (lives_file_test(set_dir, LIVES_FILE_TEST_IS_DIR)) {
3016 "Do you want to add the current clips to the existing set ?.\n"), set_name);
3054 const char *img_ext) {
3080 if (!lives_file_test(frame, LIVES_FILE_TEST_EXISTS)) {
3092 if (lives_file_test(frame, LIVES_FILE_TEST_EXISTS)) {
3119 if (bytes > 0)
return atoi(
mainw->
msg);
3147 boolean ret =
FALSE;
3149 if (!
string)
return FALSE;
3151 va_start(xargs, fmt);
3152 textx = lives_strdup_vprintf(fmt, xargs);
3154 if (!textx)
return FALSE;
3157 if (cklen == 0 || cklen > slen) {
3173 lives_snprintf(filename,
PATH_MAX,
"%s%s", (tmp = lives_path_get_dirname(filename)),
LIVES_DIR_SEP);
3174 if (!strcmp(tmp,
".")) {
3175 char *tmp1 = lives_get_current_dir(), *tmp2 = lives_build_filename(tmp1, filename + 2, NULL);
3177 lives_snprintf(filename,
PATH_MAX,
"%s", tmp2);
3188 lives_snprintf(tmp,
PATH_MAX,
"%s", filename);
3190 return lives_strdup(tmp);
3199 char *tmp = lives_path_get_basename(filename);
3200 lives_snprintf(filename,
PATH_MAX,
"%s", tmp);
3219 char *tmp = lives_path_get_basename(filename);
3220 char *ptr = strrchr(tmp,
'.');
3223 return lives_strdup(
"");
3225 char *ret = lives_strdup(ptr + 1);
3239 size_t se = strlen(ext), sf;
3240 char *eptr = (
char *)ext;
3242 if (!fname)
return NULL;
3244 if (se == 0)
return lives_strdup(fname);
3246 if (eptr[0] ==
'.') {
3252 if (sf < se + 1 || strcmp(fname + sf - se, eptr) || fname[sf - se - 1] !=
'.') {
3253 return lives_strconcat(fname,
".", eptr, NULL);
3256 return lives_strdup(fname);
3268 const char ellipsis[4] =
"...\0";
3272 if (!maxlen)
return NULL;
3273 if (slen >= maxlen) {
3274 if (maxlen == 1)
return lives_strdup(
"");
3276 if (maxlen == 2)
return lives_strdup(
".");
3277 if (maxlen == 3)
return lives_strdup(
"..");
3278 if (maxlen == 4)
return lives_strdup(
"...");
3283 lives_memcpy(retval + 3, txt + slen - maxlen, maxlen + 1);
3290 enlen = maxlen >> 1;
3291 stlen = maxlen - enlen;
3294 lives_memcpy(retval + stlen + 3, txt + slen - enlen, enlen + 1);
3312 if (align == LIVES_ALIGN_FILL)
return txt;
3313 if (slen < minlen - 1) {
3318 case LIVES_ALIGN_END:
3319 ipos = minlen - slen;
3321 case LIVES_ALIGN_CENTER:
3322 ipos = minlen - slen;
3340 if (slen == fixlen - 1)
return txt;
3355 boolean ret =
FALSE;
3356 char *tmp = lives_strdup(fname), *tmp2;
3372 if (ret) lives_snprintf(fname,
PATH_MAX,
"%s", tmp);
3379 while (offs >= 0 && !strncmp(fname + offs,
LIVES_DIR_SEP, dslen)) offs -= dslen;
3380 if (offs == slen - dslen)
return ret;
3383 if (++offs < 0) offs = 0;
3384 if (offs < slen) fname[offs] = 0;
3395 lives_snprintf(dir1,
PATH_MAX,
"%s", (tmp = F2U8(dira)));
3397 lives_snprintf(dir2,
PATH_MAX,
"%s", (tmp = F2U8(dirb)));
3412 if ((loc = lives_find_program_in_path(exe)) != NULL) {
3413 lives_snprintf(val, maxlen,
"%s", loc);
3423 if ((loc = lives_find_program_in_path(exe)) != NULL) {
3435 #ifdef NEW_CHECKSTATUS
3436 if (!cap || (*cap)->present ==
UNCHECKED) {
3444 if (lives_file_test(localv, LIVES_FILE_TEST_IS_EXECUTABLE)) {
3446 if (cap) *cap =
LOCAL;
3460 #ifdef HAS_MISSING_PRESENCE
3488 if (ntok < piece)
return -1;
3489 array = lives_strsplit(buff, sep, ntok);
3491 lives_strfreev(array);
3496 #define VER_MAJOR_MULT 1000000
3497 #define VER_MINOR_MULT 1000
3498 #define VER_MICRO_MULT 1
3509 array = lives_strsplit(ver,
".", ntok);
3517 lives_strfreev(array);
3523 if (!
version)
return lives_strdup(
_(
"'Unknown'"));
3542 char *
string = lives_strdup(entry);
3568 LiVESList *lmap, *lmap_next, *cmap, *cmap_next, *map_next;
3575 map_next = map->next;
3587 cmap_next = cmap->next;
3596 array = lives_strsplit((
char *)map->data,
"|", -1);
3598 lives_strfreev(array);
3602 d_print(
_(
"Removing layout %s\n"), fname);
3613 char *protect_file = lives_build_filename(
prefs->
workdir,
"noremove", NULL);
3621 fdir = lives_path_get_dirname(fname);
3637 lmap_next = lmap->next;
3638 if (!
lives_strncmp((
char *)lmap->data, (
char *)map->data, maplen)) {
3680 if (
cfile->audio_waveform) {
3699 if (frames * file->
fps > 0) {
3705 if (file->
fps > 0.) {
3743 < MAX(
cfile->laudio_time,
cfile->raudio_time) &&
3757 int real_width, real_height;
3758 uint64_t delta, current_delta;
3761 int calc_width = (int)((vsize + aspect * hsize) * aspect / (aspect * aspect + 1.));
3765 current_delta = (hsize - cw) * (hsize - cw) + (vsize - ch) * (vsize - ch);
3768 lives_printerr(
"aspect %.8f : width %d height %d is best fit\n", aspect, calc_width, (
int)(calc_width / aspect));
3771 for (i = -1; i < 2; i++) {
3772 real_width = (int)(calc_width / hblock + i) * hblock;
3773 real_height = (int)(real_width / aspect / vblock + .5) * vblock;
3774 delta = (hsize - real_width) * (hsize - real_width) + (vsize - real_height) * (vsize - real_height);
3776 if (real_width % hblock != 0 || real_height % vblock != 0 ||
3780 real_width = ((int)(real_width / hblock) + 1) * hblock;
3781 real_height = (int)((
double)real_width / aspect + .5);
3783 if (real_height % vblock == 0)
break;
3785 real_height = ((int)(real_height / vblock) + 1) * vblock;
3786 real_width = (int)((
double)real_height * aspect + .5);
3788 if (real_width % hblock == 0)
break;
3793 lives_printerr(
"block quantise to %d x %d\n", real_width, real_height);
3795 if (delta < current_delta) {
3797 lives_printerr(
"is better fit\n");
3799 current_delta = delta;
3800 width[0] = real_width;
3801 height[0] = real_height;
3822 if (!
mainw->jack_inited) lives_jack_init();
3825 jack_audio_read_init();
3827 if (!jack_create_client_writer(
mainw->
jackd)) {
3847 #ifdef HAVE_PULSE_AUDIO
3885 #ifdef HAVE_PULSE_AUDIO
3889 if ((retval = lives_pulse_init(-1))) {
3892 pulse_audio_read_init();
3985 #ifdef HAVE_PULSE_AUDIO
4040 #ifdef HAVE_PULSE_AUDIO
4060 #if !GTK_CHECK_VERSION(3, 0, 0)
4061 #ifdef GDK_WINDOWING_X11
4062 GdkVisual *vissi = NULL;
4084 #ifdef HAVE_PULSE_AUDIO
4120 #if GTK_CHECK_VERSION(3, 0, 0)
4122 #ifdef GDK_WINDOWING_X11
4127 #ifdef GDK_WINDOWING_WIN32
4134 #endif // GDK_WINDOWING
4144 #ifdef GDK_WINDOWING_X11
4145 #if !GTK_CHECK_VERSION(3, 0, 0)
4155 if (!vissi)
return FALSE;
4157 mainw->foreign_cmap = gdk_x11_colormap_foreign_new(vissi,
4158 gdk_x11_colormap_get_xcolormap(gdk_colormap_new(vissi,
TRUE)));
4195 int capture_fd = -1;
4205 if ((capture_fd =
lives_open2(capfile, O_RDONLY)) > -1) {
4207 if ((length = read(capture_fd, capbuf, 256))) {
4209 array = lives_strsplit(capbuf,
"|", 3);
4210 new_frames = atoi(array[1]);
4211 if (new_frames > 0) {
4213 lives_strfreev(array);
4216 lives_snprintf(
cfile->type, 40,
"Frames");
4245 if (
cfile->afilesize > 0 &&
cfile->achans > 0
4253 if (capture_fd > -1) {
4258 if (new_frames == 0) {
4285 for (
int i = 0; i < num_elems; i++)
if (array[i] == value)
return TRUE;
4295 #ifdef GTK_RADIO_MENU_BUG
4312 boolean check_file(
const char *file_name,
boolean check_existing) {
4314 boolean exists =
FALSE;
4317 char *lfile_name = U82F(file_name);
4323 if (lives_file_test(lfile_name, LIVES_FILE_TEST_EXISTS)) {
4324 if (check_existing) {
4333 check = open(lfile_name, O_WRONLY);
4338 check = open(lfile_name, O_CREAT | O_EXCL | O_WRONLY,
DEF_FILE_PERMS);
4342 LiVESResponseType resp = LIVES_RESPONSE_NONE;
4345 if (errno == EACCES)
4349 if (resp == LIVES_RESPONSE_RETRY) {
4429 if (!lives_file_test(to, LIVES_FILE_TEST_EXISTS))
4484 int lives_cat(
const char *from,
const char *to,
boolean append) {
4490 if (append) op =
">>";
4500 int lives_echo(
const char *text,
const char *to,
boolean append) {
4506 if (append) op =
">>";
4551 char test[5] =
"1234";
4553 boolean exists = lives_file_test(dir, LIVES_FILE_TEST_EXISTS);
4556 if (!exists) lives_mkdir_with_parents(dir,
capable->
umask);
4558 if (!lives_file_test(dir, LIVES_FILE_TEST_IS_DIR))
return FALSE;
4560 testfile = lives_build_filename(dir,
"livestst-XXXXXX", NULL);
4561 fp = g_mkstemp(testfile);
4599 if (!exists && !leaveit) {
4608 #if GTK_CHECK_VERSION(2, 14, 0)
4609 LiVESError *err = NULL;
4610 #if GTK_CHECK_VERSION(3, 22, 0)
4611 gtk_show_uri_on_window(NULL, link, GDK_CURRENT_TIME, &err);
4613 gtk_show_uri(NULL, link, GDK_CURRENT_TIME, &err);
4616 char *com = getenv(
"BROWSER");
4624 void activate_url(LiVESAboutDialog * about,
const char *link, livespointer data) {
4630 char *tmp = NULL, *tmp2 = NULL;
4649 while ((fd = open(afile, O_RDONLY)) < 0 &&
lives_alarm_check(alarm_handle) > 0) {
4655 if (fd >= 0) close(fd);
4667 if (
cfile->resample_events) {
4682 if (!list)
return -1;
4684 len = lives_list_length(list);
4686 if (case_sensitive) {
4687 for (i = 0; i < len; i++) {
4688 if (!
lives_strcmp((
const char *)lives_list_nth_data(list, i), (
const char *)data))
return i;
4689 if (!
lives_strcmp((
const char *)lives_list_nth_data(list, i), (
const char *)data))
return i;
4692 for (i = 0; i < len; i++) {
4693 if (!
lives_utf8_strcasecmp((
const char *)lives_list_nth_data(list, i), (
const char *)data))
return i;
4694 if (!
lives_utf8_strcasecmp((
const char *)lives_list_nth_data(list, i), (
const char *)data))
return i;
4704 char *file, *mfile, *prefname;
4709 if (!extra_params || (!(*extra_params))) file = lives_strdup(mfile);
4712 mfile = lives_strdup(filename);
4713 if (!extra_params || (!(*extra_params))) file = lives_strdup(mfile);
4726 for (; i > 0; i--) {
4757 int major = 0, minor = 0, micro = 0;
4771 s = strtok(NULL,
".");
4774 s = strtok(NULL,
".");
4775 if (s) micro = atoi(s);
4779 return major * 1000000 + minor * 1000 + micro;
4787 cfile->undoable = sensitive;
4789 char *what_safe = lives_strdelimit(lives_strdup(what),
"_",
' ');
4790 lives_snprintf(
cfile->undo_text, 32,
_(
"_Undo %s"), what_safe);
4791 lives_snprintf(
cfile->redo_text, 32,
_(
"_Redo %s"), what_safe);
4796 lives_snprintf(
cfile->undo_text, 32,
"%s",
_(
"_Undo"));
4797 lives_snprintf(
cfile->redo_text, 32,
"%s",
_(
"_Redo"));
4816 cfile->redoable = sensitive;
4818 char *what_safe = lives_strdelimit(lives_strdup(what),
"_",
' ');
4819 lives_snprintf(
cfile->undo_text, 32,
_(
"_Undo %s"), what_safe);
4820 lives_snprintf(
cfile->redo_text, 32,
_(
"_Redo %s"), what_safe);
4825 lives_snprintf(
cfile->undo_text, 32,
"%s",
_(
"_Undo"));
4826 lives_snprintf(
cfile->redo_text, 32,
"%s",
_(
"_Redo"));
4839 char *tstr, *frstr, *tmp;
4851 (tmp = lives_strconcat(
"---------- [ ", tstr, (sy = ((
_(
" sec ] ----------Selection---------- [ ")))),
4852 frstr, (sz = (
_(
" frames ] ----------"))), NULL)));
4861 for (; list; list = list->next)
lives_freep((
void **)&list->data);
4866 if (!list || !*list)
return;
4868 lives_slist_free(*list);
4874 if (!list || !*list)
return;
4876 lives_list_free(*list);
4882 lives_speed_cache_t *speedy;
4883 for (LiVESList *xlist = *list; xlist; xlist = xlist->next) {
4884 speedy = (lives_speed_cache_t *)(*list)->data;
4892 lives_list_free(*list);
4899 lives_speed_cache_t *speedy;
4900 LiVESList *ll = cache;
4901 g_print(
"dumping cache %p\n", cache);
4902 for (; ll; ll = ll->next) {
4903 speedy = (lives_speed_cache_t *)ll->data;
4904 g_print(
"cach dets: %s = %s\n", speedy->key, speedy->data);
4910 lives_speed_cache_t *speedy;
4911 LiVESList *list = NULL;
4915 char *key = NULL, *keystr_end = NULL, *cptr, *tmp, *data = NULL;
4917 if (!(hfile = fopen(filename,
"r")))
return NULL;
4918 while (fgets(buff, 65536, hfile)) {
4919 if (!*buff)
continue;
4920 if (*buff ==
'#')
continue;
4923 speedy = (lives_speed_cache_t *)
lives_calloc(1,
sizeof(lives_speed_cache_t));
4926 speedy->data = data;
4930 list = lives_list_prepend(list, speedy);
4935 if (*buff !=
'|')
continue;
4944 if (*buff !=
'<')
continue;
4946 for (cptr = buff; cptr; cptr++) {
4948 kelen = cptr - buff;
4951 key = lives_strdup(buff + 1);
4962 return lives_list_reverse(list);
4968 LiVESList *list = cache;
4970 lives_speed_cache_t *speedy;
4971 for (; list; list = list->next) {
4972 speedy = (lives_speed_cache_t *)list->data;
4973 if (khash == speedy->hash && !
lives_strcmp(key, speedy->key))
4974 return lives_strndup(speedy->data, maxlen);
4985 key = lives_strdup(
"header_version");
break;
4987 key = lives_strdup(
"bpp");
break;
4989 key = lives_strdup(
"fps");
break;
4991 key = lives_strdup(
"pb_fps");
break;
4993 key = lives_strdup(
"width");
break;
4995 key = lives_strdup(
"height");
break;
4997 key = lives_strdup(
"unique_id");
break;
4999 key = lives_strdup(
"audio_rate");
break;
5001 key = lives_strdup(
"pb_audio_rate");
break;
5003 key = lives_strdup(
"audio_channels");
break;
5005 key = lives_strdup(
"audio_signed");
break;
5007 key = lives_strdup(
"audio_endian");
break;
5009 key = lives_strdup(
"audio_sample_size");
break;
5011 key = lives_strdup(
"frames");
break;
5013 key = lives_strdup(
"title");
break;
5015 key = lives_strdup(
"author");
break;
5017 key = lives_strdup(
"comment");
break;
5019 key = lives_strdup(
"keywords");
break;
5021 key = lives_strdup(
"pb_frameno");
break;
5023 key = lives_strdup(
"clipname");
break;
5025 key = lives_strdup(
"filename");
break;
5027 key = lives_strdup(
"interlace");
break;
5029 key = lives_strdup(
"decoder");
break;
5031 key = lives_strdup(
"gamma_type");
break;
5034 if (maxlenp && *maxlenp == 0) *maxlenp = 256;
5041 char *lives_header = NULL;
5042 char *val, *key, *tmp;
5044 int retval2 = LIVES_RESPONSE_NONE;
5056 if (!lives_file_test(lives_header, LIVES_FILE_TEST_EXISTS)) {
5058 lives_header = NULL;
5066 time_t old_time = 0, new_time = 0;
5069 if (!lives_file_test(old_header, LIVES_FILE_TEST_EXISTS)) {
5070 if (!stat(old_header, &mystat)) old_time = mystat.st_mtime;
5071 if (!stat(lives_header, &mystat)) new_time = mystat.st_mtime;
5072 if (old_time > new_time) {
5086 tmp =
lives_strdup_printf(
"Invalid detail %d requested from file %s", which, lives_header);
5096 if (!val)
return FALSE;
5099 if (!val)
return FALSE;
5105 if (retval2 == LIVES_RESPONSE_CANCEL) {
5120 *(
int *)retval = atoi(val);
break;
5124 if (*(
int *)retval == 0 && (!strcasecmp(val,
"false"))) *(
int *)retval = 1;
5127 *(
int *)retval = atoi(val);
5128 if (retval == 0) *(
int *)retval = 1;
5131 *(
int *)retval = atoi(val);
5132 if (retval == 0) *(
int *)retval = sfile->
arps;
5135 *(
int *)retval = atoi(val);
5138 *(
double *)retval = strtod(val, NULL);
5142 *(
double *)retval = strtod(val, NULL);
5143 if (*(
double *)retval == 0.) *(
double *)retval = sfile->
fps;
5147 *(uint64_t *)retval = (uint64_t)atoll(val);
5149 *(uint64_t *)retval = (uint64_t)atol(val);
5153 *(
int *)retval = atoi(val) * 2;
break;
5159 lives_snprintf((
char *)retval, maxlen,
"%s", val);
5163 lives_snprintf((
char *)retval, maxlen,
"%s", (tmp = F2U8(val)));
5182 boolean needs_sigs =
FALSE;
5236 if ((*(
int *)val) == 1) myval = lives_strdup(
"true");
5237 else myval = lives_strdup(
"false");
5251 myval = lives_strdup((
char *)val);
break;
5253 myval = lives_strdup((
char *)val);
break;
5255 myval = lives_strdup((
const char *)val);
break;
5257 myval = lives_strdup((
const char *)val);
break;
5261 myval = lives_strdup((
char *)val);
break;
5263 myval = U82F((
const char *)val);
break;
5265 myval = U82F((
const char *)val);
break;
5309 LiVESList *setlist = NULL;
5310 DIR *tldir, *subdir;
5311 struct dirent *tdirent, *subdirent;
5314 if (!dir)
return NULL;
5316 tldir = opendir(dir);
5318 if (!tldir)
return NULL;
5324 tdirent = readdir(tldir);
5332 if (tdirent->d_name[0] ==
'.'
5333 && (!tdirent->d_name[1] || tdirent->d_name[1] ==
'.'))
continue;
5335 subdirname = lives_build_filename(dir, tdirent->d_name, NULL);
5336 subdir = opendir(subdirname);
5344 subdirent = readdir(subdir);
5345 if (!subdirent)
break;
5347 if (!strcmp(subdirent->d_name,
"order")) {
5349 setlist = lives_list_append(setlist, lives_strdup(tdirent->d_name));
5351 setlist = lives_list_append(setlist, F2U8(tdirent->d_name));
5366 if (strcmp(test_fps_string1, test_fps_string2)) {
5383 char **array = lives_strsplit(
string,
":", 2);
5384 int num = atoi(array[0]);
5385 int denom = atoi(array[1]);
5386 lives_strfreev(array);
5387 fps = (double)num / (
double)denom;
5389 fps = lives_strtod(fps_string, NULL);
5400 for (i = 0; i <= 16; i++) {
5412 if (little_endian) {
5419 if (little_endian) {
5432 if (!
string)
return 0;
5433 if (delim <= 0 || delim > 255)
return 1;
5435 while ((
string = strchr(
string, delim)) != NULL) {
5447 if (pnumber < 0 || pnumber >=
get_token_count(
string, (
int)delim[0]))
return NULL;
5448 array = lives_strsplit(
string, delim, pnumber + 1);
5449 for (i = 0; i < pnumber; i++) {
5450 if (i == pnumber) ret = array[i];
5460 char *s1u = lives_utf8_casefold(s1, -1);
5461 char *s2u = lives_utf8_casefold(s2, -1);
5470 return lives_utf8_collate(s1, s2);
5484 char *
subst(
const char *xstring,
const char *from,
const char *to) {
5491 const size_t fromlen = strlen(from);
5492 const size_t tolen = strlen(to);
5493 const size_t tolim =
BSIZE - tolen;
5496 size_t xtolen = tolen;
5500 size_t retlimit = retsize -
BSIZE;
5502 buff = (
char *)&ubuff;
5504 for (
char *cptr = (
char *)xstring; *cptr; cptr++) {
5505 if (*cptr == from[match++]) {
5506 if (match == fromlen) {
5508 if (bufil > tolim) xtolen =
BSIZE - bufil;
5510 if ((bufil += xtolen) ==
BSIZE) {
5511 if (retfil > retlimit) {
5514 retlimit = (retsize - 1) *
BSIZE;
5519 if (xtolen < tolen) {
5521 bufil += tolen - xtolen;
5530 if (bufil >
BSIZE - match) xtolen =
BSIZE - bufil;
5532 if ((bufil += xtolen) ==
BSIZE) {
5533 if (retfil > retlimit) {
5536 retlimit = (retsize - 1) *
BSIZE;
5541 if (xtolen < fromlen) {
5543 bufil += fromlen - xtolen;
5549 buff[bufil] = *cptr;
5550 if (++bufil ==
BSIZE) {
5551 if (retfil > retlimit) {
5554 retlimit = (retsize - 1) *
BSIZE;
5563 if (retsize > retlimit) {
5571 if (retsize > retlimit) {
5581 if (retsize - retfil > (retsize >> 2)) {
5599 size_t req_size = 1;
5600 size_t tlen, align = 1;
5604 boolean needsnl =
FALSE;
5608 if (!text)
return NULL;
5610 if (maxwidth < 1)
return lives_strdup(
"Bad maxwidth, dummy");
5614 xtoffs = mbtowc(NULL, NULL, 0);
5617 for (i = 0; i < tlen; i += xtoffs) {
5618 xtoffs = mbtowc(&utfsym, &text[i], 4);
5622 return lives_strdup(text);
5625 if (*(text + i) ==
'\n') runlen = 0;
5628 if (needsnl) req_size++;
5631 if (runlen == maxwidth) {
5632 if (i < tlen - 1 && (*(text + i + 1) !=
'\n')) {
5637 }
else needsnl =
FALSE;
5641 xtoffs = mbtowc(NULL, NULL, 0);
5645 retstr = (
char *)
lives_calloc(req_size / align, align);
5652 for (i = 0; i < tlen; i += xtoffs) {
5653 xtoffs = mbtowc(&utfsym, &text[i], 4);
5655 if (*(text + i) ==
'\n') runlen = 0;
5659 *(retstr + req_size) =
'\n';
5664 if (runlen == maxwidth) {
5665 if (i < tlen - 1 && (*(text + i + 1) !=
'\n')) {
5670 }
else needsnl =
FALSE;
5675 *(retstr + req_size) = 0;
5681 static int get_hex_digit(
const char c) {
5683 case 'a':
case 'A':
return 10;
5684 case 'b':
case 'B':
return 11;
5685 case 'c':
case 'C':
return 12;
5686 case 'd':
case 'D':
return 13;
5687 case 'e':
case 'E':
return 14;
5688 case 'f':
case 'F':
return 15;
5689 default:
return c - 48;
5696 for (
char c = *
string; c; c = *(++string)) tot = (tot << 4) + get_hex_digit(c);
5706 struct statvfs sbuf;
5707 if (!lives_file_test(dir, LIVES_FILE_TEST_IS_DIR)) {
5709 if (!lives_file_test(dir, LIVES_FILE_TEST_IS_DIR)) {
5715 if (statvfs(dir, &sbuf) == -1)
return FALSE;
5716 if (sbuf.f_flag & ST_RDONLY)
return FALSE;
5724 int ret = lives_mkdir_with_parents(newdir,
capable->
umask);
5725 int myerrno = errno;
5728 if (myerrno == EINVAL) {
5746 return LIVES_INTERP_BEST;
5750 return LIVES_INTERP_BEST;
5756 LiVESList *list = NULL;
5758 char *buf, **array = lives_strsplit(buffer, delim, pieces);
5759 boolean biglist = pieces >=
BL_LIM;
5760 for (
int i = 0; i < pieces; i++) {
5762 if (strip) buf = lives_strstrip(array[i]);
5763 else buf = array[i];
5764 if (*buf || allow_blanks) {
5765 if (biglist) list = lives_list_prepend(list, lives_strdup(buf));
5766 else list = lives_list_append(list, lives_strdup(buf));
5770 lives_strfreev(array);
5771 if (biglist && list)
return lives_list_reverse(list);
5777 LiVESList *list = xlist, *listlast = NULL;
5783 list = lives_list_append(listlast, lives_strdup(add));
5784 if (!xlist)
return list;
5791 LiVESList *xlist = item;
5792 if (xlist == list || !xlist)
return list;
5793 if (xlist->prev) xlist->prev->next = xlist->next;
5794 if (xlist->next) xlist->next->prev = xlist->prev;
5796 if ((xlist->next = list) != NULL) list->prev = xlist;
5804 LiVESList *xlist = list;
5805 for (; xlist; xlist = xlist->next) {
5808 if (xlist->prev) xlist->prev->next = xlist->next;
5810 if (xlist->next) xlist->next->prev = xlist->prev;
5811 xlist->next = xlist->prev = NULL;
5812 lives_list_free(xlist);
5822 LiVESList *xlist = NULL, *olist = list;
5824 xlist = lives_list_prepend(xlist, lives_strdup((
char *)olist->data));
5825 olist = olist->next;
5827 return lives_list_reverse(xlist);
5836 LiVESList *plist, *rlist = blist;
5838 if (lives_list_length(alist) != lives_list_length(blist))
return TRUE;
5844 LiVESList *qlist = rlist;
5845 boolean matched =
TRUE;
5848 if (matched) rlist = qlist->next;
5852 qlist = qlist->next;
5854 if (!qlist)
return TRUE;
5855 plist = plist->next;
LIVES_GLOBAL_INLINE void d_print_done(void)
char * lives_format_storage_space_string(uint64_t space)
int lives_system(const char *com, boolean allow_error)
#define LIVES_GLOBAL_INLINE
LiVESTextBuffer * layout_textbuffer
stores layout errors
void * jackd
jack audio player / transport
int lives_cp_recursive(const char *from, const char *to, boolean incl_dir)
uint8_t * ptr
buffer size for write, bytes left to read in case of read
LiVESList * get_set_list(const char *dir, boolean utf8)
boolean do_std_checks(const char *type_name, const char *type, size_t maxlen, const char *nreject)
@ CLIP_DETAILS_HEADER_VERSION
void calc_aframeno(int fileno)
#define LIVES_LOCAL_INLINE
#define LIVES_CLIP_HEADER_OLD
LiVESWidget * m_mutebutton
char * get_nth_token(const char *string, const char *delim, int pnumber)
boolean after_foreign_play(void)
double fixed_fpsd
<=0. means free playback
LiVESWidget * recent[N_RECENT_FILES]
void minimise_aspect_delta(double aspect, int hblock, int vblock, int hsize, int vsize, int *width, int *height)
#define JACK_OPTS_NOPLAY_WHEN_PAUSED
play audio even when transport paused
boolean ensure_isdir(char *fname)
lives_img_type_t resolve_img_type(lives_clip_t *sfile)
volatile off64_t aseek_pos
audio seek posn. (bytes) for when we switch clips
#define BUFF_SIZE_WRITE_SMALLMED
#define PREF_REC_EXT_AUDIO
boolean is_writeable_dir(const char *dir)
LIVES_GLOBAL_INLINE int lives_create_buffered_nosync(const char *pathname, int mode)
lives_mgeometry_t * mgeom
multi-head support
boolean do_progress_dialog(boolean visible, boolean cancellable, const char *text)
LIVES_GLOBAL_INLINE char * lives_get_audio_file_name(int fnum)
LIVES_GLOBAL_INLINE void get_filename(char *filename, boolean strip_dir)
char * get_extension(const char *filename)
boolean do_yesno_dialogf(const char *fmt,...)
void break_me(const char *brkstr)
LIVES_GLOBAL_INLINE LiVESInterpType get_interp_value(short quality, boolean low_for_mt)
char * get_val_from_cached_list(const char *key, size_t maxlen, LiVESList *cache)
#define WEED_LEAF_HOST_FLAGS
LiVESList * file_buffers
list of open files for buffered i/o
void add_to_recent(const char *filename, double start, frames_t frames, const char *extra_params)
boolean prepare_to_play_foreign(void)
#define USEC_TO_TICKS
multiplying factor uSec -> ticks_t (def. 100)
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_new(int layer_type)
char workdir[PATH_MAX]
kept in locale encoding
LIVES_GLOBAL_INLINE boolean lives_unsetenv(const char *name)
LiVESWidget * p_mutebutton
const char * version(void)
void wait_for_bg_audio_sync(int fileno)
frames_t calc_new_playback_position(int fileno, ticks_t otc, ticks_t *ntc)
LIVES_GLOBAL_INLINE lives_img_type_t lives_image_type_to_img_type(const char *lives_img_type)
volatile boolean is_exiting
set during shutdown (inverse of only_close then)
#define BUFFER_FILL_BYTES_LARGE
#define IS_VALID_CLIP(clip)
boolean crash_recovery
TRUE==maintain mainw->recovery file.
boolean get_frames_sizes(int fileno, int frame, int *hsize, int *vsize)
_vid_playback_plugin * vpp
video plugin
LiVESResponseType do_file_perm_error(const char *file_name, boolean allow_cancel)
char * repl_workdir(const char *entry, boolean fwd)
#define LIVES_IMAGE_TYPE_UNKNOWN
void * ext_src
points to opaque source for non-disk types
boolean show_overlay_msgs
int count_resampled_frames(int in_frames, double orig_fps, double resampled_fps)
boolean d_print_urgency(double timeout, const char *fmt,...)
int bigendbug
default 0; 1==use old (bad) behaviour on bigendian machines (r/w bigend ints/doubles); 2==bad reads,...
LIVES_GLOBAL_INLINE boolean do_set_locked_warning(const char *setname)
#define LIVES_OSC_NOTIFY_NONE
ssize_t lives_read(int fd, void *buf, ssize_t count, boolean allow_less)
#define AUDIO_PLAYER_NONE
#define BUFFER_FILL_BYTES_BIGMED
LIVES_GLOBAL_INLINE int weed_layer_get_width(weed_layer_t *layer)
#define LIVES_WEED_SUBTYPE_MESSAGE
LIVES_GLOBAL_INLINE void d_print_failed(void)
boolean clip_switched
for recording - did we switch clips ?
frames_t frames
number of video frames
boolean check_frame_count(int idx, boolean last_checked)
check number of frames is correct for files of type CLIP_TYPE_DISK
LiVESWidget * play_window
#define LIVES_MANUAL_FILENAME
#define LIVES_LAYER_GET_SIZE_ONLY
LIVES_GLOBAL_INLINE boolean lives_strcmp(const char *st1, const char *st2)
returns FALSE if strings match
boolean lives_read_buffered_eof(int fd)
char backend[PATH_MAX *4]
LIVES_GLOBAL_INLINE const char * get_image_ext_for_type(lives_img_type_t imgtype)
volatile boolean video_seek_ready
#define JACK_OPTS_TRANSPORT_CLIENT
jack can start/stop
LIVES_GLOBAL_INLINE boolean lives_fsync(int fd)
#define LIVES_FILE_EXT_JPG
void pad_init_silence(void)
int64_t get_best_audio(_vid_playback_plugin *vpp)
boolean string_lists_differ(LiVESList *alist, LiVESList *blist)
#define LIVES_DIRECTION_PAR(dir)
#define BUFFER_FILL_BYTES_MED
LIVES_GLOBAL_INLINE void d_print_file_error_failed(void)
#define WORKDIR_LITERAL_LEN
LIVES_GLOBAL_INLINE void d_print_cancelled(void)
LIVES_GLOBAL_INLINE uint64_t get_approx_ln64(uint64_t x)
@ LIVES_STRING_CONSTANT_CL
"the current layout"
@ LIVES_DIRECTION_FORWARD
int lives_rmdir(const char *dir, boolean force)
pthread_mutex_t alarmlist_mutex
append / remove with file_buffer list
char * remove_trailing_zeroes(double val)
char * ensure_extension(const char *fname, const char *ext)
int lives_echo(const char *text, const char *to, boolean append)
char backend_sync[PATH_MAX *4]
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
int lives_open_buffered_writer(const char *pathname, int mode, boolean append)
size_t lives_buffered_orig_size(int fd)
void mt_init_clips(lives_mt *mt, int orig_file, boolean add)
int free_n_msgs(int frval)
LIVES_GLOBAL_INLINE int weed_layer_get_height(weed_layer_t *layer)
int osc_auto
bypass user choices automatically
off_t lives_lseek_buffered_writer(int fd, off_t offset)
@ CLIP_TYPE_GENERATOR
frames from generator plugin
void add_to_clipmenu(void)
ssize_t lives_write_buffered(int fd, const char *buf, ssize_t count, boolean allow_fail)
#define BUFF_SIZE_READ_MED
#define TICKS_PER_SECOND
ticks per second - GLOBAL TIMEBASE
int lives_cat(const char *from, const char *to, boolean append)
void do_chdir_failed_error(const char *dir)
volatile boolean agen_needs_reinit
LIVES_GLOBAL_INLINE boolean lives_freep(void **ptr)
ticks_t cadjticks
used to equalise the timecode between alternate timer sources (clock -> source adjustment)
LiVESWidget * show_layout_errors
void remove_current_from_affected_layouts(lives_mt *mt)
@ LIVES_TIME_SOURCE_SYSTEM
#define lives_nanosleep(nanosec)
LIVES_GLOBAL_INLINE ticks_t q_gint64_floor(ticks_t in, double fps)
weed_event_t * event_list
current event_list, for recording
unsigned char * sl_undo_mem
void get_location(const char *exe, char *val, int maxlen)
weed_plant_t * ref_message
void show_manual_section(const char *lang, const char *section)
#define JACK_OPTS_TIMEBASE_CLIENT
full timebase client
#define BUFF_SIZE_READ_SMALLMED
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
#define BUFF_SIZE_READ_SMALL
#define WEED_LAYER_TYPE_VIDEO
LIVES_GLOBAL_INLINE int lives_create_buffered(const char *pathname, int mode)
LIVES_GLOBAL_INLINE char * lives_pad(char *txt, size_t minlen, int align)
#define LIVES_SHORTEST_TIMEOUT
void end_threaded_dialog(void)
void threaded_dialog_spin(double fraction)
lives_img_type_t img_type
boolean check_for_executable(lives_checkstatus_t *cap, const char *exec)
int pheight
playback height
lives_pgid_t lives_fork(const char *com)
@ CLIP_TYPE_DISK
imported video, broken into frames
char * string_constants[NUM_LIVES_STRING_CONSTANTS]
int lives_rmdir_with_parents(const char *dir)
@ LIVES_TIME_SOURCE_EXTERNAL
LIVES_GLOBAL_INLINE LiVESList * lives_list_sort_alpha(LiVESList *list, boolean fwd)
char * clip_detail_to_string(lives_clip_details_t what, size_t *maxlenp)
LIVES_GLOBAL_INLINE char * lives_get_filename(char *uri)
return filename (no dir, no .ext)
LIVES_GLOBAL_INLINE char * lives_ellipsize(char *txt, size_t maxlen, LiVESEllipsizeMode mode)
LIVES_GLOBAL_INLINE void msg_area_scroll_to_end(LiVESWidget *widget, LiVESAdjustment *adj)
volatile lives_whentostop_t whentostop
lives_direction_t
use REVERSE / FORWARD when a sign is used, BACKWARD / FORWARD when a parity is used
size_t lives_fread_string(char *buff, size_t stlen, const char *fname)
int lives_rm(const char *file)
volatile boolean loop_cont
@ MISSING
not yet implemented (TODO)
boolean switch_aud_to_pulse(boolean set_in_prefs)
boolean check_dir_access(const char *dir, boolean leaveit)
void get_dirname(char *filename)
volatile lives_cancel_t cancelled
ticks_t lives_get_current_playback_ticks(int64_t origsecs, int64_t orignsecs, lives_time_source_t *time_source)
volatile uint32_t audio_opts
#define is_realtime_aplayer(ptype)
LiVESAdjustment * msg_adj
int add_messages_to_list(const char *text)
void lives_invalidate_all_file_buffers(void)
@ CLIP_DETAILS_PB_FRAMENO
void d_print(const char *fmt,...)
off_t lives_lseek_buffered_rdonly(int fd, off_t offset)
LIVES_GLOBAL_INLINE ssize_t lives_readlink(const char *path, char *buf, size_t bufsiz)
#define BUFF_SIZE_WRITE_SMALL
#define CLIP_TOTAL_TIME(clip)
@ LMAP_ERROR_SHIFT_FRAMES
off_t lives_buffered_offset(int fd)
lives_proc_thread_t lives_proc_thread_create(lives_thread_attr_t attr, lives_funcptr_t func, int return_type, const char *args_fmt,...)
create the specific plant which defines a background task to be run
#define LIVES_EXT_SRC_DECODER
void reset_playback_clock(void)
LIVES_GLOBAL_INLINE int calc_frame_from_time2(int filenum, double time)
nearest frame [1, frames+1]
#define SCRATCH_FWD_EXTRA
boolean preview_rendering
ssize_t lives_write_le(int fd, const void *buf, ssize_t count, boolean allow_fail)
ssize_t lives_read_buffered(int fd, void *buf, ssize_t count, boolean allow_less)
#define BUFF_SIZE_WRITE_BIGMED
void switch_to_file(int old_file, int new_file)
@ LIVES_DIRECTION_REVERSE
boolean check_for_ratio_fps(double fps)
LiVESWidget * ext_audio_checkbutton
void set_undoable(const char *what, boolean sensitive)
#define LIVES_URGENCY_ALARM
#define BUFFER_FILL_BYTES_SMALL
fixed values only for write buffers (must be multiples of 16)
LiVESWidget * preview_box
size_t get_token_count(const char *string, int delim)
lives_alarm_t overlay_alarm
#define INSTALL_CANLOCAL
install guidance flags
#define LIVES_OSC_NOTIFY_CANCELLED
for OSC only (not for C++)
volatile ticks_t clock_ticks
unadjusted system time since pb start, measured concurrently with currticks
ticks_t deltaticks
deltaticks for scratching
LIVES_GLOBAL_INLINE void get_play_times(void)
recalculate video / audio lengths and draw the timer bars
@ CANCEL_VID_END
video playback completed
LiVESWidget * spinbutton_end
@ CLIP_TYPE_FILE
unimported video, not or partially broken in frames
boolean lives_string_ends_with(const char *string, const char *fmt,...)
void(* SignalHandlerPointer)(int)
char * filename_from_fd(char *val, int fd)
: return filename from an open fd, freeing val first
LIVES_GLOBAL_INLINE float LEFloat_to_BEFloat(float f)
void unbuffer_lmap_errors(boolean add)
char * get_dir(const char *filename)
LIVES_GLOBAL_INLINE void swab4(const void *from, const void *to, size_t gran)
boolean playing_sel
list of set names in current workdir, mau be NULL
LiVESWidget * spinbutton_start
#define BUFFER_FILL_BYTES_SMALLMED
LiVESWidget * recaudio_submenu
ssize_t lives_write_le_buffered(int fd, const void *buf, ssize_t count, boolean allow_fail)
#define AUDIO_PLAYER_JACK
boolean switch_aud_to_jack(boolean set_in_prefs)
boolean pref_factory_bool(const char *prefidx, boolean newval, boolean permanent)
LIVES_GLOBAL_INLINE int lives_open3(const char *pathname, int flags, mode_t mode)
boolean ratio_fps
framerate of the clip
int resize_all(int fileno, int width, int height, lives_img_type_t imgtype, boolean do_back, int *nbad, int *nmiss)
utility funcs for GUI
void calc_midspect(int rwidth, int rheight, int *cwidth, int *cheight)
#define SCRATCH_JUMP_NORESYNC
jump with no audio resync
int scrap_file
we throw odd sized frames here when recording in real time; used if a source is a generator or stream
off_t get_file_size(int fd)
lives_clip_t * create_cfile(int new_file, const char *handle, boolean is_loaded)
set default values for a clip (in memory)
@ LIVES_DIRECTION_BACKWARD
LIVES_GLOBAL_INLINE void reverse_bytes(char *buff, size_t count, size_t gran)
void reset_clipmenu(void)
LiVESXWindow * foreign_window
lives_alarm_t lives_alarm_set(ticks_t ticks)
set alarm for now + delta ticks (10 nanosec) param ticks (10 nanoseconds) is the offset when we want ...
#define CURRENT_CLIP_HAS_VIDEO
boolean dirs_equal(const char *dira, const char *dirb)
boolean show_urgency_msgs
#define PREF_AUDIO_PLAYER
boolean resync_audio(double frameno)
resync audio playback to the current video frame
boolean memok
set to FALSE if a segfault is received, ie. we should assume all memory is corrupted and exit ASAP
void update_play_times(void)
like get_play_times, but will force redraw of audio waveforms
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
#define P_(String, StringPlural, n)
LIVES_GLOBAL_INLINE int calc_frame_from_time(int filenum, double time)
nearest frame [1, frames]
@ LMAP_INFO_SETNAME_CHANGED
LIVES_GLOBAL_INLINE LiVESList * lives_list_move_to_first(LiVESList *list, LiVESList *item)
LIVES_GLOBAL_INLINE boolean int_array_contains_value(int *array, int num_elems, int value)
void print_cache(LiVESList *cache)
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
ssize_t lives_buffered_write_printf(int fd, boolean allow_fail, const char *fmt,...)
LiVESList * cache_file_contents(const char *filename)
void autotune_u64(weed_plant_t *tuner, uint64_t min, uint64_t max, int ntrials, double cost)
LIVES_GLOBAL_INLINE char * lives_strstop(char *st, const char term)
void * pulsed
pulseaudio player
void zero_spinbuttons(void)
double get_ratio_fps(const char *string)
LIVES_GLOBAL_INLINE boolean do_warning_dialog(const char *text)
double aframeno
and the audio 'frame' for when we are looping
LIVES_GLOBAL_INLINE LiVESList * lives_list_append_unique(LiVESList *xlist, const char *add)
frames_t rec_vid_frames
values to be written to the event list concurrent with next video ftame event
void activate_url_inner(const char *link)
void add_to_recovery_file(const char *handle)
void remove_layout_files(LiVESList *map)
LIVES_GLOBAL_INLINE uint64_t get_near2pow(uint64_t val)
LIVES_GLOBAL_INLINE uint64_t lives_10pow(int pow)
LIVES_GLOBAL_INLINE int lives_killpg(lives_pgid_t pgrp, int sig)
boolean _lives_buffered_rdonly_slurp(int fd, off_t skip)
#define LIVES_CLIP_HEADER
int *(* get_audio_fmts)(void)
error("LSD_RANDFUNC(ptr, size) must be defined")
#define BUFF_SIZE_READ_LARGE
void calc_minspect(int rwidth, int rheight, int *cwidth, int *cheight)
weed_event_t * stored_event_list
stored mt -> clip editor
LIVES_GLOBAL_INLINE const char * image_ext_to_lives_image_type(const char *img_ext)
ticks_t adjticks
used to equalise the timecode between alternate timer sources (souce -> clock adjustment)
LIVES_GLOBAL_INLINE boolean lives_setenv(const char *name, const char *value)
LIVES_LOCAL_INLINE lives_presence_t has_executable(const char *exe)
char * dump_messages(int start, int end)
LIVES_GLOBAL_INLINE ticks_t lives_get_current_ticks(void)
@ LMAP_ERROR_MISSING_CLIP
@ CLIP_DETAILS_DECODER_NAME
void do_threaded_dialog(const char *trans_text, boolean has_cancel)
ticks_t syncticks
adjustment to compensate for missed clock updates when switching time sources
int arps
audio physical sample rate (i.e the "normal" sample rate of the clip when played at 1,...
pthread_mutex_t fbuffer_mutex
LIVES_GLOBAL_INLINE void clear_mainw_msg(void)
void catch_sigint(int signum)
#define lives_strdup_printf(fmt,...)
LIVES_GLOBAL_INLINE void cached_list_free(LiVESList **list)
boolean add_lmap_error(lives_lmap_error_t lerror, const char *name, livespointer user_data, int clipno, int frameno, double atime, boolean affects_current)
#define LIVES_MAX_USER_ALARMS
frames_t tcache_dubious_from
height for thumbnail cache (width is fixed, but if this changes, invalidate)
char * insert_newlines(const char *text, int maxwidth)
#define LIVES_IMAGE_TYPE_JPEG
LIVES_GLOBAL_INLINE int calc_frame_from_time3(int filenum, double time)
nearest frame rounded down, [1, frames+1]
boolean dirchange_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer area_enum)
char * lives_fgets(char *s, int size, FILE *stream)
weed_plant_t weed_layer_t
LIVES_GLOBAL_INLINE char * lives_pad_ellipsize(char *txt, size_t fixlen, int palign, LiVESEllipsizeMode emode)
void clear_lmap_errors(void)
LiVESWidget * t_infobutton
LIVES_GLOBAL_INLINE int lives_open_buffered_rdonly(const char *pathname)
#define LIVES_OSC_NOTIFY_FAILED
for OSC only (not for C++)
boolean get_clip_value(int which, lives_clip_details_t what, void *retval, size_t maxlen)
#define LIVES_MAIN_WINDOW_WIDGET
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
int lives_cp(const char *from, const char *to)
boolean checked_for_old_header
#define LIVES_THRDATTR_NONE
int lives_close_buffered(int fd)
int ascrap_file
scrap file for recording audio scraps
#define PB_QUALITY_MED
default
void close_clip_decoder(int clipno)
#define AUDIO_OPTS_FOLLOW_FPS
LIVES_GLOBAL_INLINE LiVESList * buff_to_list(const char *buffer, const char *delim, boolean allow_blanks, boolean strip)
#define WEED_LEAF_LIVES_MESSAGE_STRING
#define SCREEN_AREA_FOREGROUND
LIVES_GLOBAL_INLINE size_t lives_strlen(const char *s)
LIVES_GLOBAL_INLINE void lives_sync(int times)
ssize_t lives_write(int fd, const void *buf, ssize_t count, boolean allow_fail)
boolean check_file(const char *file_name, boolean check_existing)
check if file exists
#define CURRENT_CLIP_IS_NORMAL
LIVES_GLOBAL_INLINE int lives_utf8_strcmp(const char *s1, const char *s2)
size_t lives_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
lives_timeout_t alarms[LIVES_MAX_ALARMS]
reserve 1 for emergency msgs
char home_dir[PATH_MAX]
home directory - default location for config file - locale encoding
LiVESList * hdrs_cache
cache of a file header (e.g. header.lives)
LIVES_GLOBAL_INLINE lives_alarm_t lives_alarm_reset(lives_alarm_t alarm_handle, ticks_t ticks)
weed_plant_t * get_nth_info_message(int n)
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
LIVES_GLOBAL_INLINE void get_basename(char *filename)
LIVES_GLOBAL_INLINE int lives_kill(lives_pid_t pid, int sig)
#define CURRENT_CLIP_IS_VALID
boolean is_legal_set_name(const char *set_name, boolean allow_dupes, boolean leeway)
uint8_t * buffer
read point in buffer
char ar_layout_name[PATH_MAX]
locale
#define LIVES_IMAGE_TYPE_PNG
LIVES_GLOBAL_INLINE void lives_list_free_all(LiVESList **list)
boolean suppress_dprint
tidy up, e.g. by blocking "switched to file..." and "closed file..." messages
LiVESWidget * int_audio_checkbutton
int lives_chdir(const char *path, boolean no_error_dlg)
int aud_rec_fd
fd of file we are recording audio to
int lives_list_strcmp_index(LiVESList *list, livesconstpointer data, boolean case_sensitive)
int lives_touch(const char *tfile)
volatile boolean record_paused
pause during recording
#define SCRATCH_REV
set on direction change (video)
LiVESResponseType do_write_failed_error_s_with_retry(const char *fname, const char *errtext)
void mt_clip_select(lives_mt *mt, boolean scroll)
int last_dprint_file
message output settings
LiVESList * current_layouts_map
map of all layouts for set
@ CLIP_DETAILS_GAMMA_TYPE
LIVES_GLOBAL_INLINE uint32_t fast_hash(const char *key)
#define MAX_FILES
max files is actually 1 more than this, since file 0 is the clipboard
#define LIVES_FILE_EXT_TMP
#define MAX_SET_NAME_LEN
sets
void stored_event_list_free_all(boolean wiped)
void get_total_time(lives_clip_t *file)
calculate laudio, raudio and video time (may be deprecated and replaced with macros)
void switch_aud_to_none(boolean set_in_prefs)
void lives_notify(int msgnumber, const char *msgstring)
uint32_t get_signed_endian(boolean is_signed, boolean little_endian)
produce bitmapped value
void set_signal_handlers(SignalHandlerPointer sigfunc)
boolean ext_playback
using external video playback plugin
#define BUFF_SIZE_WRITE_LARGE
uint64_t autotune_u64_end(weed_plant_t **tuner, uint64_t val)
LIVES_GLOBAL_INLINE void d_print_enough(int frames)
void lives_buffered_rdonly_slurp(int fd, off_t skip)
#define BUFF_SIZE_WRITE_MED
ssize_t lives_read_le(int fd, void *buf, ssize_t count, boolean allow_less)
uint64_t get_version_hash(const char *exe, const char *sep, int piece)
LiVESList * affected_layouts_map
map of layouts with errors
lives_cursor_t cursor_style
off_t offset
ptr to data (ptr - buffer + bytes) gives the read size
void lives_kill_subprocesses(const char *dirname, boolean kill_parent)
#define AUDIO_PLAYER_PULSE
used in pref and for external players (e.g -ao pulse, -aplayer pulse)
int lives_rmglob(const char *files)
boolean force_system_clock
lives_file_buffer_t * find_in_file_buffers_by_pathname(const char *pathname)
#define LIVES_OSC_NOTIFY_CLIP_OPENED
sent after a clip is opened
LIVES_GLOBAL_INLINE void lives_slist_free_all(LiVESSList **list)
int get_frame_count(int idx, int start)
sets mainw->files[idx]->frames with current framecount
LIVES_GLOBAL_INLINE uint32_t get_approx_ln(uint32_t x)
double pb_fps
current playback rate, may vary from fps, can be 0. or negative
LIVES_GLOBAL_INLINE LiVESList * lives_list_copy_strings(LiVESList *list)
#define WARN_MASK_LAYOUT_MISSING_CLIPS
void update_timer_bars(int posx, int posy, int width, int height, int which)
draw the timer bars
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_free(weed_layer_t *layer)
frees pixel_data for a layer, then the layer itself
void buffer_lmap_error(lives_lmap_error_t lerror, const char *name, livespointer user_data, int clipno, int frameno, double atime, boolean affects_current)
LIVES_GLOBAL_INLINE char * lives_chomp(char *buff)
lives_checkstatus_t has_sox_play
LiVESResponseType get_utf8_pref(const char *key, char *val, int maxlen)
lives_clip_t * cbstores[8]
@ LMAP_ERROR_DELETE_FRAMES
LIVES_GLOBAL_INLINE char * make_image_file_name(lives_clip_t *sfile, frames_t frame, const char *img_ext)
lives_image_type can be a string, lives_img_type_t is an enumeration
void *(* lives_funcptr_t)(void *)
ssize_t lives_read_le_buffered(int fd, void *buf, ssize_t count, boolean allow_less)
void resize(double scale)
volatile ticks_t lastcheck
ssize_t lives_popen(const char *com, boolean allow_error, char *buff, ssize_t buflen)
char * get_menu_name(lives_clip_t *sfile, boolean add_setname)
LIVES_GLOBAL_INLINE int hextodec(const char *string)
#define LIVES_WEED_SUBTYPE_TUNABLE
corresponds to one clip in the GUI
void set_sel_label(LiVESWidget *sel_label)
void defer_sigint(int signum)
LIVES_GLOBAL_INLINE void * lives_calloc_safety(size_t nmemb, size_t xsize)
void activate_url(LiVESAboutDialog *about, const char *link, livespointer data)
LIVES_GLOBAL_INLINE void lives_list_free_strings(LiVESList *list)
char audio_play_command[PATH_MAX *2]
off_t lives_lseek_buffered_rdonly_absolute(int fd, off_t offset)
boolean d_print_overlay(double timeout, const char *fmt,...)
void lives_suspend_resume_process(const char *dirname, boolean suspend)
lives_file_buffer_t * find_in_file_buffers(int fd)
#define lives_nanosleep_until_nonzero(condition)
#define BUFF_SIZE_READ_CUSTOM
@ CANCEL_AUD_END
video playback completed
boolean switch_aud_to_sox(boolean set_in_prefs)
LIVES_GLOBAL_INLINE double calc_time_from_frame(int clip, int frame)
lives_time_source_t
timebase sources
@ LMAP_ERROR_ALTER_FRAMES
volatile boolean ping_pong
boolean check_for_lock_file(const char *set_name, int type)
check for set lock file do this via the back-end (smogrify) this allows for the locking scheme to be ...
int lives_utf8_strcasecmp(const char *s1, const char *s2)
void calc_maxspect(int rwidth, int rheight, int *cwidth, int *cheight)
int asampsize
audio sample size in bits (8 or 16)
volatile int agen_key
which fx key is generating audio [1 based] (or 0 for none)
LIVES_GLOBAL_INLINE weed_plant_t * lives_plant_new_with_index(int subtype, int64_t index)
int lives_cp_keep_perms(const char *from, const char *to)
int lives_mv(const char *from, const char *to)
#define WEED_LEAF_LIVES_SUBTYPE
LIVES_GLOBAL_INLINE size_t get_max_align(size_t req_size, size_t align_max)
int lives_ln(const char *from, const char *to)
LIVES_GLOBAL_INLINE lives_img_type_t lives_image_ext_to_img_type(const char *img_ext)
#define SCRATCH_JUMP
jump and resync audio
this struct is used only when physically resampling frames on the disk we create an array of these an...
LiVESWidget * vol_toolitem
#define LIVES_FILE_EXT_PNG
void save_layout_map(int *lmap, double *lmap_audio, const char *file, const char *dir)
#define DEF_FILE_PERMS
non-executable, is modified by the umask
char * unhash_version(uint64_t version)
LIVES_GLOBAL_INLINE double lives_fix(double val, int decimals)
boolean save_clip_values(int which_file)
int arate
current audio playback rate (varies if the clip rate is changed)
LIVES_GLOBAL_INLINE int lives_open2(const char *pathname, int flags)
char * subst(const char *xstring, const char *from, const char *to)
boolean perm_audio_reader
void init_clipboard(void)
LiVESList * affected_layout_marks
list of pairs of marks in affected_layouts_map, text between them should be deleted when stored_layou...
size_t get_read_buff_size(int sztype)
boolean create_event_space(int length)
@ LMAP_ERROR_DELETE_AUDIO
lives_direction_t adirection
audio play direction during playback, FORWARD or REVERSE.
boolean clip_can_reverse(int clipno)
LIVES_GLOBAL_INLINE boolean lives_buffered_rdonly_set_reversed(int fd, boolean val)
#define IS_NORMAL_CLIP(clip)
@ LIVES_TIME_SOURCE_SOUNDCARD
LiVESResponseType do_error_dialogf(const char *fmt,...)
LIVES_GLOBAL_INLINE LiVESResponseType get_pref_from_file(const char *filename, const char *key, char *val, int maxlen)
LiVESResponseType do_system_failed_error(const char *com, int retval, const char *addinfo, boolean can_retry, boolean trysudo)
LiVESList * lives_list_delete_string(LiVESList *list, const char *string)
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
int achans
number of audio channels (0, 1 or 2)
boolean save_clip_value(int which, lives_clip_details_t what, void *val)
LIVES_GLOBAL_INLINE int calc_frame_from_time4(int filenum, double time)
nearest frame, no maximum
int lives_fputs(const char *s, FILE *stream)
#define SCRATCH_BACK_EXTRA
void find_when_to_stop(void)
int lives_chmod(const char *target, const char *mode)
#define LIVES_ACLIP_HEADER
boolean weed_layer_create_from_file_progressive(weed_layer_t *layer, const char *fname, int width, int height, int tpalette, const char *img_ext)
LIVES_GLOBAL_INLINE ticks_t lives_get_relative_ticks(ticks_t origsecs, ticks_t orignsecs)
int set_string_pref(const char *key, const char *value)
LIVES_GLOBAL_INLINE boolean lives_strncmp(const char *st1, const char *st2, size_t len)
returns FALSE if strings match
boolean lives_make_writeable_dir(const char *newdir)
#define MAINW_MSG_SIZE
mainw->msg bytesize
boolean foreign
for external window capture
uint64_t make_version_hash(const char *ver)
LIVES_GLOBAL_INLINE void * lives_recalloc(void *p, size_t nmemb, size_t omemb, size_t xsize)
#define WEED_LEAF_PREVIOUS
#define AV_TRACK_MIN_DIFF
ignore track time differences < this (seconds)
void set_redoable(const char *what, boolean sensitive)
int set_utf8_pref(const char *key, const char *value)
boolean get_new_handle(int index, const char *name)
LiVESList * new_lmap_errors