Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

644 lines
21KB

  1. /*
  2. * Common Carla code
  3. * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "carla_shared.hpp"
  18. #include <QtCore/QDir>
  19. #include <QtCore/QFile>
  20. #include <QtGui/QFileDialog>
  21. //#ifdef CARLA_OS_MAC
  22. //#endif
  23. CARLA_BACKEND_USE_NAMESPACE
  24. // ------------------------------------------------------------------------------------------------------------
  25. // Misc functions
  26. static
  27. QString getenvWithFallback(const char* const key, const QString& fallback)
  28. {
  29. if (const char* const value = std::getenv(key))
  30. return key;
  31. return fallback;
  32. }
  33. // ------------------------------------------------------------------------------------------------------------
  34. // Global objects
  35. QString TMP;
  36. QString HOME;
  37. QStringList PATH;
  38. QStringList MIDI_CC_LIST;
  39. CarlaObject gCarla;
  40. // ------------------------------------------------------------------------------------------------------------
  41. // init
  42. static
  43. void init()
  44. {
  45. // --------------------------------------------------------------------------------------------------------
  46. // Platform specific stuff
  47. #if defined(CARLA_OS_MAC)
  48. qt_mac_set_menubar_icons(false);
  49. #elif defined(CARLA_OS_WIN)
  50. QString WINDIR = std::getenv("WINDIR");
  51. #endif
  52. // --------------------------------------------------------------------------------------------------------
  53. // Set TMP
  54. const char* const envTMP = std::getenv("TMP");
  55. if (envTMP == nullptr)
  56. {
  57. #ifdef CARLA_OS_WIN
  58. qWarning("TMP variable not set");
  59. #endif
  60. TMP = QDir::tempPath();
  61. }
  62. else
  63. TMP = envTMP;
  64. if (! QDir(TMP).exists())
  65. {
  66. qWarning("TMP does not exist");
  67. TMP = "/";
  68. }
  69. // --------------------------------------------------------------------------------------------------------
  70. // Set HOME
  71. const char* const envHOME = std::getenv("HOME");
  72. if (envHOME == nullptr)
  73. {
  74. #if defined(CARLA_OS_LINUX) || defined(CARLA_OS_MAC)
  75. qWarning("HOME variable not set");
  76. #endif
  77. HOME = QDir::homePath();
  78. }
  79. else
  80. HOME = envHOME;
  81. if (! QDir(HOME).exists())
  82. {
  83. qWarning("HOME does not exist");
  84. HOME = TMP;
  85. }
  86. // --------------------------------------------------------------------------------------------------------
  87. // Set PATH
  88. const char* const envPATH = std::getenv("PATH");
  89. if (envPATH == nullptr)
  90. {
  91. qWarning("PATH variable not set");
  92. PATH.clear();
  93. #if defined(CARLA_OS_MAC)
  94. PATH << "/opt/local/bin";
  95. PATH << "/usr/local/bin";
  96. PATH << "/usr/bin";
  97. PATH << "/bin";
  98. #elif defined(CARLA_OS_WIN)
  99. PATH << QDir(WINDIR).filePath("system32");
  100. PATH << WINDIR;
  101. #else
  102. PATH << "/usr/local/bin";
  103. PATH << "/usr/bin";
  104. PATH << "/bin";
  105. #endif
  106. }
  107. else
  108. {
  109. #ifdef CARLA_OS_WIN
  110. PATH = QString(envPATH).split(":");
  111. #else
  112. PATH = QString(envPATH).split(";");
  113. #endif
  114. }
  115. // --------------------------------------------------------------------------------------------------------
  116. // Static MIDI CC list
  117. MIDI_CC_LIST.clear();
  118. MIDI_CC_LIST << "0x01 Modulation";
  119. MIDI_CC_LIST << "0x02 Breath";
  120. MIDI_CC_LIST << "0x03 (Undefined)";
  121. MIDI_CC_LIST << "0x04 Foot";
  122. MIDI_CC_LIST << "0x05 Portamento";
  123. MIDI_CC_LIST << "0x07 Volume";
  124. MIDI_CC_LIST << "0x08 Balance";
  125. MIDI_CC_LIST << "0x09 (Undefined)";
  126. MIDI_CC_LIST << "0x0A Pan";
  127. MIDI_CC_LIST << "0x0B Expression";
  128. MIDI_CC_LIST << "0x0C FX Control 1";
  129. MIDI_CC_LIST << "0x0D FX Control 2";
  130. MIDI_CC_LIST << "0x0E (Undefined)";
  131. MIDI_CC_LIST << "0x0F (Undefined)";
  132. MIDI_CC_LIST << "0x10 General Purpose 1";
  133. MIDI_CC_LIST << "0x11 General Purpose 2";
  134. MIDI_CC_LIST << "0x12 General Purpose 3";
  135. MIDI_CC_LIST << "0x13 General Purpose 4";
  136. MIDI_CC_LIST << "0x14 (Undefined)";
  137. MIDI_CC_LIST << "0x15 (Undefined)";
  138. MIDI_CC_LIST << "0x16 (Undefined)";
  139. MIDI_CC_LIST << "0x17 (Undefined)";
  140. MIDI_CC_LIST << "0x18 (Undefined)";
  141. MIDI_CC_LIST << "0x19 (Undefined)";
  142. MIDI_CC_LIST << "0x1A (Undefined)";
  143. MIDI_CC_LIST << "0x1B (Undefined)";
  144. MIDI_CC_LIST << "0x1C (Undefined)";
  145. MIDI_CC_LIST << "0x1D (Undefined)";
  146. MIDI_CC_LIST << "0x1E (Undefined)";
  147. MIDI_CC_LIST << "0x1F (Undefined)";
  148. MIDI_CC_LIST << "0x46 Control 1 [Variation]";
  149. MIDI_CC_LIST << "0x47 Control 2 [Timbre]";
  150. MIDI_CC_LIST << "0x48 Control 3 [Release]";
  151. MIDI_CC_LIST << "0x49 Control 4 [Attack]";
  152. MIDI_CC_LIST << "0x4A Control 5 [Brightness]";
  153. MIDI_CC_LIST << "0x4B Control 6 [Decay]";
  154. MIDI_CC_LIST << "0x4C Control 7 [Vib Rate]";
  155. MIDI_CC_LIST << "0x4D Control 8 [Vib Depth]";
  156. MIDI_CC_LIST << "0x4E Control 9 [Vib Delay]";
  157. MIDI_CC_LIST << "0x4F Control 10 [Undefined]";
  158. MIDI_CC_LIST << "0x50 General Purpose 5";
  159. MIDI_CC_LIST << "0x51 General Purpose 6";
  160. MIDI_CC_LIST << "0x52 General Purpose 7";
  161. MIDI_CC_LIST << "0x53 General Purpose 8";
  162. MIDI_CC_LIST << "0x54 Portamento Control";
  163. MIDI_CC_LIST << "0x5B FX 1 Depth [Reverb]";
  164. MIDI_CC_LIST << "0x5C FX 2 Depth [Tremolo]";
  165. MIDI_CC_LIST << "0x5D FX 3 Depth [Chorus]";
  166. MIDI_CC_LIST << "0x5E FX 4 Depth [Detune]";
  167. MIDI_CC_LIST << "0x5F FX 5 Depth [Phaser]";
  168. // --------------------------------------------------------------------------------------------------------
  169. // Global Carla object
  170. gCarla.host = nullptr;
  171. gCarla.gui = nullptr;
  172. gCarla.isControl = false;
  173. gCarla.isLocal = true;
  174. gCarla.isPlugin = false;
  175. gCarla.bufferSize = 0;
  176. gCarla.sampleRate = 0.0;
  177. #ifdef CARLA_OS_LINUX
  178. gCarla.processMode = CarlaBackend::ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS;
  179. gCarla.transportMode = CarlaBackend::ENGINE_TRANSPORT_MODE_JACK;
  180. #else
  181. gCarla.processMode = CarlaBackend::ENGINE_PROCESS_MODE_CONTINUOUS_RACK;
  182. gCarla.transportMode = CarlaBackend::ENGINE_TRANSPORT_MODE_INTERNAL;
  183. #endif
  184. gCarla.maxParameters = CarlaBackend::MAX_DEFAULT_PARAMETERS;
  185. // --------------------------------------------------------------------------------------------------------
  186. // Default Plugin Folders (get)
  187. QString splitter;
  188. QString DEFAULT_LADSPA_PATH, DEFAULT_DSSI_PATH, DEFAULT_LV2_PATH, DEFAULT_VST_PATH, DEFAULT_VST3_PATH, DEFAULT_AU_PATH;
  189. QString DEFAULT_CSOUND_PATH, DEFAULT_GIG_PATH, DEFAULT_SF2_PATH, DEFAULT_SFZ_PATH;
  190. #if defined(CARLA_OS_WIN)
  191. splitter = ";";
  192. const char* const envAPPDATA = std::getenv("APPDATA");
  193. const char* const envPROGRAMFILES = std::getenv("PROGRAMFILES");
  194. const char* const envPROGRAMFILESx86 = std::getenv("PROGRAMFILES(x86)");
  195. const char* const envCOMMONPROGRAMFILES = std::getenv("COMMONPROGRAMFILES");
  196. // Small integrity tests
  197. if (envAPPDATA == nullptr)
  198. {
  199. qFatal("APPDATA variable not set, cannot continue");
  200. std::exit(1);
  201. }
  202. if (envPROGRAMFILES == nullptr)
  203. {
  204. qFatal("PROGRAMFILES variable not set, cannot continue");
  205. std::exit(1);
  206. }
  207. if (envCOMMONPROGRAMFILES == nullptr)
  208. {
  209. qFatal("COMMONPROGRAMFILES variable not set, cannot continue");
  210. std::exit(1);
  211. }
  212. QString APPDATA(envAPPDATA);
  213. QString PROGRAMFILES(envPROGRAMFILES);
  214. QString COMMONPROGRAMFILES(envCOMMONPROGRAMFILES);
  215. DEFAULT_LADSPA_PATH = APPDATA + "\\LADSPA";
  216. DEFAULT_LADSPA_PATH += ";" + PROGRAMFILES + "\\LADSPA";
  217. DEFAULT_DSSI_PATH = APPDATA + "\\DSSI";
  218. DEFAULT_DSSI_PATH += ";" + PROGRAMFILES + "\\DSSI";
  219. DEFAULT_LV2_PATH = APPDATA + "\\LV2";
  220. DEFAULT_LV2_PATH += ";" + COMMONPROGRAMFILES + "\\LV2";
  221. DEFAULT_VST_PATH = PROGRAMFILES + "\\VstPlugins";
  222. DEFAULT_VST_PATH += ";" + PROGRAMFILES + "\\Steinberg\\VstPlugins";
  223. DEFAULT_VST3_PATH = PROGRAMFILES + "\\Vst3";
  224. DEFAULT_GIG_PATH = APPDATA + "\\GIG";
  225. DEFAULT_SF2_PATH = APPDATA + "\\SF2";
  226. DEFAULT_SFZ_PATH = APPDATA + "\\SFZ";
  227. if (envPROGRAMFILESx86 != nullptr)
  228. {
  229. QString PROGRAMFILESx86(envPROGRAMFILESx86);
  230. DEFAULT_LADSPA_PATH += ";" + PROGRAMFILESx86 + "\\LADSPA";
  231. DEFAULT_DSSI_PATH += ";" + PROGRAMFILESx86 + "\\DSSI";
  232. DEFAULT_VST_PATH += ";" + PROGRAMFILESx86 + "\\VstPlugins";
  233. DEFAULT_VST_PATH += ";" + PROGRAMFILESx86 + "\\Steinberg\\VstPlugins";
  234. }
  235. #elif defined(CARLA_OS_HAIKU)
  236. splitter = ":";
  237. DEFAULT_LADSPA_PATH = HOME + "/.ladspa";
  238. DEFAULT_LADSPA_PATH += ":/boot/common/add-ons/ladspa";
  239. DEFAULT_DSSI_PATH = HOME + "/.dssi";
  240. DEFAULT_DSSI_PATH += ":/boot/common/add-ons/dssi";
  241. DEFAULT_LV2_PATH = HOME + "/.lv2";
  242. DEFAULT_LV2_PATH += ":/boot/common/add-ons/lv2";
  243. DEFAULT_VST_PATH = HOME + "/.vst";
  244. DEFAULT_VST_PATH += ":/boot/common/add-ons/vst";
  245. DEFAULT_VST3_PATH = HOME + "/.vst3";
  246. DEFAULT_VST3_PATH += ":/boot/common/add-ons/vst3";
  247. #elif defined(CARLA_OS_MAC)
  248. splitter = ":";
  249. DEFAULT_LADSPA_PATH = HOME + "/Library/Audio/Plug-Ins/LADSPA";
  250. DEFAULT_LADSPA_PATH += ":/Library/Audio/Plug-Ins/LADSPA";
  251. DEFAULT_DSSI_PATH = HOME + "/Library/Audio/Plug-Ins/DSSI";
  252. DEFAULT_DSSI_PATH += ":/Library/Audio/Plug-Ins/DSSI";
  253. DEFAULT_LV2_PATH = HOME + "/Library/Audio/Plug-Ins/LV2";
  254. DEFAULT_LV2_PATH += ":/Library/Audio/Plug-Ins/LV2";
  255. DEFAULT_VST_PATH = HOME + "/Library/Audio/Plug-Ins/VST";
  256. DEFAULT_VST_PATH += ":/Library/Audio/Plug-Ins/VST";
  257. DEFAULT_VST3_PATH = HOME + "/Library/Audio/Plug-Ins/VST3";
  258. DEFAULT_VST3_PATH += ":/Library/Audio/Plug-Ins/VST3";
  259. DEFAULT_AU_PATH = HOME + "/Library/Audio/Plug-Ins/Components";
  260. DEFAULT_AU_PATH += ":/Library/Audio/Plug-Ins/Components";
  261. #else
  262. splitter = ":";
  263. DEFAULT_LADSPA_PATH = HOME + "/.ladspa";
  264. DEFAULT_LADSPA_PATH += ":/usr/lib/ladspa";
  265. DEFAULT_LADSPA_PATH += ":/usr/local/lib/ladspa";
  266. DEFAULT_DSSI_PATH = HOME + "/.dssi";
  267. DEFAULT_DSSI_PATH += ":/usr/lib/dssi";
  268. DEFAULT_DSSI_PATH += ":/usr/local/lib/dssi";
  269. DEFAULT_LV2_PATH = HOME + "/.lv2";
  270. DEFAULT_LV2_PATH += ":/usr/lib/lv2";
  271. DEFAULT_LV2_PATH += ":/usr/local/lib/lv2";
  272. DEFAULT_VST_PATH = HOME + "/.vst";
  273. DEFAULT_VST_PATH += ":/usr/lib/vst";
  274. DEFAULT_VST_PATH += ":/usr/local/lib/vst";
  275. DEFAULT_VST3_PATH = HOME + "/.vst3";
  276. DEFAULT_VST3_PATH += ":/usr/lib/vst3";
  277. DEFAULT_VST3_PATH += ":/usr/local/lib/vst3";
  278. DEFAULT_GIG_PATH = HOME + "/.sounds/gig";
  279. DEFAULT_GIG_PATH += ":/usr/share/sounds/gig";
  280. DEFAULT_SF2_PATH = HOME + "/.sounds/sf2";
  281. DEFAULT_SF2_PATH += ":/usr/share/sounds/sf2";
  282. DEFAULT_SFZ_PATH = HOME + "/.sounds/sfz";
  283. DEFAULT_SFZ_PATH += ":/usr/share/sounds/sfz";
  284. #endif
  285. // --------------------------------------------------------------------------------------------------------
  286. // Default Plugin Folders (set)
  287. bool readEnvVars = true;
  288. #if 0 //def CARLA_OS_WIN
  289. // Check if running Wine. If yes, ignore env vars
  290. from winreg import ConnectRegistry, OpenKey, CloseKey, HKEY_CURRENT_USER;
  291. reg = ConnectRegistry(None, HKEY_CURRENT_USER);
  292. key = OpenKey(reg, r"SOFTWARE\Wine");
  293. CloseKey(key);
  294. readEnvVars = False;
  295. CloseKey(reg);
  296. #endif
  297. if (readEnvVars)
  298. {
  299. gCarla.DEFAULT_LADSPA_PATH = getenvWithFallback("LADSPA_PATH", DEFAULT_LADSPA_PATH).split(splitter);
  300. gCarla.DEFAULT_DSSI_PATH = getenvWithFallback("DSSI_PATH", DEFAULT_DSSI_PATH).split(splitter);
  301. gCarla.DEFAULT_LV2_PATH = getenvWithFallback("LV2_PATH", DEFAULT_LV2_PATH).split(splitter);
  302. gCarla.DEFAULT_VST_PATH = getenvWithFallback("VST_PATH", DEFAULT_VST_PATH).split(splitter);
  303. gCarla.DEFAULT_VST3_PATH = getenvWithFallback("VST3_PATH", DEFAULT_VST3_PATH).split(splitter);
  304. gCarla.DEFAULT_AU_PATH = getenvWithFallback("AU_PATH", DEFAULT_AU_PATH).split(splitter);
  305. gCarla.DEFAULT_CSOUND_PATH = getenvWithFallback("CSOUND_PATH", DEFAULT_CSOUND_PATH).split(splitter);
  306. gCarla.DEFAULT_GIG_PATH = getenvWithFallback("GIG_PATH", DEFAULT_GIG_PATH).split(splitter);
  307. gCarla.DEFAULT_SF2_PATH = getenvWithFallback("SF2_PATH", DEFAULT_SF2_PATH).split(splitter);
  308. gCarla.DEFAULT_SFZ_PATH = getenvWithFallback("SFZ_PATH", DEFAULT_SFZ_PATH).split(splitter);
  309. }
  310. else
  311. {
  312. gCarla.DEFAULT_LADSPA_PATH = DEFAULT_LADSPA_PATH.split(splitter);
  313. gCarla.DEFAULT_DSSI_PATH = DEFAULT_DSSI_PATH.split(splitter);
  314. gCarla.DEFAULT_LV2_PATH = DEFAULT_LV2_PATH.split(splitter);
  315. gCarla.DEFAULT_VST_PATH = DEFAULT_VST_PATH.split(splitter);
  316. gCarla.DEFAULT_VST3_PATH = DEFAULT_VST3_PATH.split(splitter);
  317. gCarla.DEFAULT_AU_PATH = DEFAULT_AU_PATH.split(splitter);
  318. gCarla.DEFAULT_CSOUND_PATH = DEFAULT_CSOUND_PATH.split(splitter);
  319. gCarla.DEFAULT_GIG_PATH = DEFAULT_GIG_PATH.split(splitter);
  320. gCarla.DEFAULT_SF2_PATH = DEFAULT_SF2_PATH.split(splitter);
  321. gCarla.DEFAULT_SFZ_PATH = DEFAULT_SFZ_PATH.split(splitter);
  322. }
  323. }
  324. // ------------------------------------------------------------------------------------------------------------
  325. // Search for Carla tools
  326. static
  327. QString findTool(const QString& toolDir, const QString& toolName)
  328. {
  329. QDir tmp(QDir::current());
  330. tmp.cd(toolDir);
  331. QString path = tmp.filePath(toolName);
  332. if (QFile(path).exists())
  333. return path;
  334. foreach (const QString& p, PATH)
  335. {
  336. path = QDir(p).filePath(toolName);
  337. if (QFile(path).exists())
  338. return path;
  339. }
  340. return "";
  341. }
  342. // ------------------------------------------------------------------------------------------------------------
  343. // Init host
  344. void initHost(const QString& /*appName*/, const char* const libPrefix, bool failError)
  345. {
  346. init();
  347. // -------------------------------------------------------------
  348. // Set Carla library name
  349. QString libname = "libcarla_";
  350. if (gCarla.isControl)
  351. libname += "control2";
  352. else
  353. libname += "standalone2";
  354. #if defined(CARLA_OS_WIN)
  355. libname += ".dll";
  356. #elif defined(CARLA_OS_MAC)
  357. libname += ".dylib";
  358. #else
  359. libname += ".so";
  360. #endif
  361. // -------------------------------------------------------------
  362. // Search for the Carla library
  363. QString libfilename = "";
  364. if (libPrefix != nullptr)
  365. {
  366. QDir tmp(libPrefix);
  367. tmp.cd("lib");
  368. tmp.cd("carla");
  369. libfilename = tmp.filePath(libname);
  370. }
  371. else
  372. {
  373. QDir tmp(QDir::current());
  374. tmp.cdUp();
  375. tmp.cd("backend");
  376. QString path = tmp.filePath(libname);
  377. if (QFile(path).exists())
  378. {
  379. libfilename = path;
  380. }
  381. else
  382. {
  383. QStringList CARLA_LIB_PATH;
  384. const char* const envLibPath = std::getenv("CARLA_LIB_PATH");
  385. if (envLibPath != nullptr && QDir(envLibPath).exists())
  386. {
  387. CARLA_LIB_PATH << envLibPath;
  388. }
  389. else
  390. {
  391. #if defined(CARLA_OS_WIN)
  392. //CARLA_LIB_PATH << (os.path.join(PROGRAMFILES, "Carla"),);
  393. #elif defined(CARLA_OS_MAC)
  394. CARLA_LIB_PATH << "/opt/local/lib";
  395. CARLA_LIB_PATH << "/usr/local/lib/";
  396. CARLA_LIB_PATH << "/usr/lib";
  397. #else
  398. CARLA_LIB_PATH << "/usr/local/lib/";
  399. CARLA_LIB_PATH << "/usr/lib";
  400. #endif
  401. }
  402. foreach (const QString& libpath, CARLA_LIB_PATH)
  403. {
  404. tmp = libpath;
  405. tmp.cd("carla");
  406. path = tmp.filePath(libname);
  407. if (QFile(path).exists())
  408. {
  409. libfilename = path;
  410. break;
  411. }
  412. }
  413. }
  414. }
  415. // -------------------------------------------------------------
  416. // find windows tools
  417. gCarla.discovery_win32 = findTool("discovery", "carla-discovery-win32.exe");
  418. gCarla.discovery_win64 = findTool("discovery", "carla-discovery-win64.exe");
  419. #ifndef CARLA_OS_WIN
  420. // -------------------------------------------------------------
  421. // find native and posix tools
  422. gCarla.discovery_native = findTool("discovery", "carla-discovery-native");
  423. gCarla.discovery_posix32 = findTool("discovery", "carla-discovery-posix32");
  424. gCarla.discovery_posix64 = findTool("discovery", "carla-discovery-posix64");
  425. #endif
  426. // -------------------------------------------------------------
  427. if (libfilename.isEmpty() && ! gCarla.isPlugin)
  428. {
  429. if (failError)
  430. {
  431. QMessageBox::critical(nullptr, "Error", "Failed to find the carla library, cannot continue");
  432. std::exit(1);
  433. }
  434. return;
  435. }
  436. // -------------------------------------------------------------
  437. // Set binary path
  438. QDir tmp;
  439. QString libfolder, localBinaries, systemBinaries;
  440. libfolder = libfilename.replace(libname, "");
  441. tmp = libfolder;
  442. tmp.cdUp();
  443. tmp.cd("bridges");
  444. localBinaries = tmp.absolutePath();
  445. tmp = libfolder;
  446. tmp.cd("bridges");
  447. systemBinaries = tmp.absolutePath();
  448. if (QDir(libfolder).exists())
  449. carla_set_engine_option(ENGINE_OPTION_PATH_BINARIES, 0, libfolder.toUtf8().constData());
  450. else if (QDir(localBinaries).exists())
  451. carla_set_engine_option(ENGINE_OPTION_PATH_BINARIES, 0, localBinaries.toUtf8().constData());
  452. else if (QDir(systemBinaries).exists())
  453. carla_set_engine_option(ENGINE_OPTION_PATH_BINARIES, 0, systemBinaries.toUtf8().constData());
  454. // -------------------------------------------------------------
  455. // Set resource path
  456. QString localResources, systemResources;
  457. tmp = libfolder;
  458. tmp.cdUp();
  459. tmp.cd("modules");
  460. tmp.cd("native-plugins");
  461. tmp.cd("resources");
  462. localResources = tmp.absolutePath();
  463. tmp = libfolder;
  464. tmp.cd("resources");
  465. systemResources = tmp.absolutePath();
  466. if (QDir(localResources).exists())
  467. carla_set_engine_option(ENGINE_OPTION_PATH_RESOURCES, 0, localResources.toUtf8().constData());
  468. else if (QDir(systemResources).exists())
  469. carla_set_engine_option(ENGINE_OPTION_PATH_RESOURCES, 0, systemResources.toUtf8().constData());
  470. }
  471. // ------------------------------------------------------------------------------------------------------------
  472. // Get Icon from user theme, using our own as backup (Oxygen)
  473. QIcon getIcon(const QString& icon, const int size)
  474. {
  475. return QIcon::fromTheme(icon, QIcon(QString(":/%ix%i/%s.png").arg(size).arg(size).arg(icon)));
  476. }
  477. // ------------------------------------------------------------------------------------------------------------
  478. // Signal handler
  479. static inline // TODO - remove inline
  480. void signalHandler(/*sig, frame*/)
  481. {
  482. if (gCarla.gui == nullptr)
  483. return;
  484. // if (sig == SIGINT || sig == SIGTERM)
  485. // emit(gCarla.gui.SIGTERM);
  486. #ifdef HAVE_SIGUSR1
  487. // else if (sig == SIGUSR1)
  488. // emit(gCarla.gui.SIGUSR1);
  489. #endif
  490. }
  491. void setUpSignals()
  492. {
  493. //signal(SIGINT, signalHandler);
  494. //signal(SIGTERM, signalHandler);
  495. #ifdef HAVE_SIGUSR1
  496. //signal(SIGUSR1, signalHandler);
  497. #endif
  498. }
  499. // ------------------------------------------------------------------------------------------------------------
  500. // QLineEdit and QPushButton combo
  501. QString getAndSetPath(QWidget* const parent, const QString& currentPath, QLineEdit* const lineEdit)
  502. {
  503. QString newPath = QFileDialog::getExistingDirectory(parent, parent->tr("Set Path"), currentPath, QFileDialog::ShowDirsOnly);
  504. if (! newPath.isEmpty())
  505. lineEdit->setText(newPath);
  506. return newPath;
  507. }
  508. // ------------------------------------------------------------------------------------------------------------
  509. // Custom MessageBox
  510. int CustomMessageBox(QWidget* const parent, const QMessageBox::Icon icon, const QString& title, const QString& text, const QString& extraText, const QMessageBox::StandardButtons buttons, const QMessageBox::StandardButton defButton)
  511. {
  512. QMessageBox msgBox(parent);
  513. msgBox.setIcon(icon);
  514. msgBox.setWindowTitle(title);
  515. msgBox.setText(text);
  516. msgBox.setInformativeText(extraText);
  517. msgBox.setStandardButtons(buttons);
  518. msgBox.setDefaultButton(defButton);
  519. return msgBox.exec();
  520. }
  521. // ------------------------------------------------------------------------------------------------------------