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.

249 lines
6.7KB

  1. /*
  2. * Carla Native Plugin API (C++)
  3. * Copyright (C) 2012-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. #ifndef CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED
  18. #define CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED
  19. #include "CarlaNative.hpp"
  20. #include "CarlaExternalUI.hpp"
  21. /*!
  22. * @defgroup CarlaNativeAPI Carla Native API
  23. * @{
  24. */
  25. // -----------------------------------------------------------------------
  26. // Native Plugin and External UI class
  27. class NativePluginAndUiClass : public NativePluginClass,
  28. public CarlaExternalUI
  29. {
  30. public:
  31. NativePluginAndUiClass(const NativeHostDescriptor* const host, const char* const extUiPath)
  32. : NativePluginClass(host),
  33. CarlaExternalUI(),
  34. fExtUiPath(getResourceDir())
  35. {
  36. fExtUiPath += CARLA_OS_SEP_STR;
  37. fExtUiPath += extUiPath;
  38. }
  39. const char* getExtUiPath() const noexcept
  40. {
  41. return fExtUiPath;
  42. }
  43. protected:
  44. // -------------------------------------------------------------------
  45. // Plugin UI calls
  46. void uiShow(const bool show) override
  47. {
  48. if (show)
  49. {
  50. if (isPipeRunning())
  51. {
  52. const CarlaMutexLocker cml(getPipeLock());
  53. writeMessage("focus\n", 6);
  54. flushMessages();
  55. return;
  56. }
  57. carla_stdout("Trying to start UI using \"%s\"", fExtUiPath.buffer());
  58. CarlaExternalUI::setData(fExtUiPath, getSampleRate(), getUiName());
  59. if (! CarlaExternalUI::startPipeServer(true))
  60. {
  61. uiClosed();
  62. hostUiUnavailable();
  63. }
  64. }
  65. else
  66. {
  67. CarlaExternalUI::stopPipeServer(2000);
  68. }
  69. }
  70. void uiIdle() override
  71. {
  72. CarlaExternalUI::idlePipe();
  73. switch (CarlaExternalUI::getAndResetUiState())
  74. {
  75. case CarlaExternalUI::UiNone:
  76. case CarlaExternalUI::UiShow:
  77. break;
  78. case CarlaExternalUI::UiCrashed:
  79. uiClosed();
  80. hostUiUnavailable();
  81. break;
  82. case CarlaExternalUI::UiHide:
  83. uiClosed();
  84. CarlaExternalUI::stopPipeServer(1000);
  85. break;
  86. }
  87. }
  88. void uiSetParameterValue(const uint32_t index, const float value) noexcept override
  89. {
  90. CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),);
  91. // TODO writeControlMessage and others
  92. char tmpBuf[0xff+1];
  93. tmpBuf[0xff] = '\0';
  94. const CarlaMutexLocker cml(getPipeLock());
  95. const ScopedLocale csl;
  96. writeMessage("control\n", 8);
  97. {
  98. std::snprintf(tmpBuf, 0xff, "%i\n", index);
  99. writeMessage(tmpBuf);
  100. std::snprintf(tmpBuf, 0xff, "%f\n", value);
  101. writeMessage(tmpBuf);
  102. }
  103. flushMessages();
  104. }
  105. void uiSetMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program) noexcept override
  106. {
  107. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  108. char tmpBuf[0xff+1];
  109. tmpBuf[0xff] = '\0';
  110. const CarlaMutexLocker cml(getPipeLock());
  111. writeMessage("program\n", 8);
  112. {
  113. std::snprintf(tmpBuf, 0xff, "%i\n", channel);
  114. writeMessage(tmpBuf);
  115. std::snprintf(tmpBuf, 0xff, "%i\n", bank);
  116. writeMessage(tmpBuf);
  117. std::snprintf(tmpBuf, 0xff, "%i\n", program);
  118. writeMessage(tmpBuf);
  119. }
  120. flushMessages();
  121. }
  122. void uiSetCustomData(const char* const key, const char* const value) noexcept override
  123. {
  124. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  125. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  126. const CarlaMutexLocker cml(getPipeLock());
  127. writeMessage("configure\n", 10);
  128. writeAndFixMessage(key);
  129. writeAndFixMessage(value);
  130. flushMessages();
  131. }
  132. void uiNameChanged(const char* const uiName) override
  133. {
  134. CARLA_SAFE_ASSERT_RETURN(uiName != nullptr && uiName[0] != '\0',);
  135. const CarlaMutexLocker cml(getPipeLock());
  136. writeMessage("uiTitle\n", 8);
  137. writeAndFixMessage(uiName);
  138. flushMessages();
  139. }
  140. // -------------------------------------------------------------------
  141. // Pipe Server calls
  142. bool msgReceived(const char* const msg) noexcept override
  143. {
  144. if (CarlaExternalUI::msgReceived(msg))
  145. return true;
  146. if (std::strcmp(msg, "control") == 0)
  147. {
  148. uint32_t param;
  149. float value;
  150. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(param), true);
  151. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  152. try {
  153. uiParameterChanged(param, value);
  154. } CARLA_SAFE_EXCEPTION("uiParameterChanged");
  155. return true;
  156. }
  157. if (std::strcmp(msg, "program") == 0)
  158. {
  159. uint32_t channel, bank, program;
  160. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(channel), true);
  161. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(bank), true);
  162. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(program), true);
  163. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, true);
  164. try {
  165. uiMidiProgramChanged(static_cast<uint8_t>(channel), bank, program);
  166. } CARLA_SAFE_EXCEPTION("uiMidiProgramChanged");
  167. return true;
  168. }
  169. if (std::strcmp(msg, "configure") == 0)
  170. {
  171. const char* key;
  172. const char* value;
  173. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(key), true);
  174. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(value), true);
  175. try {
  176. uiCustomDataChanged(key, value);
  177. } CARLA_SAFE_EXCEPTION("uiCustomDataChanged");
  178. delete[] key;
  179. delete[] value;
  180. return true;
  181. }
  182. return false;
  183. }
  184. private:
  185. CarlaString fExtUiPath;
  186. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePluginAndUiClass)
  187. };
  188. /**@}*/
  189. // -----------------------------------------------------------------------
  190. #endif // CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED