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.

zita-common.hpp 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2012-2015 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_ZITA_COMMON_HPP_INCLUDED
  18. #define CARLA_ZITA_COMMON_HPP_INCLUDED
  19. #include "CarlaMutex.hpp"
  20. #include "CarlaThread.hpp"
  21. #include "LinkedList.hpp"
  22. #include <png.h>
  23. #include <clxclient.h>
  24. #include <cairo/cairo.h>
  25. #include <cairo/cairo-xlib.h>
  26. #define EV_X11 16
  27. #define EV_EXIT 31
  28. // -----------------------------------------------------------------------
  29. struct x_cairo_t {
  30. cairo_t * type;
  31. cairo_surface_t* surf;
  32. x_cairo_t() noexcept
  33. : type(nullptr),
  34. surf(nullptr) {}
  35. ~x_cairo_t()
  36. {
  37. cairo_destroy(type);
  38. cairo_surface_destroy(surf);
  39. }
  40. void initIfNeeded(X_display* const disp)
  41. {
  42. if (surf != nullptr)
  43. return;
  44. surf = cairo_xlib_surface_create(disp->dpy(), 0, disp->dvi(), 50, 50);
  45. type = cairo_create(surf);
  46. }
  47. };
  48. // -----------------------------------------------------------------------
  49. struct X_handler_Param {
  50. uint32_t index;
  51. float value;
  52. };
  53. typedef LinkedList<X_handler_Param> ParamList;
  54. template<class MainwinType>
  55. class X_handler_thread : public CarlaThread
  56. {
  57. public:
  58. struct SetValueCallback {
  59. virtual ~SetValueCallback() {}
  60. virtual void setParameterValueFromHandlerThread(const uint32_t index, const float value) = 0;
  61. };
  62. X_handler_thread(SetValueCallback* const cb)
  63. : CarlaThread("X_handler"),
  64. fCallback(cb),
  65. fMutex(),
  66. fHandler(nullptr),
  67. fRootwin(nullptr),
  68. fMainwin(nullptr),
  69. fClosed(false),
  70. fParamMutex(),
  71. fParamChanges() {}
  72. void setupAndRun(X_handler* const h, X_rootwin* const r, MainwinType* const m) noexcept
  73. {
  74. const CarlaMutexLocker cml(fMutex);
  75. fHandler = h;
  76. fRootwin = r;
  77. fMainwin = m;
  78. startThread();
  79. }
  80. void stopThread() noexcept
  81. {
  82. signalThreadShouldExit();
  83. {
  84. const CarlaMutexLocker cml(fMutex);
  85. fHandler = nullptr;
  86. fRootwin = nullptr;
  87. fMainwin = nullptr;
  88. }
  89. CarlaThread::stopThread(1000);
  90. }
  91. CarlaMutex& getLock() noexcept
  92. {
  93. return fMutex;
  94. }
  95. void setParameterValueLater(const uint32_t index, const float value) noexcept
  96. {
  97. const CarlaMutexLocker cml(fParamMutex);
  98. for (ParamList::Itenerator it = fParamChanges.begin(); it.valid(); it.next())
  99. {
  100. X_handler_Param& param(it.getValue());
  101. if (param.index != index)
  102. continue;
  103. param.value = value;
  104. return;
  105. }
  106. const X_handler_Param param = { index, value };
  107. fParamChanges.append(param);
  108. }
  109. bool wasClosed() noexcept
  110. {
  111. if (fClosed)
  112. {
  113. fClosed = false;
  114. return true;
  115. }
  116. return false;
  117. }
  118. private:
  119. SetValueCallback* const fCallback;
  120. CarlaMutex fMutex;
  121. X_handler* fHandler;
  122. X_rootwin* fRootwin;
  123. MainwinType* fMainwin;
  124. volatile bool fClosed;
  125. CarlaMutex fParamMutex;
  126. ParamList fParamChanges;
  127. void run() override
  128. {
  129. for (; ! shouldThreadExit();)
  130. {
  131. const CarlaMutexLocker cml(fMutex);
  132. CARLA_SAFE_ASSERT_RETURN(fMainwin != nullptr,);
  133. {
  134. const CarlaMutexLocker cml(fParamMutex);
  135. for (ParamList::Itenerator it = fParamChanges.begin(); it.valid(); it.next())
  136. {
  137. const X_handler_Param& param(it.getValue());
  138. fCallback->setParameterValueFromHandlerThread(param.index, param.value);
  139. }
  140. fParamChanges.clear();
  141. }
  142. switch (fMainwin->process())
  143. {
  144. case EV_X11:
  145. fRootwin->handle_event();
  146. fHandler->next_event();
  147. break;
  148. case EV_EXIT:
  149. fClosed = true;
  150. fHandler = nullptr;
  151. fMainwin = nullptr;
  152. fRootwin = nullptr;
  153. return;
  154. case Esync::EV_TIME:
  155. fRootwin->handle_event();
  156. break;
  157. default:
  158. carla_stdout("custom X11 event for zita plugs");
  159. break;
  160. }
  161. }
  162. }
  163. };
  164. // -----------------------------------------------------------------------
  165. #endif // CARLA_ZITA_COMMON_HPP_INCLUDED