Signed-off-by: falkTX <falktx@falktx.com>tags/v2.1-rc2
@@ -183,7 +183,7 @@ enum CarlaLv2Features { | |||
kFeatureIdUiPortMap, | |||
kFeatureIdUiPortSubscribe, | |||
kFeatureIdUiResize, | |||
kFeatureIdUiRequestParameter, | |||
kFeatureIdUiRequestValue, | |||
kFeatureIdUiTouch, | |||
kFeatureIdExternalUi, | |||
kFeatureIdExternalUiOld, | |||
@@ -652,8 +652,8 @@ public: | |||
if (fFeatures[kFeatureIdUiPortMap] != nullptr && fFeatures[kFeatureIdUiPortMap]->data != nullptr) | |||
delete (LV2UI_Port_Map*)fFeatures[kFeatureIdUiPortMap]->data; | |||
if (fFeatures[kFeatureIdUiRequestParameter] != nullptr && fFeatures[kFeatureIdUiRequestParameter]->data != nullptr) | |||
delete (LV2UI_Request_Parameter*)fFeatures[kFeatureIdUiRequestParameter]->data; | |||
if (fFeatures[kFeatureIdUiRequestValue] != nullptr && fFeatures[kFeatureIdUiRequestValue]->data != nullptr) | |||
delete (LV2UI_Request_Value*)fFeatures[kFeatureIdUiRequestValue]->data; | |||
if (fFeatures[kFeatureIdUiResize] != nullptr && fFeatures[kFeatureIdUiResize]->data != nullptr) | |||
delete (LV2UI_Resize*)fFeatures[kFeatureIdUiResize]->data; | |||
@@ -5357,17 +5357,22 @@ public: | |||
return LV2UI_INVALID_PORT_INDEX; | |||
} | |||
LV2UI_Request_Parameter_Status handleUIRequestParameter(const LV2_URID key) | |||
LV2UI_Request_Value_Status handleUIRequestValue(const LV2_URID key, | |||
const LV2_URID type, | |||
const LV2_Feature* const* features) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL, LV2UI_REQUEST_PARAMETER_ERR_UNKNOWN); | |||
carla_debug("CarlaPluginLV2::handleUIRequestParameter(%u)", key); | |||
CARLA_SAFE_ASSERT_RETURN(fUI.type != UI::TYPE_NULL, LV2UI_REQUEST_VALUE_ERR_UNKNOWN); | |||
carla_debug("CarlaPluginLV2::handleUIRequestValue(%u, %u, %p)", key, type, features); | |||
// check if a file browser is already open | |||
if (fUI.fileNeededForURI != nullptr || fUI.fileBrowserOpen) | |||
return LV2UI_REQUEST_PARAMETER_ERR_UNKNOWN; | |||
if (type != kUridAtomPath) | |||
return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED; | |||
const char* const uri = getCustomURIDString(key); | |||
CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri != kUnmapFallback, LV2UI_REQUEST_PARAMETER_ERR_UNSUPPORTED); | |||
CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri != kUnmapFallback, LV2UI_REQUEST_VALUE_ERR_UNKNOWN); | |||
// check if a file browser is already open | |||
if (fUI.fileNeededForURI != nullptr || fUI.fileBrowserOpen) | |||
return LV2UI_REQUEST_VALUE_BUSY; | |||
for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i) | |||
{ | |||
@@ -5379,10 +5384,13 @@ public: | |||
// TODO file browser filters, also store label to use for title | |||
fUI.fileNeededForURI = uri; | |||
return LV2UI_REQUEST_PARAMETER_SUCCESS; | |||
return LV2UI_REQUEST_VALUE_SUCCESS; | |||
} | |||
return LV2UI_REQUEST_PARAMETER_ERR_UNSUPPORTED; | |||
return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED; | |||
// may be unused | |||
(void)features; | |||
} | |||
int handleUIResize(const int width, const int height) | |||
@@ -6190,7 +6198,7 @@ public: | |||
if (std::strcmp(uri, LV2_UI__makeResident) == 0 || std::strcmp(uri, LV2_UI__makeSONameResident) == 0) | |||
canDelete = false; | |||
else if (std::strcmp(uri, LV2_UI__requestParameter) == 0) | |||
else if (std::strcmp(uri, LV2_UI__requestValue) == 0) | |||
pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD; | |||
} | |||
@@ -6372,9 +6380,9 @@ public: | |||
uiPortMapFt->handle = this; | |||
uiPortMapFt->port_index = carla_lv2_ui_port_map; | |||
LV2UI_Request_Parameter* const uiRequestParamFt = new LV2UI_Request_Parameter; | |||
uiRequestParamFt->handle = this; | |||
uiRequestParamFt->request = carla_lv2_ui_request_parameter; | |||
LV2UI_Request_Value* const uiRequestValueFt = new LV2UI_Request_Value; | |||
uiRequestValueFt->handle = this; | |||
uiRequestValueFt->request = carla_lv2_ui_request_value; | |||
LV2UI_Resize* const uiResizeFt = new LV2UI_Resize; | |||
uiResizeFt->handle = this; | |||
@@ -6424,8 +6432,8 @@ public: | |||
fFeatures[kFeatureIdUiPortSubscribe]->URI = LV2_UI__portSubscribe; | |||
fFeatures[kFeatureIdUiPortSubscribe]->data = nullptr; | |||
fFeatures[kFeatureIdUiRequestParameter]->URI = LV2_UI__requestParameter; | |||
fFeatures[kFeatureIdUiRequestParameter]->data = uiRequestParamFt; | |||
fFeatures[kFeatureIdUiRequestValue]->URI = LV2_UI__requestValue; | |||
fFeatures[kFeatureIdUiRequestValue]->data = uiRequestValueFt; | |||
fFeatures[kFeatureIdUiResize]->URI = LV2_UI__resize; | |||
fFeatures[kFeatureIdUiResize]->data = uiResizeFt; | |||
@@ -7156,12 +7164,15 @@ private: | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// UI Request Parameter Feature | |||
static LV2UI_Request_Parameter_Status carla_lv2_ui_request_parameter(LV2UI_Feature_Handle handle, LV2_URID key) | |||
static LV2UI_Request_Value_Status carla_lv2_ui_request_value(LV2UI_Feature_Handle handle, | |||
LV2_URID key, | |||
LV2_URID type, | |||
const LV2_Feature* const* features) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_REQUEST_PARAMETER_ERR_UNKNOWN); | |||
carla_debug("carla_lv2_ui_request_parameter(%p, %u)", handle, key); | |||
CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_REQUEST_VALUE_ERR_UNKNOWN); | |||
carla_debug("carla_lv2_ui_request_value(%p, %u, %u, %p)", handle, key, type, features); | |||
return ((CarlaPluginLV2*)handle)->handleUIRequestParameter(key); | |||
return ((CarlaPluginLV2*)handle)->handleUIRequestValue(key, type, features); | |||
} | |||
// ------------------------------------------------------------------- | |||
@@ -7311,17 +7322,18 @@ bool CarlaPipeServerLV2::msgReceived(const char* const msg) noexcept | |||
return true; | |||
} | |||
if (std::strcmp(msg, "requestparam") == 0) | |||
if (std::strcmp(msg, "requestvalue") == 0) | |||
{ | |||
uint32_t urid; | |||
uint32_t key, type; | |||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(urid), true); | |||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(key), true); | |||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(type), true); | |||
if (urid != 0) | |||
if (key != 0) | |||
{ | |||
try { | |||
kPlugin->handleUIRequestParameter(urid); | |||
} CARLA_SAFE_EXCEPTION("msgReceived requestparam"); | |||
kPlugin->handleUIRequestValue(key, type, nullptr); | |||
} CARLA_SAFE_EXCEPTION("msgReceived requestvalue"); | |||
} | |||
return true; | |||
@@ -126,7 +126,7 @@ enum CarlaLv2Features { | |||
kFeatureIdUiParent, | |||
kFeatureIdUiPortMap, | |||
kFeatureIdUiPortSubscribe, | |||
kFeatureIdUiRequestParameter, | |||
kFeatureIdUiRequestValue, | |||
kFeatureIdUiResize, | |||
kFeatureIdUiTouch, | |||
kFeatureCount | |||
@@ -277,9 +277,9 @@ public: | |||
uiPortMapFt->handle = this; | |||
uiPortMapFt->port_index = carla_lv2_ui_port_map; | |||
LV2UI_Request_Parameter* const uiRequestParamFt = new LV2UI_Request_Parameter; | |||
uiRequestParamFt->handle = this; | |||
uiRequestParamFt->request = carla_lv2_ui_request_parameter; | |||
LV2UI_Request_Value* const uiRequestValueFt = new LV2UI_Request_Value; | |||
uiRequestValueFt->handle = this; | |||
uiRequestValueFt->request = carla_lv2_ui_request_value; | |||
LV2UI_Resize* const uiResizeFt = new LV2UI_Resize; | |||
uiResizeFt->handle = this; | |||
@@ -339,8 +339,8 @@ public: | |||
fFeatures[kFeatureIdUiPortSubscribe]->URI = LV2_UI__portSubscribe; | |||
fFeatures[kFeatureIdUiPortSubscribe]->data = nullptr; | |||
fFeatures[kFeatureIdUiRequestParameter]->URI = LV2_UI__requestParameter; | |||
fFeatures[kFeatureIdUiRequestParameter]->data = uiRequestParamFt; | |||
fFeatures[kFeatureIdUiRequestValue]->URI = LV2_UI__requestValue; | |||
fFeatures[kFeatureIdUiRequestValue]->data = uiRequestValueFt; | |||
fFeatures[kFeatureIdUiResize]->URI = LV2_UI__resize; | |||
fFeatures[kFeatureIdUiResize]->data = uiResizeFt; | |||
@@ -373,7 +373,7 @@ public: | |||
delete (LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data; | |||
delete (LV2_URID_Unmap*)fFeatures[kFeatureIdUridUnmap]->data; | |||
delete (LV2UI_Port_Map*)fFeatures[kFeatureIdUiPortMap]->data; | |||
delete (LV2UI_Request_Parameter*)fFeatures[kFeatureIdUiRequestParameter]->data; | |||
delete (LV2UI_Request_Value*)fFeatures[kFeatureIdUiRequestValue]->data; | |||
delete (LV2UI_Resize*)fFeatures[kFeatureIdUiResize]->data; | |||
for (uint32_t i=0; i < kFeatureCount; ++i) | |||
@@ -762,15 +762,20 @@ public: | |||
return LV2UI_INVALID_PORT_INDEX; | |||
} | |||
LV2UI_Request_Parameter_Status handleUiRequestParameter(const LV2_URID key) | |||
LV2UI_Request_Value_Status handleUiRequestValue(const LV2_URID key, | |||
const LV2_URID type, | |||
const LV2_Feature* const* features) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fToolkit != nullptr, LV2UI_REQUEST_PARAMETER_ERR_UNKNOWN); | |||
carla_debug("CarlaPluginLV2::handleUIRequestParameter(%u)", key); | |||
CARLA_SAFE_ASSERT_RETURN(fToolkit != nullptr, LV2UI_REQUEST_VALUE_ERR_UNKNOWN); | |||
carla_debug("CarlaLv2Client::handleUIRequestValue(%u, %u, %p)", key, type, features); | |||
// TODO check if a file browser is already open | |||
if (type != kUridAtomPath) | |||
return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED; | |||
const char* const uri = getCustomURIDString(key); | |||
CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri != kUnmapFallback, LV2UI_REQUEST_PARAMETER_ERR_UNSUPPORTED); | |||
CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri != kUnmapFallback, LV2UI_REQUEST_VALUE_ERR_UNKNOWN); | |||
// TODO check if a file browser is already open | |||
for (uint32_t i=0; i < fRdfDescriptor->ParameterCount; ++i) | |||
{ | |||
@@ -783,19 +788,27 @@ public: | |||
if (isPipeRunning()) | |||
{ | |||
char tmpBuf[0xff]; | |||
std::snprintf(tmpBuf, 0xff-1, "%u\n", key); | |||
tmpBuf[0xff-1] = '\0'; | |||
const CarlaMutexLocker cml(getPipeLock()); | |||
writeMessage("requestparam\n", 13); | |||
writeMessage("requestvalue\n", 13); | |||
std::snprintf(tmpBuf, 0xff-1, "%u\n", key); | |||
tmpBuf[0xff-1] = '\0'; | |||
writeMessage(tmpBuf); | |||
std::snprintf(tmpBuf, 0xff-1, "%u\n", type); | |||
tmpBuf[0xff-1] = '\0'; | |||
writeMessage(tmpBuf); | |||
} | |||
return LV2UI_REQUEST_PARAMETER_SUCCESS; | |||
return LV2UI_REQUEST_VALUE_SUCCESS; | |||
} | |||
return LV2UI_REQUEST_PARAMETER_ERR_UNSUPPORTED; | |||
return LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED; | |||
// may be unused | |||
(void)features; | |||
} | |||
int handleUiResize(const int width, const int height) | |||
@@ -1299,12 +1312,15 @@ private: | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
// UI Request Parameter Feature | |||
static LV2UI_Request_Parameter_Status carla_lv2_ui_request_parameter(LV2UI_Feature_Handle handle, LV2_URID key) | |||
static LV2UI_Request_Value_Status carla_lv2_ui_request_value(LV2UI_Feature_Handle handle, | |||
LV2_URID key, | |||
LV2_URID type, | |||
const LV2_Feature* const* features) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_REQUEST_PARAMETER_ERR_UNKNOWN); | |||
carla_debug("carla_lv2_ui_request_parameter(%p, %u)", handle, key); | |||
CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_REQUEST_VALUE_ERR_UNKNOWN); | |||
carla_debug("carla_lv2_ui_request_value(%p, %u, %u, %p)", handle, key, type, features); | |||
return ((CarlaLv2Client*)handle)->handleUiRequestParameter(key); | |||
return ((CarlaLv2Client*)handle)->handleUiRequestValue(key, type, features); | |||
} | |||
// ---------------------------------------------------------------------------------------------------------------- | |||
@@ -62,7 +62,7 @@ | |||
#define LV2_UI__protocol LV2_UI_PREFIX "protocol" ///< http://lv2plug.in/ns/extensions/ui#protocol | |||
#define LV2_UI__floatProtocol LV2_UI_PREFIX "floatProtocol" ///< http://lv2plug.in/ns/extensions/ui#floatProtocol | |||
#define LV2_UI__peakProtocol LV2_UI_PREFIX "peakProtocol" ///< http://lv2plug.in/ns/extensions/ui#peakProtocol | |||
#define LV2_UI__requestParameter LV2_UI_PREFIX "requestParameter" ///< http://lv2plug.in/ns/extensions/ui#requestParameter | |||
#define LV2_UI__requestValue LV2_UI_PREFIX "requestValue" ///< http://lv2plug.in/ns/extensions/ui#requestValue | |||
#define LV2_UI__resize LV2_UI_PREFIX "resize" ///< http://lv2plug.in/ns/extensions/ui#resize | |||
#define LV2_UI__scaleFactor LV2_UI_PREFIX "scaleFactor" ///< http://lv2plug.in/ns/extensions/ui#scaleFactor | |||
#define LV2_UI__showInterface LV2_UI_PREFIX "showInterface" ///< http://lv2plug.in/ns/extensions/ui#showInterface | |||
@@ -348,14 +348,25 @@ typedef struct _LV2UI_Touch { | |||
bool grabbed); | |||
} LV2UI_Touch; | |||
/** A status code for LV2UI_Request_Parameter::request. */ | |||
/** | |||
A status code for LV2UI_Request_Value::request. | |||
*/ | |||
typedef enum { | |||
/** | |||
Completed successfully. | |||
The host will set the parameter later if the user choses a new value. | |||
*/ | |||
LV2UI_REQUEST_PARAMETER_SUCCESS, | |||
LV2UI_REQUEST_VALUE_SUCCESS, | |||
/** | |||
Parameter already being requested. | |||
The host is already requesting a parameter from the user (for example, a | |||
dialog is visible), or the UI is otherwise busy and can not make this | |||
request. | |||
*/ | |||
LV2UI_REQUEST_VALUE_BUSY, | |||
/** | |||
Unknown parameter. | |||
@@ -363,7 +374,7 @@ typedef enum { | |||
The host is not aware of this parameter, and is not able to set a new | |||
value for it. | |||
*/ | |||
LV2UI_REQUEST_PARAMETER_ERR_UNKNOWN, | |||
LV2UI_REQUEST_VALUE_ERR_UNKNOWN, | |||
/** | |||
Unsupported parameter. | |||
@@ -372,13 +383,13 @@ typedef enum { | |||
new value for it from the user. This is likely because the host does | |||
not have UI support for choosing a value with the appropriate type. | |||
*/ | |||
LV2UI_REQUEST_PARAMETER_ERR_UNSUPPORTED | |||
} LV2UI_Request_Parameter_Status; | |||
LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED | |||
} LV2UI_Request_Value_Status; | |||
/** | |||
A feature to request a new parameter value from the host. | |||
*/ | |||
typedef struct _LV2UI_Request_Parameter { | |||
typedef struct { | |||
/** | |||
Pointer to opaque data which must be passed to request(). | |||
*/ | |||
@@ -387,27 +398,43 @@ typedef struct _LV2UI_Request_Parameter { | |||
/** | |||
Request a value for a parameter from the host. | |||
The main use case for this is a UI requesting a file path from the host, | |||
but conceptually it can be used to request any parameter value. | |||
This is mainly used by UIs to request values for complex parameters that | |||
don't change often, such as file paths, but it may be used to request | |||
any parameter value. | |||
This function returns immediately, and the return value indicates | |||
whether the host can fulfill the request. The host may notify the | |||
plugin about any new parameter value, for example when a file is | |||
plugin about the new parameter value, for example when a file is | |||
selected by the user, via the usual mechanism. Typically, the host will | |||
send a message (using the atom and path extensions) to the plugin that | |||
sets the new parameter value, and the plugin will notify the UI via a | |||
message as usual for any other parameter change. | |||
send a message to the plugin that sets the new parameter value, and the | |||
plugin will notify the UI via a message as usual for any other parameter | |||
change. | |||
The host can determine details about the property, like the value type, | |||
from the plugin data. | |||
To provide an appropriate UI, the host can determine details about the | |||
parameter from the plugin data as usual. The additional parameters of | |||
this function provide support for more advanced use cases, but in the | |||
simple common case, the plugin will simply pass the key of the desired | |||
parameter and zero for everything else. | |||
@param handle The handle field of this struct. | |||
@param key The URID of the parameter. | |||
@return 0 on success, non-zero on error. | |||
@param type The optional type of the value to request. This can be used | |||
to request a specific value type for parameters that support several. | |||
If non-zero, it must be the URID of an instance of rdfs:Class or | |||
rdfs:Datatype. | |||
@param features Additional features for this request, or NULL. | |||
@return A status code which is 0 on success. | |||
*/ | |||
LV2UI_Request_Parameter_Status (*request)(LV2UI_Feature_Handle handle, | |||
LV2_URID key); | |||
} LV2UI_Request_Parameter; | |||
LV2UI_Request_Value_Status (*request)(LV2UI_Feature_Handle handle, | |||
LV2_URID key, | |||
LV2_URID type, | |||
const LV2_Feature* const* features); | |||
} LV2UI_Request_Value; | |||
/** | |||
UI Idle Interface (LV2_UI__idleInterface) | |||
@@ -3090,7 +3090,7 @@ bool is_lv2_ui_feature_supported(const LV2_URI uri) noexcept | |||
return true; | |||
if (std::strcmp(uri, LV2_UI__portSubscribe) == 0) | |||
return true; | |||
if (std::strcmp(uri, LV2_UI__requestParameter) == 0) | |||
if (std::strcmp(uri, LV2_UI__requestValue) == 0) | |||
return true; | |||
if (std::strcmp(uri, LV2_UI__resize) == 0) | |||
return true; | |||