LMMS
Loading...
Searching...
No Matches
PluginDiscovery.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "CarlaUtils.h"
5
6#include "CarlaBackendUtils.hpp"
7#include "CarlaBinaryUtils.hpp"
8#include "CarlaJuceUtils.hpp"
9#include "CarlaPipeUtils.hpp"
10#include "CarlaSha1Utils.hpp"
11#include "CarlaTimeUtils.hpp"
12
13#include "water/files/File.h"
17
18namespace CB = CARLA_BACKEND_NAMESPACE;
19
20// --------------------------------------------------------------------------------------------------------------------
21
22#ifndef CARLA_OS_WIN
23static water::String findWinePrefix(const water::String filename, const int recursionLimit = 10)
24{
25 if (recursionLimit == 0 || filename.length() < 5 || ! filename.contains("/"))
26 return "";
27
28 const water::String path(filename.upToLastOccurrenceOf("/", false, false));
29
30 if (water::File(path + "/dosdevices").isDirectory())
31 return path;
32
33 return findWinePrefix(path, recursionLimit-1);
34}
35#endif
36
37// --------------------------------------------------------------------------------------------------------------------
38
39static const char* const gPluginsDiscoveryNullCharPtr = "";
40
41_CarlaPluginDiscoveryMetadata::_CarlaPluginDiscoveryMetadata() noexcept
44 category(CB::PLUGIN_CATEGORY_NONE),
45 hints(0x0) {}
46
47_CarlaPluginDiscoveryIO::_CarlaPluginDiscoveryIO() noexcept
48 : audioIns(0),
49 audioOuts(0),
50 cvIns(0),
51 cvOuts(0),
52 midiIns(0),
53 midiOuts(0),
54 parameterIns(0),
55 parameterOuts(0) {}
56
57_CarlaPluginDiscoveryInfo::_CarlaPluginDiscoveryInfo() noexcept
58 : btype(CB::BINARY_NONE),
59 ptype(CB::PLUGIN_NONE),
62 uniqueId(0),
63 metadata() {}
64
65// --------------------------------------------------------------------------------------------------------------------
66
68 #if !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH) && !defined(CARLA_OS_WIN)
69 struct {
71 CarlaString executable;
72 CarlaString fallbackPrefix;
74 #endif
75
77 {
78 static CarlaPluginDiscoveryOptions instance;
79 return instance;
80 }
81};
82
83// --------------------------------------------------------------------------------------------------------------------
84
85class CarlaPluginDiscovery : private CarlaPipeServer
86{
87public:
88 CarlaPluginDiscovery(const char* const discoveryTool,
89 const BinaryType btype,
90 const PluginType ptype,
91 const std::vector<water::File>&& binaries,
92 const CarlaPluginDiscoveryCallback discoveryCb,
93 const CarlaPluginCheckCacheCallback checkCacheCb,
94 void* const callbackPtr)
95 : fBinaryType(btype),
96 fPluginType(ptype),
97 fDiscoveryCallback(discoveryCb),
98 fCheckCacheCallback(checkCacheCb),
99 fCallbackPtr(callbackPtr),
102 fBinaryIndex(0),
103 fBinaryCount(static_cast<uint>(binaries.size())),
104 fBinaries(binaries),
105 fDiscoveryTool(discoveryTool),
110 {
111 start();
112 }
113
114 CarlaPluginDiscovery(const char* const discoveryTool,
115 const BinaryType btype,
116 const PluginType ptype,
117 const CarlaPluginDiscoveryCallback discoveryCb,
118 const CarlaPluginCheckCacheCallback checkCacheCb,
119 void* const callbackPtr,
120 const char* const pluginPath = nullptr)
121 : fBinaryType(btype),
122 fPluginType(ptype),
123 fDiscoveryCallback(discoveryCb),
124 fCheckCacheCallback(checkCacheCb),
125 fCallbackPtr(callbackPtr),
126 fPluginPath(pluginPath != nullptr ? carla_strdup_safe(pluginPath) : nullptr),
128 fBinaryIndex(0),
129 fBinaryCount(1),
130 fDiscoveryTool(discoveryTool),
135 {
136 start();
137 }
138
140 {
141 stopPipeServer(5000);
142 std::free(fNextLabel);
143 std::free(fNextMaker);
144 std::free(fNextName);
145 delete[] fPluginPath;
146 }
147
148 bool idle()
149 {
150 if (isPipeRunning())
151 {
152 idlePipe();
153
154 // automatically skip a plugin if 30s passes without a reply
155 const uint32_t timeNow = carla_gettime_ms();
156
157 if (timeNow - fLastMessageTime < 30000)
158 return true;
159
160 carla_stdout("Plugin took too long to respond, skipping...");
161 stopPipeServer(1000);
162 }
163
164 // report binary as having no plugins
165 if (fCheckCacheCallback != nullptr && !fPluginsFoundInBinary && !fBinaries.empty())
166 {
168 const water::String filename(file.getFullPathName());
169
171
174 }
175
176 if (++fBinaryIndex == fBinaryCount)
177 return false;
178
179 start();
180 return true;
181 }
182
183 void skip()
184 {
185 if (isPipeRunning())
186 stopPipeServer(1000);
187 }
188
189protected:
190 bool msgReceived(const char* const msg) noexcept
191 {
192 fLastMessageTime = carla_gettime_ms();
193
194 if (std::strcmp(msg, "warning") == 0 || std::strcmp(msg, "error") == 0)
195 {
196 const char* text = nullptr;
197 readNextLineAsString(text, false);
198 carla_stdout("discovery: %s", text);
199 return true;
200 }
201
202 if (std::strcmp(msg, "init") == 0)
203 {
204 const char* _;
205 readNextLineAsString(_, false);
207 return true;
208 }
209
210 if (std::strcmp(msg, "end") == 0)
211 {
212 const char* _;
213 readNextLineAsString(_, false);
214
215 if (fNextInfo.label == nullptr)
217
218 if (fNextInfo.metadata.maker == nullptr)
220
221 if (fNextInfo.metadata.name == nullptr)
223
224 if (fBinaries.empty())
225 {
226 char* filename = nullptr;
227
228 if (fPluginType == CB::PLUGIN_LV2)
229 {
230 do {
231 const char* const slash = std::strchr(fNextLabel, CARLA_OS_SEP);
232 CARLA_SAFE_ASSERT_BREAK(slash != nullptr);
233 filename = strdup(fNextLabel);
234 filename[slash - fNextLabel] = '\0';
235 fNextInfo.filename = filename;
236 fNextInfo.label = slash + 1;
237 } while (false);
238 }
239
240 fNextInfo.ptype = fPluginType;
242
243 std::free(filename);
244 }
245 else
246 {
247 CARLA_SAFE_ASSERT(fNextSha1Sum.isNotEmpty());
248 const water::String filename(fBinaries[fBinaryIndex].getFullPathName());
249 fNextInfo.filename = filename.toRawUTF8();
250 fNextInfo.ptype = fPluginType;
252 carla_stdout("Found %s from %s", fNextInfo.metadata.name, fNextInfo.filename);
254 }
255
256 std::free(fNextLabel);
257 fNextLabel = nullptr;
258
259 std::free(fNextMaker);
260 fNextMaker = nullptr;
261
262 std::free(fNextName);
263 fNextName = nullptr;
264
265 return true;
266 }
267
268 if (std::strcmp(msg, "build") == 0)
269 {
270 uint8_t btype = 0;
271 readNextLineAsByte(btype);
272 fNextInfo.btype = static_cast<BinaryType>(btype);
273 return true;
274 }
275
276 if (std::strcmp(msg, "hints") == 0)
277 {
278 readNextLineAsUInt(fNextInfo.metadata.hints);
279 return true;
280 }
281
282 if (std::strcmp(msg, "category") == 0)
283 {
284 const char* category = nullptr;
285 readNextLineAsString(category, false);
286 fNextInfo.metadata.category = CB::getPluginCategoryFromString(category);
287 return true;
288 }
289
290 if (std::strcmp(msg, "name") == 0)
291 {
292 fNextInfo.metadata.name = fNextName = readNextLineAsString();
293 return true;
294 }
295
296 if (std::strcmp(msg, "label") == 0)
297 {
298 fNextInfo.label = fNextLabel = readNextLineAsString();
299 return true;
300 }
301
302 if (std::strcmp(msg, "maker") == 0)
303 {
304 fNextInfo.metadata.maker = fNextMaker = readNextLineAsString();
305 return true;
306 }
307
308 if (std::strcmp(msg, "uniqueId") == 0)
309 {
310 readNextLineAsULong(fNextInfo.uniqueId);
311 return true;
312 }
313
314 if (std::strcmp(msg, "audio.ins") == 0)
315 {
316 readNextLineAsUInt(fNextInfo.io.audioIns);
317 return true;
318 }
319
320 if (std::strcmp(msg, "audio.outs") == 0)
321 {
322 readNextLineAsUInt(fNextInfo.io.audioOuts);
323 return true;
324 }
325
326 if (std::strcmp(msg, "cv.ins") == 0)
327 {
328 readNextLineAsUInt(fNextInfo.io.cvIns);
329 return true;
330 }
331
332 if (std::strcmp(msg, "cv.outs") == 0)
333 {
334 readNextLineAsUInt(fNextInfo.io.cvOuts);
335 return true;
336 }
337
338 if (std::strcmp(msg, "midi.ins") == 0)
339 {
340 readNextLineAsUInt(fNextInfo.io.midiIns);
341 return true;
342 }
343
344 if (std::strcmp(msg, "midi.outs") == 0)
345 {
346 readNextLineAsUInt(fNextInfo.io.midiOuts);
347 return true;
348 }
349
350 if (std::strcmp(msg, "parameters.ins") == 0)
351 {
352 readNextLineAsUInt(fNextInfo.io.parameterIns);
353 return true;
354 }
355
356 if (std::strcmp(msg, "parameters.outs") == 0)
357 {
358 readNextLineAsUInt(fNextInfo.io.parameterOuts);
359 return true;
360 }
361
362 if (std::strcmp(msg, "exiting") == 0)
363 {
364 stopPipeServer(1000);
365 return true;
366 }
367
368 carla_stdout("discovery: unknown message '%s' received", msg);
369 return true;
370 }
371
372private:
377 void* const fCallbackPtr;
378 const char* fPluginPath;
379
383 const std::vector<water::File> fBinaries;
384 const CarlaString fDiscoveryTool;
385
387
389 CarlaString fNextSha1Sum;
393
394 void start()
395 {
396 using water::File;
397 using water::String;
398
399 fLastMessageTime = carla_gettime_ms();
400 fPluginsFoundInBinary = false;
401 fNextSha1Sum.clear();
402
403 #ifndef CARLA_OS_WIN
405
406 String helperTool;
407
408 switch (fBinaryType)
409 {
410 case CB::BINARY_WIN32:
411 if (options.wine.executable.isNotEmpty())
412 helperTool = options.wine.executable.buffer();
413 else
414 helperTool = "wine";
415 break;
416
417 case CB::BINARY_WIN64:
418 if (options.wine.executable.isNotEmpty())
419 {
420 helperTool = options.wine.executable.buffer();
421
422 if (helperTool.isNotEmpty() && helperTool[0] == CARLA_OS_SEP && File(helperTool + "64").existsAsFile())
423 helperTool += "64";
424 }
425 else
426 {
427 helperTool = "wine";
428 }
429 break;
430
431 default:
432 break;
433 }
434
435 String winePrefix;
436
437 if (options.wine.autoPrefix && !fBinaries.empty())
438 {
440 const String filename(file.getFullPathName());
441
442 winePrefix = findWinePrefix(filename);
443 }
444
445 if (winePrefix.isEmpty())
446 {
447 const char* const envWinePrefix = std::getenv("WINEPREFIX");
448
449 if (envWinePrefix != nullptr && envWinePrefix[0] != '\0')
450 winePrefix = envWinePrefix;
451 else if (options.wine.fallbackPrefix.isNotEmpty())
452 winePrefix = options.wine.fallbackPrefix.buffer();
453 else
455 }
456
457 const CarlaScopedEnvVar sev1("WINEDEBUG", "-all");
458 const CarlaScopedEnvVar sev2("WINEPREFIX", winePrefix.toRawUTF8());
459 #endif
460
461 const CarlaScopedEnvVar sev3("CARLA_DISCOVERY_NO_PROCESSING_CHECKS", "1");
462
463 if (fBinaries.empty())
464 {
465 if (fBinaryType == CB::BINARY_NATIVE)
466 {
467 switch (fPluginType)
468 {
469 default:
470 break;
471 case CB::PLUGIN_INTERNAL:
472 case CB::PLUGIN_LV2:
473 case CB::PLUGIN_JSFX:
474 case CB::PLUGIN_SFZ:
476 {
477 for (uint i=0; i<count; ++i)
478 {
480
481 if (pinfo == nullptr || !pinfo->valid)
482 continue;
483
484 char* filename = nullptr;
486 info.btype = CB::BINARY_NATIVE;
487 info.ptype = fPluginType;
488 info.metadata.name = pinfo->name;
489 info.metadata.maker = pinfo->maker;
490 info.metadata.category = pinfo->category;
491 info.metadata.hints = pinfo->hints;
492 info.io.audioIns = pinfo->audioIns;
493 info.io.audioOuts = pinfo->audioOuts;
494 info.io.cvIns = pinfo->cvIns;
495 info.io.cvOuts = pinfo->cvOuts;
496 info.io.midiIns = pinfo->midiIns;
497 info.io.midiOuts = pinfo->midiOuts;
498 info.io.parameterIns = pinfo->parameterIns;
499 info.io.parameterOuts = pinfo->parameterOuts;
500
501 if (fPluginType == CB::PLUGIN_LV2)
502 {
503 const char* const slash = std::strchr(pinfo->label, CARLA_OS_SEP);
504 CARLA_SAFE_ASSERT_BREAK(slash != nullptr);
505 filename = strdup(pinfo->label);
506 filename[slash - pinfo->label] = '\0';
507 info.filename = filename;
508 info.label = slash + 1;
509 }
510 else
511 {
513 info.label = pinfo->label;
514 }
515
517
518 std::free(filename);
519 }
520 }
521 return;
522 }
523 }
524
525 #ifndef CARLA_OS_WIN
526 if (helperTool.isNotEmpty())
527 startPipeServer(helperTool.toRawUTF8(), fDiscoveryTool, getPluginTypeAsString(fPluginType), ":all", -1, 2000);
528 else
529 #endif
530 startPipeServer(fDiscoveryTool, getPluginTypeAsString(fPluginType), ":all", -1, 2000);
531 }
532 else
533 {
535 const String filename(file.getFullPathName());
536
537 if (fCheckCacheCallback != nullptr)
538 {
540
542 {
544 carla_debug("Skipping \"%s\", using cache", filename.toRawUTF8());
545 return;
546 }
547 }
548
549 carla_stdout("Scanning \"%s\"...", filename.toRawUTF8());
550
551 #ifndef CARLA_OS_WIN
552 if (helperTool.isNotEmpty())
553 startPipeServer(helperTool.toRawUTF8(), fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8(), -1, 2000);
554 else
555 #endif
556 startPipeServer(fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8(), -1, 2000);
557 }
558 }
559
561 {
562 CarlaSha1 sha1;
563
564 /* do we want this? it is not exactly needed and makes discovery slow..
565 if (file.existsAsFile() && file.getSize() < 20*1024*1024) // dont bother hashing > 20Mb files
566 {
567 water::FileInputStream stream(file);
568
569 if (stream.openedOk())
570 {
571 uint8_t block[8192];
572 for (int r; r = stream.read(block, sizeof(block)), r > 0;)
573 sha1.write(block, r);
574 }
575 }
576 */
577
578 sha1.write(filename.toRawUTF8(), filename.length());
579
580 const int64_t mtime = file.getLastModificationTime();
581 sha1.write(&mtime, sizeof(mtime));
582
583 fNextSha1Sum = sha1.resultAsString();
584 }
585
586 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginDiscovery)
587};
588
589// --------------------------------------------------------------------------------------------------------------------
590
591static bool findDirectories(std::vector<water::File>& files, const char* const pluginPath, const char* const wildcard)
592{
593 CARLA_SAFE_ASSERT_RETURN(pluginPath != nullptr, true);
594
595 if (pluginPath[0] == '\0')
596 return true;
597
598 using water::File;
599 using water::String;
600 using water::StringArray;
601
602 const StringArray splitPaths(StringArray::fromTokens(pluginPath, CARLA_OS_SPLIT_STR, ""));
603
604 if (splitPaths.size() == 0)
605 return true;
606
607 for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it)
608 {
609 const File dir(*it);
610 std::vector<File> results;
611
612 if (dir.findChildFiles(results, File::findDirectories|File::ignoreHiddenFiles, true, wildcard) > 0)
613 {
614 files.reserve(files.size() + results.size());
615 files.insert(files.end(), results.begin(), results.end());
616 }
617 }
618
619 return files.empty();
620}
621
622static bool findFiles(std::vector<water::File>& files,
623 const BinaryType btype, const char* const pluginPath, const char* const wildcard)
624{
625 CARLA_SAFE_ASSERT_RETURN(pluginPath != nullptr, true);
626
627 if (pluginPath[0] == '\0')
628 return true;
629
630 using water::File;
631 using water::String;
632 using water::StringArray;
633
634 const StringArray splitPaths(StringArray::fromTokens(pluginPath, CARLA_OS_SPLIT_STR, ""));
635
636 if (splitPaths.size() == 0)
637 return true;
638
639 for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it)
640 {
641 const File dir(*it);
642 std::vector<File> results;
643
644 if (dir.findChildFiles(results, File::findFiles|File::ignoreHiddenFiles, true, wildcard) > 0)
645 {
646 files.reserve(files.size() + results.size());
647
648 for (std::vector<File>::const_iterator cit = results.begin(); cit != results.end(); ++cit)
649 {
650 const File file(*cit);
651
652 if (CB::getBinaryTypeFromFile(file.getFullPathName().toRawUTF8()) == btype)
653 files.push_back(file);
654 }
655 }
656 }
657
658 return files.empty();
659}
660
661static bool findVST3s(std::vector<water::File>& files,
662 const BinaryType btype, const char* const pluginPath)
663{
664 CARLA_SAFE_ASSERT_RETURN(pluginPath != nullptr, true);
665
666 if (pluginPath[0] == '\0')
667 return true;
668
669 using water::File;
670 using water::String;
671 using water::StringArray;
672
673 const StringArray splitPaths(StringArray::fromTokens(pluginPath, CARLA_OS_SPLIT_STR, ""));
674
675 if (splitPaths.size() == 0)
676 return true;
677
678 const uint flags = btype == CB::BINARY_WIN32 || btype == CB::BINARY_WIN64
681
682 for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it)
683 {
684 const File dir(*it);
685 std::vector<File> results;
686
687 if (dir.findChildFiles(results, flags|File::ignoreHiddenFiles, true, "*.vst3") > 0)
688 {
689 files.reserve(files.size() + results.size());
690
691 for (std::vector<File>::const_iterator cit = results.begin(); cit != results.end(); ++cit)
692 {
693 const File file(*cit);
694
695 if (CB::getBinaryTypeFromFile(file.getFullPathName().toRawUTF8()) == btype)
696 files.push_back(file);
697 }
698 }
699 }
700
701 return files.empty();
702}
703
705 const BinaryType btype,
706 const PluginType ptype,
707 const char* const pluginPath,
708 const CarlaPluginDiscoveryCallback discoveryCb,
709 const CarlaPluginCheckCacheCallback checkCacheCb,
710 void* const callbackPtr)
711{
712 CARLA_SAFE_ASSERT_RETURN(btype != CB::BINARY_NONE, nullptr);
713 CARLA_SAFE_ASSERT_RETURN(ptype != CB::PLUGIN_NONE, nullptr);
714 CARLA_SAFE_ASSERT_RETURN(discoveryTool != nullptr && discoveryTool[0] != '\0', nullptr);
715 CARLA_SAFE_ASSERT_RETURN(discoveryCb != nullptr, nullptr);
716 carla_debug("carla_plugin_discovery_start(%s, %d:%s, %d:%s, %s, %p, %p, %p)",
717 discoveryTool, btype, BinaryType2Str(btype), ptype, PluginType2Str(ptype), pluginPath,
718 discoveryCb, checkCacheCb, callbackPtr);
719
720 bool directories = false;
721 const char* wildcard = nullptr;
722
723 switch (ptype)
724 {
725 case CB::PLUGIN_INTERNAL:
726 case CB::PLUGIN_LV2:
727 case CB::PLUGIN_SFZ:
728 case CB::PLUGIN_JSFX:
729 case CB::PLUGIN_DLS:
730 case CB::PLUGIN_GIG:
731 case CB::PLUGIN_SF2:
732 CARLA_SAFE_ASSERT_UINT_RETURN(btype == CB::BINARY_NATIVE, btype, nullptr);
733 break;
734 default:
735 break;
736 }
737
738 switch (ptype)
739 {
740 case CB::PLUGIN_NONE:
741 case CB::PLUGIN_JACK:
742 case CB::PLUGIN_TYPE_COUNT:
743 return nullptr;
744
745 case CB::PLUGIN_LV2:
746 case CB::PLUGIN_SFZ:
747 case CB::PLUGIN_JSFX:
748 {
749 const CarlaScopedEnvVar csev("CARLA_DISCOVERY_PATH", pluginPath);
750 return new CarlaPluginDiscovery(discoveryTool, btype, ptype, discoveryCb, checkCacheCb, callbackPtr, pluginPath);
751 }
752
753 case CB::PLUGIN_INTERNAL:
754 return new CarlaPluginDiscovery(discoveryTool, btype, ptype, discoveryCb, checkCacheCb, callbackPtr);
755
756 case CB::PLUGIN_LADSPA:
757 case CB::PLUGIN_DSSI:
758 #ifdef CARLA_OS_WIN
759 wildcard = "*.dll";
760 #else
761 if (btype == CB::BINARY_WIN32 || btype == CB::BINARY_WIN64)
762 {
763 wildcard = "*.dll";
764 }
765 else
766 {
767 #ifdef CARLA_OS_MAC
768 wildcard = "*.dylib";
769 #else
770 wildcard = "*.so";
771 #endif
772 }
773 #endif
774 break;
775
776 case CB::PLUGIN_VST2:
777 #ifdef CARLA_OS_WIN
778 wildcard = "*.dll";
779 #else
780 if (btype == CB::BINARY_WIN32 || btype == CB::BINARY_WIN64)
781 {
782 wildcard = "*.dll";
783 }
784 else
785 {
786 #ifdef CARLA_OS_MAC
787 directories = true;
788 wildcard = "*.vst";
789 #else
790 wildcard = "*.so";
791 #endif
792 }
793 #endif
794 break;
795
796 case CB::PLUGIN_VST3:
797 directories = true;
798 wildcard = "*.vst3";
799 break;
800
801 case CB::PLUGIN_AU:
802 directories = true;
803 wildcard = "*.component";
804 break;
805
806 case CB::PLUGIN_CLAP:
807 wildcard = "*.clap";
808 #ifdef CARLA_OS_MAC
809 directories = true;
810 #endif
811 break;
812
813 case CB::PLUGIN_DLS:
814 wildcard = "*.dls";
815 break;
816 case CB::PLUGIN_GIG:
817 wildcard = "*.gig";
818 break;
819 case CB::PLUGIN_SF2:
820 wildcard = "*.sf2";
821 break;
822 }
823
824 CARLA_SAFE_ASSERT_RETURN(wildcard != nullptr, nullptr);
825
826 std::vector<water::File> files;
827
828 if (ptype == CB::PLUGIN_VST3)
829 {
830 if (findVST3s(files, btype, pluginPath))
831 return nullptr;
832 }
833 else if (directories)
834 {
835 if (findDirectories(files, pluginPath, wildcard))
836 return nullptr;
837 }
838 else
839 {
840 if (findFiles(files, btype, pluginPath, wildcard))
841 return nullptr;
842 }
843
844 return new CarlaPluginDiscovery(discoveryTool, btype, ptype, std::move(files),
845 discoveryCb, checkCacheCb, callbackPtr);
846}
847
849{
850 return static_cast<CarlaPluginDiscovery*>(handle)->idle();
851}
852
854{
855 static_cast<CarlaPluginDiscovery*>(handle)->skip();
856}
857
859{
860 delete static_cast<CarlaPluginDiscovery*>(handle);
861}
862
863void carla_plugin_discovery_set_option(const EngineOption option, const int value, const char* const valueStr)
864{
865 switch (option)
866 {
867 #if !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH) && !defined(CARLA_OS_WIN)
868 case CB::ENGINE_OPTION_WINE_EXECUTABLE:
869 if (valueStr != nullptr && valueStr[0] != '\0')
871 else
873 break;
874 case CB::ENGINE_OPTION_WINE_AUTO_PREFIX:
875 CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
877 break;
878 case CB::ENGINE_OPTION_WINE_FALLBACK_PREFIX:
879 if (valueStr != nullptr && valueStr[0] != '\0')
881 else
883 break;
884 #endif
885 default:
886 break;
887 }
888}
889
890// --------------------------------------------------------------------------------------------------------------------
#define CARLA_BACKEND_NAMESPACE
Definition CarlaBackend.h:32
#define CARLA_OS_SEP
Definition CarlaDefines.h:318
#define CARLA_OS_SPLIT_STR
Definition CarlaDefines.h:321
#define CARLA_SAFE_ASSERT_RETURN(cond, ret)
Definition CarlaDefines.h:190
unsigned int uint
Definition CarlaDefines.h:327
#define CARLA_SAFE_ASSERT_BREAK(cond)
Definition CarlaDefines.h:188
#define CARLA_SAFE_ASSERT_UINT_RETURN(cond, value, ret)
Definition CarlaDefines.h:211
#define CARLA_SAFE_ASSERT(cond)
Definition CarlaDefines.h:182
#define noexcept
Definition DistrhoDefines.h:72
#define nullptr
Definition DistrhoDefines.h:75
static bool findFiles(std::vector< water::File > &files, const BinaryType btype, const char *const pluginPath, const char *const wildcard)
Definition PluginDiscovery.cpp:622
static water::String findWinePrefix(const water::String filename, const int recursionLimit=10)
Definition PluginDiscovery.cpp:23
static bool findDirectories(std::vector< water::File > &files, const char *const pluginPath, const char *const wildcard)
Definition PluginDiscovery.cpp:591
static bool findVST3s(std::vector< water::File > &files, const BinaryType btype, const char *const pluginPath)
Definition PluginDiscovery.cpp:661
static const char *const gPluginsDiscoveryNullCharPtr
Definition PluginDiscovery.cpp:39
Definition PluginDiscovery.cpp:86
char * fNextMaker
Definition PluginDiscovery.cpp:391
const CarlaPluginCheckCacheCallback fCheckCacheCallback
Definition PluginDiscovery.cpp:376
bool idle()
Definition PluginDiscovery.cpp:148
CarlaPluginDiscovery(const char *const discoveryTool, const BinaryType btype, const PluginType ptype, const std::vector< water::File > &&binaries, const CarlaPluginDiscoveryCallback discoveryCb, const CarlaPluginCheckCacheCallback checkCacheCb, void *const callbackPtr)
Definition PluginDiscovery.cpp:88
char * fNextName
Definition PluginDiscovery.cpp:392
const char * fPluginPath
Definition PluginDiscovery.cpp:378
const PluginType fPluginType
Definition PluginDiscovery.cpp:374
char * fNextLabel
Definition PluginDiscovery.cpp:390
CarlaPluginDiscovery(const char *const discoveryTool, const BinaryType btype, const PluginType ptype, const CarlaPluginDiscoveryCallback discoveryCb, const CarlaPluginCheckCacheCallback checkCacheCb, void *const callbackPtr, const char *const pluginPath=nullptr)
Definition PluginDiscovery.cpp:114
~CarlaPluginDiscovery()
Definition PluginDiscovery.cpp:139
void makeHash(const water::File &file, const water::String &filename)
Definition PluginDiscovery.cpp:560
const std::vector< water::File > fBinaries
Definition PluginDiscovery.cpp:383
uint32_t fLastMessageTime
Definition PluginDiscovery.cpp:386
const uint fBinaryCount
Definition PluginDiscovery.cpp:382
CarlaString fNextSha1Sum
Definition PluginDiscovery.cpp:389
void skip()
Definition PluginDiscovery.cpp:183
bool msgReceived(const char *const msg) noexcept
Definition PluginDiscovery.cpp:190
const CarlaString fDiscoveryTool
Definition PluginDiscovery.cpp:384
void start()
Definition PluginDiscovery.cpp:394
uint fBinaryIndex
Definition PluginDiscovery.cpp:381
bool fPluginsFoundInBinary
Definition PluginDiscovery.cpp:380
const CarlaPluginDiscoveryCallback fDiscoveryCallback
Definition PluginDiscovery.cpp:375
void *const fCallbackPtr
Definition PluginDiscovery.cpp:377
CarlaPluginDiscoveryInfo fNextInfo
Definition PluginDiscovery.cpp:388
const BinaryType fBinaryType
Definition PluginDiscovery.cpp:373
Definition File.h:50
@ findDirectories
Definition File.h:461
@ findFiles
Definition File.h:462
@ ignoreHiddenFiles
Definition File.h:464
@ userHomeDirectory
Definition File.h:635
static File getSpecialLocation(const SpecialLocationType type)
Definition File.cpp:1642
uint findChildFiles(std::vector< File > &results, int whatToLookFor, bool searchRecursively, const String &wildCardPattern="*") const
Definition File.cpp:581
Definition StringArray.h:41
String * begin() const noexcept
Definition StringArray.h:120
int size() const noexcept
Definition StringArray.h:97
static StringArray fromTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Definition StringArray.cpp:369
String * end() const noexcept
Definition StringArray.h:125
Definition String.h:48
bool isNotEmpty() const noexcept
Definition String.h:244
const char * toRawUTF8() const
Definition String.cpp:1925
bool isEmpty() const noexcept
Definition String.h:238
Definition File.h:50
const String & getFullPathName() const noexcept
Definition File.h:152
Definition StringArray.h:41
Definition String.h:48
register unsigned i
Definition inflate.c:1575
static char filename[]
Definition features.c:5
#define _(msgid)
Definition getopt.c:86
PluginType
Definition CarlaBackend.h:614
BinaryType
Definition CarlaBackend.h:550
EngineOption
Definition CarlaBackend.h:1333
@ PLUGIN_NONE
Definition CarlaBackend.h:618
@ BINARY_NONE
Definition CarlaBackend.h:554
@ PLUGIN_CATEGORY_NONE
Definition CarlaBackend.h:708
CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char *const discoveryTool, const BinaryType btype, const PluginType ptype, const char *const pluginPath, const CarlaPluginDiscoveryCallback discoveryCb, const CarlaPluginCheckCacheCallback checkCacheCb, void *const callbackPtr)
Definition PluginDiscovery.cpp:704
void * CarlaPluginDiscoveryHandle
Definition CarlaUtils.h:28
void carla_plugin_discovery_stop(const CarlaPluginDiscoveryHandle handle)
Definition PluginDiscovery.cpp:858
struct _CarlaCachedPluginInfo CarlaCachedPluginInfo
bool carla_plugin_discovery_idle(const CarlaPluginDiscoveryHandle handle)
Definition PluginDiscovery.cpp:848
bool(* CarlaPluginCheckCacheCallback)(void *ptr, const char *filename, const char *sha1)
Definition CarlaUtils.h:188
void carla_plugin_discovery_skip(const CarlaPluginDiscoveryHandle handle)
Definition PluginDiscovery.cpp:853
CARLA_PLUGIN_EXPORT uint carla_get_cached_plugin_count(PluginType ptype, const char *pluginPath)
void carla_plugin_discovery_set_option(const EngineOption option, const int value, const char *const valueStr)
Definition PluginDiscovery.cpp:863
void(* CarlaPluginDiscoveryCallback)(void *ptr, const CarlaPluginDiscoveryInfo *info, const char *sha1)
Definition CarlaUtils.h:181
struct _CarlaPluginDiscoveryInfo CarlaPluginDiscoveryInfo
CARLA_PLUGIN_EXPORT const CarlaCachedPluginInfo * carla_get_cached_plugin_info(PluginType ptype, uint index)
static PuglViewHint int value
Definition pugl.h:1708
static const char * name
Definition pugl.h:1582
struct backing_store_struct * info
Definition jmemsys.h:183
unsigned int uint32_t
Definition mid.cpp:100
unsigned char uint8_t
Definition mid.cpp:98
static char ** files
Definition misc.c:28
const char * msg
Definition missing_descriptor.c:20
#define false
Definition ordinals.h:83
uint32_t parameterIns
Definition CarlaUtils.h:291
uint32_t midiOuts
Definition CarlaUtils.h:286
uint32_t parameterOuts
Definition CarlaUtils.h:296
uint32_t audioOuts
Definition CarlaUtils.h:266
uint32_t midiIns
Definition CarlaUtils.h:281
uint32_t cvIns
Definition CarlaUtils.h:271
uint hints
Definition CarlaUtils.h:256
uint32_t cvOuts
Definition CarlaUtils.h:276
const char * maker
Definition CarlaUtils.h:311
bool valid
Definition CarlaUtils.h:245
const char * label
Definition CarlaUtils.h:306
const char * name
Definition CarlaUtils.h:301
uint32_t audioIns
Definition CarlaUtils.h:261
PluginCategory category
Definition CarlaUtils.h:250
Definition CarlaUtils.h:124
Definition PluginDiscovery.cpp:67
CarlaString executable
Definition PluginDiscovery.cpp:71
struct CarlaPluginDiscoveryOptions::@225223212227005147163077370124203146176270146345 wine
CarlaString fallbackPrefix
Definition PluginDiscovery.cpp:72
static CarlaPluginDiscoveryOptions & getInstance() noexcept
Definition PluginDiscovery.cpp:76
bool autoPrefix
Definition PluginDiscovery.cpp:70
Definition mygetopt.h:88
const char * text
Definition swell-functions.h:167
ulg size
Definition extract.c:2350
struct zdirent * file
Definition win32.c:1500
_WDL_CSTRING_PREFIX void INT_PTR count
Definition wdlcstring.h:263