Cleanup
[carla.git] / source / includes / CarlaNativeExtUI.hpp
blob31f867397f9b905cbf40cd36770f56c0a730544a
1 /*
2 * Carla Native Plugin API (C++)
3 * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
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.
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.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED
19 #define CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED
21 #include "CarlaNative.hpp"
22 #include "CarlaExternalUI.hpp"
23 #include "CarlaMIDI.h"
25 /*!
26 * @defgroup CarlaNativeAPI Carla Native API
27 * @{
30 // -----------------------------------------------------------------------
31 // Native Plugin and External UI class
33 class NativePluginAndUiClass : public NativePluginClass
34 #ifndef CARLA_OS_WASM
35 , public CarlaExternalUI
36 #endif
38 public:
39 NativePluginAndUiClass(const NativeHostDescriptor* const host, const char* const pathToExternalUI)
40 : NativePluginClass(host),
41 #ifndef CARLA_OS_WASM
42 CarlaExternalUI(),
43 #endif
44 fExtUiPath(getResourceDir())
46 fExtUiPath += CARLA_OS_SEP_STR;
47 fExtUiPath += pathToExternalUI;
48 #ifdef CARLA_OS_WIN
49 fExtUiPath += ".exe";
50 #endif
53 const char* getExtUiPath() const noexcept
55 return fExtUiPath;
58 #ifndef CARLA_OS_WASM
59 protected:
60 // -------------------------------------------------------------------
61 // Plugin UI calls
63 void uiShow(const bool show) override
65 if (show)
67 if (isPipeRunning())
69 writeFocusMessage();
70 return;
73 carla_stdout("Trying to start UI using \"%s\"", fExtUiPath.buffer());
75 CarlaExternalUI::setData(fExtUiPath, getSampleRate(), getUiName());
77 if (! CarlaExternalUI::startPipeServer(true))
79 uiClosed();
80 hostUiUnavailable();
83 else
85 CarlaExternalUI::stopPipeServer(2000);
89 void uiIdle() override
91 CarlaExternalUI::idlePipe();
93 switch (CarlaExternalUI::getAndResetUiState())
95 case CarlaExternalUI::UiNone:
96 case CarlaExternalUI::UiShow:
97 break;
98 case CarlaExternalUI::UiCrashed:
99 uiClosed();
100 hostUiUnavailable();
101 break;
102 case CarlaExternalUI::UiHide:
103 uiClosed();
104 CarlaExternalUI::stopPipeServer(1000);
105 break;
109 void uiSetParameterValue(const uint32_t index, const float value) noexcept override
111 CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),);
113 writeControlMessage(index, value);
116 void uiSetMidiProgram(const uint8_t channel, const uint32_t bank, const uint32_t program) noexcept override
118 CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
120 writeProgramMessage(channel, bank, program);
123 void uiSetCustomData(const char* const key, const char* const value) noexcept override
125 CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
126 CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
128 writeConfigureMessage(key, value);
131 void uiNameChanged(const char* const uiName) override
133 CARLA_SAFE_ASSERT_RETURN(uiName != nullptr && uiName[0] != '\0',);
135 const CarlaMutexLocker cml(getPipeLock());
137 if (! writeMessage("uiTitle\n", 8))
138 return;
139 if (! writeAndFixMessage(uiName))
140 return;
142 syncMessages();
145 bool uiMIDIEvent(const uint8_t size, const uint8_t data[]) override
147 if (size != 3)
148 return false;
150 const uint8_t status = MIDI_GET_STATUS_FROM_DATA(data);
152 if (! (MIDI_IS_STATUS_NOTE_ON(status) || MIDI_IS_STATUS_NOTE_OFF(status)))
153 return false;
155 writeMidiNoteMessage(MIDI_IS_STATUS_NOTE_ON(status),
156 MIDI_GET_CHANNEL_FROM_DATA(data),
157 data[1], data[2]);
158 return true;
161 // -------------------------------------------------------------------
162 // Pipe Server calls
164 bool msgReceived(const char* const msg) noexcept override
166 if (CarlaExternalUI::msgReceived(msg))
167 return true;
169 if (std::strcmp(msg, "control") == 0)
171 uint32_t param;
172 float value;
174 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(param), true);
175 CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
177 try {
178 uiParameterChanged(param, value);
179 } CARLA_SAFE_EXCEPTION("uiParameterChanged");
181 return true;
184 if (std::strcmp(msg, "program") == 0)
186 uint8_t channel;
187 uint32_t bank, program;
189 CARLA_SAFE_ASSERT_RETURN(readNextLineAsByte(channel), true);
190 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(bank), true);
191 CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(program), true);
192 CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, true);
194 try {
195 uiMidiProgramChanged(static_cast<uint8_t>(channel), bank, program);
196 } CARLA_SAFE_EXCEPTION("uiMidiProgramChanged");
198 return true;
201 if (std::strcmp(msg, "configure") == 0)
203 const char* key;
204 const char* value;
206 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(key, true), true);
207 CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(value, false), true);
209 try {
210 uiCustomDataChanged(key, value);
211 } CARLA_SAFE_EXCEPTION("uiCustomDataChanged");
213 delete[] key;
215 return true;
218 return false;
220 #endif
222 private:
223 CarlaString fExtUiPath;
225 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePluginAndUiClass)
228 /**@}*/
230 // -----------------------------------------------------------------------
232 #endif // CARLA_NATIVE_EXTERNAL_UI_HPP_INCLUDED