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.

173 lines
3.8KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #ifndef DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED
  17. #define DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED
  18. #include "String.hpp"
  19. #ifdef DISTRHO_OS_WINDOWS
  20. # error Unsupported platform!
  21. #else
  22. # include <cerrno>
  23. # include <signal.h>
  24. # include <sys/wait.h>
  25. # include <unistd.h>
  26. #endif
  27. START_NAMESPACE_DISTRHO
  28. // -----------------------------------------------------------------------
  29. // ExternalWindow class
  30. class ExternalWindow
  31. {
  32. public:
  33. ExternalWindow(const uint w = 1, const uint h = 1, const char* const t = "")
  34. : width(w),
  35. height(h),
  36. title(t),
  37. pid(0) {}
  38. virtual ~ExternalWindow()
  39. {
  40. terminateAndWaitForProcess();
  41. }
  42. uint getWidth() const noexcept
  43. {
  44. return width;
  45. }
  46. uint getHeight() const noexcept
  47. {
  48. return height;
  49. }
  50. const char* getTitle() const noexcept
  51. {
  52. return title;
  53. }
  54. void setTitle(const char* const t) noexcept
  55. {
  56. title = t;
  57. }
  58. bool isRunning() noexcept
  59. {
  60. if (pid <= 0)
  61. return false;
  62. const pid_t p = ::waitpid(pid, nullptr, WNOHANG);
  63. if (p == pid || (p == -1 && errno == ECHILD))
  64. {
  65. printf("NOTICE: Child process exited while idle\n");
  66. pid = 0;
  67. return false;
  68. }
  69. return true;
  70. }
  71. protected:
  72. bool startExternalProcess(const char* args[])
  73. {
  74. terminateAndWaitForProcess();
  75. pid = vfork();
  76. switch (pid)
  77. {
  78. case 0:
  79. execvp(args[0], (char**)args);
  80. _exit(1);
  81. return false;
  82. case -1:
  83. printf("Could not start external ui\n");
  84. return false;
  85. default:
  86. return true;
  87. }
  88. }
  89. private:
  90. uint width;
  91. uint height;
  92. String title;
  93. pid_t pid;
  94. friend class UIExporter;
  95. void terminateAndWaitForProcess()
  96. {
  97. if (pid <= 0)
  98. return;
  99. printf("Waiting for previous process to stop,,,\n");
  100. bool sendTerm = true;
  101. for (pid_t p;;)
  102. {
  103. p = ::waitpid(pid, nullptr, WNOHANG);
  104. switch (p)
  105. {
  106. case 0:
  107. if (sendTerm)
  108. {
  109. sendTerm = false;
  110. ::kill(pid, SIGTERM);
  111. }
  112. break;
  113. case -1:
  114. if (errno == ECHILD)
  115. {
  116. printf("Done! (no such process)\n");
  117. pid = 0;
  118. return;
  119. }
  120. break;
  121. default:
  122. if (p == pid)
  123. {
  124. printf("Done! (clean wait)\n");
  125. pid = 0;
  126. return;
  127. }
  128. break;
  129. }
  130. // 5 msec
  131. usleep(5*1000);
  132. }
  133. }
  134. DISTRHO_DECLARE_NON_COPY_CLASS(ExternalWindow)
  135. };
  136. // -----------------------------------------------------------------------
  137. END_NAMESPACE_DISTRHO
  138. #endif // DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED