Eliminate the C FFI; Namespace lib API and DeviceManager
We decided to get rid of the C FFI for libs. It was becoming too intricate and complicated. It was becoming a technical burden and expanding into too much extra code. It's unfortunate, but we'll have to give up on getting out-of-tree hot-loadable libraries the easy way. It's possible to still do it with cross compilation or by keeping track of the libstdc++ version that the running harikoff binary was compiled against. Then we can ensure that our loadable lib code is linked against that same libstdc++ code and this should ensure ABI stability.
This commit is contained in:
@@ -8,6 +8,9 @@
|
|||||||
#include <opts.h>
|
#include <opts.h>
|
||||||
#include <deviceManager/deviceManager.h>
|
#include <deviceManager/deviceManager.h>
|
||||||
|
|
||||||
|
namespace hk {
|
||||||
|
namespace device {
|
||||||
|
|
||||||
std::vector<std::shared_ptr<InteroceptorDeviceSpec>>
|
std::vector<std::shared_ptr<InteroceptorDeviceSpec>>
|
||||||
DeviceManager::interoceptorDeviceSpecs;
|
DeviceManager::interoceptorDeviceSpecs;
|
||||||
std::vector<std::shared_ptr<ExtrospectorDeviceSpec>>
|
std::vector<std::shared_ptr<ExtrospectorDeviceSpec>>
|
||||||
@@ -20,12 +23,15 @@ const std::string DeviceManager::stringifyDeviceSpecs(void)
|
|||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
|
||||||
for (const auto& spec : DeviceManager::interoceptorDeviceSpecs) {
|
for (const auto& spec : DeviceManager::interoceptorDeviceSpecs) {
|
||||||
oss << "Interoceptor " << CSenseDeviceSpec(*spec);
|
oss << "Interoceptor " << spec->stringify();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& spec : DeviceManager::extrospectorDeviceSpecs) {
|
for (const auto& spec : DeviceManager::extrospectorDeviceSpecs) {
|
||||||
oss << "Extrospector " << CSenseDeviceSpec(*spec);
|
oss << "Extrospector " << spec->stringify();
|
||||||
}
|
}
|
||||||
|
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace device
|
||||||
|
} // namespace hk
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
#include "deviceSpecp.hh"
|
#include "deviceSpecp.hh"
|
||||||
#include "deviceSpecl.hh"
|
#include "deviceSpecl.hh"
|
||||||
|
|
||||||
|
namespace hk {
|
||||||
|
namespace device {
|
||||||
|
|
||||||
std::string DeviceManager::readDeviceFile(const std::string& filename)
|
std::string DeviceManager::readDeviceFile(const std::string& filename)
|
||||||
{
|
{
|
||||||
std::ifstream file(filename);
|
std::ifstream file(filename);
|
||||||
@@ -61,3 +64,6 @@ void DeviceManager::parseAllDeviceSpecs(void)
|
|||||||
"Check specs for errors");
|
"Check specs for errors");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace device
|
||||||
|
} // namespace hk
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ void yyerror(const char *message)
|
|||||||
%union {
|
%union {
|
||||||
char* str;
|
char* str;
|
||||||
char chr;
|
char chr;
|
||||||
SenseDeviceSpec* sensorSpec;
|
hk::device::SenseDeviceSpec* sensorSpec;
|
||||||
InteroceptorDeviceSpec* interoceptorSpec;
|
hk::device::InteroceptorDeviceSpec* interoceptorSpec;
|
||||||
ExtrospectorDeviceSpec* extrospectorSpec;
|
hk::device::ExtrospectorDeviceSpec* extrospectorSpec;
|
||||||
std::vector<std::string>* stringVector;
|
std::vector<std::string>* stringVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,12 +73,12 @@ sensor_spec:
|
|||||||
|
|
||||||
interoceptor_spec:
|
interoceptor_spec:
|
||||||
KEYWORD_SPECTYPE_INTEROSPECTOR PIPE spec_body {
|
KEYWORD_SPECTYPE_INTEROSPECTOR PIPE spec_body {
|
||||||
auto spec = std::make_shared<InteroceptorDeviceSpec>(
|
auto spec = std::make_shared<hk::device::InteroceptorDeviceSpec>(
|
||||||
*static_cast<InteroceptorDeviceSpec *>($3));
|
*static_cast<hk::device::InteroceptorDeviceSpec *>($3));
|
||||||
|
|
||||||
spec->sensorType = $1;
|
spec->sensorType = $1;
|
||||||
DeviceManager::interoceptorDeviceSpecs.push_back(spec);
|
hk::device::DeviceManager::interoceptorDeviceSpecs.push_back(spec);
|
||||||
DeviceManager::senseDeviceSpecs.push_back(spec);
|
hk::device::DeviceManager::senseDeviceSpecs.push_back(spec);
|
||||||
|
|
||||||
delete $3;
|
delete $3;
|
||||||
}
|
}
|
||||||
@@ -86,12 +86,12 @@ interoceptor_spec:
|
|||||||
|
|
||||||
extrospector_spec:
|
extrospector_spec:
|
||||||
KEYWORD_SPECTYPE_EXTROSPECTOR PIPE spec_body {
|
KEYWORD_SPECTYPE_EXTROSPECTOR PIPE spec_body {
|
||||||
auto spec = std::make_shared<ExtrospectorDeviceSpec>(
|
auto spec = std::make_shared<hk::device::ExtrospectorDeviceSpec>(
|
||||||
*static_cast<ExtrospectorDeviceSpec *>($3));
|
*static_cast<hk::device::ExtrospectorDeviceSpec *>($3));
|
||||||
|
|
||||||
spec->sensorType = $1;
|
spec->sensorType = $1;
|
||||||
DeviceManager::extrospectorDeviceSpecs.push_back(spec);
|
hk::device::DeviceManager::extrospectorDeviceSpecs.push_back(spec);
|
||||||
DeviceManager::senseDeviceSpecs.push_back(spec);
|
hk::device::DeviceManager::senseDeviceSpecs.push_back(spec);
|
||||||
|
|
||||||
delete $3;
|
delete $3;
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ extrospector_spec:
|
|||||||
|
|
||||||
spec_body:
|
spec_body:
|
||||||
STRING PIPE STRING LPAREN opt_params RPAREN PIPE STRING LPAREN opt_params RPAREN PIPE STRING {
|
STRING PIPE STRING LPAREN opt_params RPAREN PIPE STRING LPAREN opt_params RPAREN PIPE STRING {
|
||||||
$$ = new SenseDeviceSpec();
|
$$ = new hk::device::SenseDeviceSpec();
|
||||||
$$->sensorType = '\0';
|
$$->sensorType = '\0';
|
||||||
$$->implexor = std::string($1);
|
$$->implexor = std::string($1);
|
||||||
$$->api = std::string($3);
|
$$->api = std::string($3);
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <user/senseDeviceSpec.h>
|
#include <user/senseDeviceSpec.h>
|
||||||
|
|
||||||
|
namespace hk {
|
||||||
|
namespace device {
|
||||||
|
|
||||||
class DeviceManager
|
class DeviceManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -39,4 +42,7 @@ public:
|
|||||||
senseDeviceSpecs;
|
senseDeviceSpecs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace device
|
||||||
|
} // namespace hk
|
||||||
|
|
||||||
#endif // DEVICEMANAGER_H
|
#endif // DEVICEMANAGER_H
|
||||||
|
|||||||
@@ -11,59 +11,6 @@
|
|||||||
namespace hk {
|
namespace hk {
|
||||||
namespace sense_api {
|
namespace sense_api {
|
||||||
|
|
||||||
/* C++ version of the C struct above, which Harikoff uses to manage the
|
|
||||||
* lib and connect implexors to it.
|
|
||||||
*/
|
|
||||||
class SenseApiDesc
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class ExportedImplexorApiDesc
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ExportedImplexorApiDesc(const CExportedImplexorApiDesc& cDesc)
|
|
||||||
// The caller should sanity check before calling this constructor.
|
|
||||||
: name(cDesc.name)
|
|
||||||
{}
|
|
||||||
|
|
||||||
const std::string name;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
SenseApiDesc() = default;
|
|
||||||
SenseApiDesc(const CSenseApiDesc& cDesc)
|
|
||||||
// The caller should sanity check before calling this constructor.
|
|
||||||
: name(cDesc.name),
|
|
||||||
sal_mgmt_libOps(cDesc.sal_mgmt_libOps)
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < cDesc.numExportedImplexorApis; ++i)
|
|
||||||
{
|
|
||||||
if (!CExportedImplexorApiDesc_sanityCheck(
|
|
||||||
&cDesc.exportedImplexorApis[i]))
|
|
||||||
{
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Sanity check failed for exported implexor API descriptor");
|
|
||||||
}
|
|
||||||
|
|
||||||
exportedImplexorApis.push_back(
|
|
||||||
ExportedImplexorApiDesc(cDesc.exportedImplexorApis[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
// These are the implexors whose APIs this lib exports.
|
|
||||||
std::vector<ExportedImplexorApiDesc> exportedImplexorApis;
|
|
||||||
Csal_mgmt_libOps* sal_mgmt_libOps;
|
|
||||||
|
|
||||||
std::string stringify() const {
|
|
||||||
std::string result = "Name: " + name + "\n";
|
|
||||||
result += "Exported Implexor APIs:\n";
|
|
||||||
for (const auto& api : exportedImplexorApis) {
|
|
||||||
result += " - " + api.name + "\n";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SenseApiLib
|
class SenseApiLib
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -86,27 +33,16 @@ public:
|
|||||||
HK_GET_SENSE_API_DESC_FN_NAME(descFn)
|
HK_GET_SENSE_API_DESC_FN_NAME(descFn)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void setSenseApiDesc(const CSenseApiDesc* desc)
|
void setSenseApiDesc(const SenseApiDesc &desc)
|
||||||
{
|
{
|
||||||
if (!CSenseApiDesc_sanityCheck(desc) ||
|
if (!SenseApiDesc::sanityCheck(desc))
|
||||||
!Csal_mgmt_libOps_sanityCheck(desc->sal_mgmt_libOps))
|
|
||||||
{
|
{
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
std::string(__func__) + ": Sanity check failed for sense API "
|
std::string(__func__) + ": Sanity check failed for sense API "
|
||||||
"descriptor in library '" + libraryPath + "'");
|
"descriptor in library '" + libraryPath + "'");
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < desc->numExportedImplexorApis; ++i)
|
|
||||||
{
|
senseApiDesc = desc;
|
||||||
if (!CExportedImplexorApiDesc_sanityCheck(
|
|
||||||
&desc->exportedImplexorApis[i]))
|
|
||||||
{
|
|
||||||
throw std::runtime_error(
|
|
||||||
std::string(__func__) + ": Sanity check failed for "
|
|
||||||
"exported implexor API descriptor in library '"
|
|
||||||
+ libraryPath + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
new (&senseApiDesc) SenseApiDesc(*desc); // Placement new
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -119,7 +55,7 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Every sense API lib is required to provide a function that returns
|
* @brief Every sense API lib is required to provide a function that returns
|
||||||
* a CSenseApiDesc struct. This struct states which API the lib uses to
|
* a SenseApiDesc struct. This struct states which API the lib uses to
|
||||||
* connect Harikoff to the sense provider it supports.
|
* connect Harikoff to the sense provider it supports.
|
||||||
*
|
*
|
||||||
* This getter function should be visible to dlsym() so that Harikoff can
|
* This getter function should be visible to dlsym() so that Harikoff can
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ public:
|
|||||||
void finalizeAllSenseApiLibs(void);
|
void finalizeAllSenseApiLibs(void);
|
||||||
|
|
||||||
void attachAllSenseDevicesFromSpecs(void);
|
void attachAllSenseDevicesFromSpecs(void);
|
||||||
void attachSenseDevice(const SenseDeviceSpec& spec);
|
void attachSenseDevice(const device::SenseDeviceSpec& spec);
|
||||||
void detachSenseDevice(const SenseDeviceSpec& spec);
|
void detachSenseDevice(const device::SenseDeviceSpec& spec);
|
||||||
void detachAllSenseDevices(void);
|
void detachAllSenseDevices(void);
|
||||||
|
|
||||||
std::string stringifyLibs() const;
|
std::string stringifyLibs() const;
|
||||||
|
|||||||
@@ -38,20 +38,18 @@ static std::optional<std::string> findLibraryPath(
|
|||||||
|
|
||||||
std::cerr << std::string(__func__) + ": library '"
|
std::cerr << std::string(__func__) + ": library '"
|
||||||
+ libraryPath + "' isn't in search bespoke search paths: ";
|
+ libraryPath + "' isn't in search bespoke search paths: ";
|
||||||
for (const auto& path : searchPaths)
|
for (const auto& path : searchPaths) {
|
||||||
{
|
|
||||||
std::cerr << path << " ";
|
std::cerr << path << " ";
|
||||||
}
|
}
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << "Trying to load " + libraryPath + " from system default search "
|
std::cerr << "Trying to load " + libraryPath + " from system default "
|
||||||
"paths\n";
|
"search paths\n";
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
SenseApiLib& SenseApiManager::loadSenseApiLib(const std::string& libraryPath)
|
SenseApiLib& SenseApiManager::loadSenseApiLib(const std::string& libraryPath)
|
||||||
{
|
{
|
||||||
const CSenseApiDesc *libApiDesc;
|
|
||||||
std::optional<std::string> fullPath = findLibraryPath(libraryPath);
|
std::optional<std::string> fullPath = findLibraryPath(libraryPath);
|
||||||
std::string resolvedPath = fullPath.value_or(libraryPath);
|
std::string resolvedPath = fullPath.value_or(libraryPath);
|
||||||
|
|
||||||
@@ -90,14 +88,7 @@ SenseApiLib& SenseApiManager::loadSenseApiLib(const std::string& libraryPath)
|
|||||||
+ libraryPath + "'");
|
+ libraryPath + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
libApiDesc = func();
|
const SenseApiDesc &libApiDesc = func();
|
||||||
if (!libApiDesc)
|
|
||||||
{
|
|
||||||
throw std::runtime_error(
|
|
||||||
std::string(__func__) + ": getSenseApiDesc() returned NULL for "
|
|
||||||
"library '" + libraryPath + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lib = std::make_unique<SenseApiLib>(
|
auto lib = std::make_unique<SenseApiLib>(
|
||||||
libraryPath, dlopen_handle.release(), func);
|
libraryPath, dlopen_handle.release(), func);
|
||||||
lib->setSenseApiDesc(libApiDesc);
|
lib->setSenseApiDesc(libApiDesc);
|
||||||
@@ -173,24 +164,24 @@ std::string SenseApiManager::stringifyLibs() const
|
|||||||
|
|
||||||
void SenseApiManager::initializeSenseApiLib(SenseApiLib& lib)
|
void SenseApiManager::initializeSenseApiLib(SenseApiLib& lib)
|
||||||
{
|
{
|
||||||
if (!lib.senseApiDesc.sal_mgmt_libOps->initializeInd)
|
if (!lib.senseApiDesc.sal_mgmt_libOps.initializeInd)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
std::string(__func__) + ": initializeInd() is NULL for library '"
|
std::string(__func__) + ": initializeInd() is NULL for library '"
|
||||||
+ lib.libraryPath + "'");
|
+ lib.libraryPath + "'");
|
||||||
}
|
}
|
||||||
lib.senseApiDesc.sal_mgmt_libOps->initializeInd();
|
lib.senseApiDesc.sal_mgmt_libOps.initializeInd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SenseApiManager::finalizeSenseApiLib(SenseApiLib& lib)
|
void SenseApiManager::finalizeSenseApiLib(SenseApiLib& lib)
|
||||||
{
|
{
|
||||||
if (!lib.senseApiDesc.sal_mgmt_libOps->finalizeInd)
|
if (!lib.senseApiDesc.sal_mgmt_libOps.finalizeInd)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
std::string(__func__) + ": finalizeInd() is NULL for library '"
|
std::string(__func__) + ": finalizeInd() is NULL for library '"
|
||||||
+ lib.libraryPath + "'");
|
+ lib.libraryPath + "'");
|
||||||
}
|
}
|
||||||
lib.senseApiDesc.sal_mgmt_libOps->finalizeInd();
|
lib.senseApiDesc.sal_mgmt_libOps.finalizeInd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SenseApiManager::initializeAllSenseApiLibs(void)
|
void SenseApiManager::initializeAllSenseApiLibs(void)
|
||||||
@@ -207,7 +198,7 @@ void SenseApiManager::finalizeAllSenseApiLibs(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SenseApiManager::attachSenseDevice(const SenseDeviceSpec& spec)
|
void SenseApiManager::attachSenseDevice(const device::SenseDeviceSpec& spec)
|
||||||
{
|
{
|
||||||
auto libOpt = getSenseApiLibByApiName(spec.api);
|
auto libOpt = getSenseApiLibByApiName(spec.api);
|
||||||
if (!libOpt)
|
if (!libOpt)
|
||||||
@@ -217,17 +208,16 @@ void SenseApiManager::attachSenseDevice(const SenseDeviceSpec& spec)
|
|||||||
+ spec.api + "'");
|
+ spec.api + "'");
|
||||||
}
|
}
|
||||||
auto& lib = libOpt.value().get();
|
auto& lib = libOpt.value().get();
|
||||||
if (!lib.senseApiDesc.sal_mgmt_libOps->attachDeviceReq)
|
if (!lib.senseApiDesc.sal_mgmt_libOps.attachDeviceReq)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
std::string(__func__) + ": attachDeviceReq() is NULL for library '"
|
std::string(__func__) + ": attachDeviceReq() is NULL for library '"
|
||||||
+ lib.libraryPath + "'");
|
+ lib.libraryPath + "'");
|
||||||
}
|
}
|
||||||
CSenseDeviceSpec cSpec(spec);
|
lib.senseApiDesc.sal_mgmt_libOps.attachDeviceReq(&spec);
|
||||||
lib.senseApiDesc.sal_mgmt_libOps->attachDeviceReq(&cSpec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SenseApiManager::detachSenseDevice(const SenseDeviceSpec& spec)
|
void SenseApiManager::detachSenseDevice(const device::SenseDeviceSpec& spec)
|
||||||
{
|
{
|
||||||
auto libOpt = getSenseApiLibByApiName(spec.api);
|
auto libOpt = getSenseApiLibByApiName(spec.api);
|
||||||
if (!libOpt)
|
if (!libOpt)
|
||||||
@@ -237,26 +227,25 @@ void SenseApiManager::detachSenseDevice(const SenseDeviceSpec& spec)
|
|||||||
+ spec.api + "'");
|
+ spec.api + "'");
|
||||||
}
|
}
|
||||||
auto& lib = libOpt.value().get();
|
auto& lib = libOpt.value().get();
|
||||||
if (!lib.senseApiDesc.sal_mgmt_libOps->detachDeviceReq)
|
if (!lib.senseApiDesc.sal_mgmt_libOps.detachDeviceReq)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
std::string(__func__) + ": detachDeviceReq() is NULL for library '"
|
std::string(__func__) + ": detachDeviceReq() is NULL for library '"
|
||||||
+ lib.libraryPath + "'");
|
+ lib.libraryPath + "'");
|
||||||
}
|
}
|
||||||
CSenseDeviceSpec cSpec(spec);
|
lib.senseApiDesc.sal_mgmt_libOps.detachDeviceReq(&spec);
|
||||||
lib.senseApiDesc.sal_mgmt_libOps->detachDeviceReq(&cSpec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SenseApiManager::attachAllSenseDevicesFromSpecs(void)
|
void SenseApiManager::attachAllSenseDevicesFromSpecs(void)
|
||||||
{
|
{
|
||||||
for (const auto& spec : DeviceManager::senseDeviceSpecs) {
|
for (const auto& spec : device::DeviceManager::senseDeviceSpecs) {
|
||||||
attachSenseDevice(*spec);
|
attachSenseDevice(*spec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SenseApiManager::detachAllSenseDevices(void)
|
void SenseApiManager::detachAllSenseDevices(void)
|
||||||
{
|
{
|
||||||
for (const auto& spec : DeviceManager::senseDeviceSpecs) {
|
for (const auto& spec : device::DeviceManager::senseDeviceSpecs) {
|
||||||
detachSenseDevice(*spec);
|
detachSenseDevice(*spec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+75
-66
@@ -5,24 +5,18 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <user/senseDeviceSpec.h>
|
#include <user/senseDeviceSpec.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
namespace hk {
|
||||||
extern "C" {
|
namespace sense_api {
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Exported by all sense API Libraries to tell Harikoff what API the lib uses
|
/* Exported by all sense API Libraries to tell Harikoff what API the lib uses
|
||||||
* to connect to providers; and also to state which implexor APIs it exports.
|
* to connect to providers; and also to state which implexor APIs it exports.
|
||||||
*/
|
*/
|
||||||
struct CExportedImplexorApiDesc
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef int (sal_mho_initializeRdyFn)(void);
|
typedef int (sal_mho_initializeRdyFn)(void);
|
||||||
typedef int (sal_mho_finalizeRdyFn)(void);
|
typedef int (sal_mho_finalizeRdyFn)(void);
|
||||||
typedef int (sal_mho_attachDeviceAckFn)(const CSenseDeviceSpec *const desc);
|
typedef int (sal_mho_attachDeviceAckFn)(const device::SenseDeviceSpec *const desc);
|
||||||
typedef int (sal_mho_detachDeviceAckFn)(const CSenseDeviceSpec *const desc);
|
typedef int (sal_mho_detachDeviceAckFn)(const device::SenseDeviceSpec *const desc);
|
||||||
|
|
||||||
struct Csal_mgmt_hkOps
|
struct Sal_Mgmt_HkOps
|
||||||
{
|
{
|
||||||
// Lib calls this function to notify Harikoff that it's done initializing.
|
// Lib calls this function to notify Harikoff that it's done initializing.
|
||||||
sal_mho_initializeRdyFn *initializeRdy;
|
sal_mho_initializeRdyFn *initializeRdy;
|
||||||
@@ -36,10 +30,10 @@ struct Csal_mgmt_hkOps
|
|||||||
|
|
||||||
typedef int (sal_mlo_initializeIndFn)(void);
|
typedef int (sal_mlo_initializeIndFn)(void);
|
||||||
typedef int (sal_mlo_finalizeIndFn)(void);
|
typedef int (sal_mlo_finalizeIndFn)(void);
|
||||||
typedef int (sal_mlo_attachDeviceReqFn)(const CSenseDeviceSpec *const desc);
|
typedef int (sal_mlo_attachDeviceReqFn)(const device::SenseDeviceSpec *const desc);
|
||||||
typedef int (sal_mlo_detachDeviceReqFn)(const CSenseDeviceSpec *const desc);
|
typedef int (sal_mlo_detachDeviceReqFn)(const device::SenseDeviceSpec *const desc);
|
||||||
|
|
||||||
struct Csal_mgmt_libOps
|
struct Sal_Mgmt_LibOps
|
||||||
{
|
{
|
||||||
/* When Harikoff loads a sense API lib, it calls this function to initialize
|
/* When Harikoff loads a sense API lib, it calls this function to initialize
|
||||||
* the lib. When this returns, the lib should be ready to attach devices.
|
* the lib. When this returns, the lib should be ready to attach devices.
|
||||||
@@ -55,67 +49,82 @@ struct Csal_mgmt_libOps
|
|||||||
sal_mlo_attachDeviceReqFn *attachDeviceReq;
|
sal_mlo_attachDeviceReqFn *attachDeviceReq;
|
||||||
// When this returns, the device should be detached.
|
// When this returns, the device should be detached.
|
||||||
sal_mlo_detachDeviceReqFn *detachDeviceReq;
|
sal_mlo_detachDeviceReqFn *detachDeviceReq;
|
||||||
|
|
||||||
|
static bool sanityCheck(const Sal_Mgmt_LibOps &ops)
|
||||||
|
{
|
||||||
|
if (!ops.initializeInd || !ops.finalizeInd
|
||||||
|
|| !ops.attachDeviceReq || !ops.detachDeviceReq)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CSenseApiDesc
|
/* C++ version of the C struct above, which Harikoff uses to manage the
|
||||||
|
* lib and connect implexors to it.
|
||||||
|
*/
|
||||||
|
class SenseApiDesc
|
||||||
{
|
{
|
||||||
/* Shortname that identifies the API used by this lib to talk to the sense
|
public:
|
||||||
* provider.
|
class ExportedImplexorApiDesc
|
||||||
*/
|
{
|
||||||
const char *name;
|
public:
|
||||||
/* These are the implexors whose APIs this lib exports.
|
ExportedImplexorApiDesc(const std::string name)
|
||||||
*/
|
// The caller should sanity check before calling this constructor.
|
||||||
uint32_t numExportedImplexorApis;
|
: name(name)
|
||||||
CExportedImplexorApiDesc *exportedImplexorApis;
|
{}
|
||||||
/* Sub-API for managing the lib. Library role within the API.
|
|
||||||
*/
|
static bool sanityCheck(const ExportedImplexorApiDesc &desc)
|
||||||
Csal_mgmt_libOps *sal_mgmt_libOps;
|
{
|
||||||
|
if (desc.name.empty()) { return false; }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
SenseApiDesc() = default;
|
||||||
|
|
||||||
|
std::string stringify() const
|
||||||
|
{
|
||||||
|
std::string result = "Name: " + name + "\n";
|
||||||
|
result += "Exported Implexor APIs:\n";
|
||||||
|
for (const auto& api : exportedImplexorApis) {
|
||||||
|
result += " - " + api.name + "\n";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool sanityCheck(const SenseApiDesc &desc)
|
||||||
|
{
|
||||||
|
if (desc.name.empty() || desc.exportedImplexorApis.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& api : desc.exportedImplexorApis) {
|
||||||
|
if (!ExportedImplexorApiDesc::sanityCheck(api)) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return Sal_Mgmt_LibOps::sanityCheck(desc.sal_mgmt_libOps);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
// These are the implexors whose APIs this lib exports.
|
||||||
|
std::vector<ExportedImplexorApiDesc> exportedImplexorApis;
|
||||||
|
Sal_Mgmt_LibOps sal_mgmt_libOps;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool CSenseApiDesc_sanityCheck(const CSenseApiDesc *desc)
|
|
||||||
{
|
|
||||||
(void)CSenseApiDesc_sanityCheck;
|
|
||||||
if (!desc || !desc->name || desc->numExportedImplexorApis < 1
|
|
||||||
||!desc->exportedImplexorApis || !desc->sal_mgmt_libOps)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CExportedImplexorApiDesc_sanityCheck(
|
|
||||||
const CExportedImplexorApiDesc *desc)
|
|
||||||
{
|
|
||||||
(void)CExportedImplexorApiDesc_sanityCheck;
|
|
||||||
if (!desc || !desc->name)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool Csal_mgmt_libOps_sanityCheck(const Csal_mgmt_libOps *ops)
|
|
||||||
{
|
|
||||||
(void)Csal_mgmt_libOps_sanityCheck;
|
|
||||||
if (!ops || !ops->initializeInd || !ops->finalizeInd
|
|
||||||
|| !ops->attachDeviceReq || !ops->detachDeviceReq)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define HK_GET_SENSE_API_DESC_FN_NAME getSenseApiDesc
|
#define HK_GET_SENSE_API_DESC_FN_NAME getSenseApiDesc
|
||||||
#define HK_GET_SENSE_API_DESC_FN_NAME_STR \
|
#define HK_GET_SENSE_API_DESC_FN_NAME_STR \
|
||||||
HK_QUOTE(HK_GET_SENSE_API_DESC_FN_NAME)
|
HK_QUOTE(HK_GET_SENSE_API_DESC_FN_NAME)
|
||||||
|
|
||||||
typedef const CSenseApiDesc *(getSenseApiDescFn)(void);
|
typedef const SenseApiDesc &(getSenseApiDescFn)(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
} // namespace sense_api
|
||||||
}
|
} // namespace hk
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __USER_SENSE_API_LIB_H__
|
#endif // __USER_SENSE_API_LIB_H__
|
||||||
|
|||||||
+35
-155
@@ -1,19 +1,32 @@
|
|||||||
#ifndef SENSORDEVICESPEC_H
|
#ifndef SENSORDEVICESPEC_H
|
||||||
#define SENSORDEVICESPEC_H
|
#define SENSORDEVICESPEC_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
namespace hk {
|
||||||
struct SenseDeviceSpec
|
namespace device {
|
||||||
|
|
||||||
|
class SenseDeviceSpec
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
friend std::ostream& operator<<(
|
||||||
|
std::ostream& os, const SenseDeviceSpec& spec)
|
||||||
|
{
|
||||||
|
os << spec.stringify();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const SenseDeviceSpec& other) const
|
||||||
|
{
|
||||||
|
return sensorType == other.sensorType &&
|
||||||
|
provider == other.provider &&
|
||||||
|
deviceSelector == other.deviceSelector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
char sensorType;
|
char sensorType;
|
||||||
std::string implexor;
|
std::string implexor;
|
||||||
std::string api;
|
std::string api;
|
||||||
@@ -22,168 +35,35 @@ struct SenseDeviceSpec
|
|||||||
std::vector<std::string> providerParams;
|
std::vector<std::string> providerParams;
|
||||||
std::string deviceSelector;
|
std::string deviceSelector;
|
||||||
|
|
||||||
friend std::ostream& operator<<(
|
|
||||||
std::ostream& os, const SenseDeviceSpec& spec);
|
|
||||||
|
|
||||||
bool operator==(const SenseDeviceSpec& other) const
|
|
||||||
{
|
|
||||||
return sensorType == other.sensorType &&
|
|
||||||
provider == other.provider &&
|
|
||||||
deviceSelector == other.deviceSelector;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InteroceptorDeviceSpec : public SenseDeviceSpec
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ExtrospectorDeviceSpec : public SenseDeviceSpec
|
|
||||||
{
|
|
||||||
};
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct CSenseDeviceSpec
|
|
||||||
{
|
|
||||||
#ifdef __cplusplus
|
|
||||||
CSenseDeviceSpec(const SenseDeviceSpec& spec)
|
|
||||||
: sensorType(spec.sensorType),
|
|
||||||
implexor(strdup(spec.implexor.c_str())),
|
|
||||||
api(strdup(spec.api.c_str())),
|
|
||||||
provider(strdup(spec.provider.c_str())),
|
|
||||||
deviceSelector(strdup(spec.deviceSelector.c_str()))
|
|
||||||
{
|
|
||||||
apiParams = new char*[spec.apiParams.size() + 1];
|
|
||||||
for (size_t i = 0; i < spec.apiParams.size(); ++i)
|
|
||||||
{
|
|
||||||
apiParams[i] = strdup(spec.apiParams[i].c_str());
|
|
||||||
}
|
|
||||||
apiParams[spec.apiParams.size()] = nullptr;
|
|
||||||
|
|
||||||
providerParams = new char*[spec.providerParams.size() + 1];
|
|
||||||
for (size_t i = 0; i < spec.providerParams.size(); ++i)
|
|
||||||
{
|
|
||||||
providerParams[i] = strdup(spec.providerParams[i].c_str());
|
|
||||||
}
|
|
||||||
providerParams[spec.providerParams.size()] = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSenseDeviceSpec(const CSenseDeviceSpec& other)
|
|
||||||
: sensorType(other.sensorType),
|
|
||||||
implexor(strdup(other.implexor)),
|
|
||||||
api(strdup(other.api)),
|
|
||||||
provider(strdup(other.provider)),
|
|
||||||
deviceSelector(strdup(other.deviceSelector))
|
|
||||||
{
|
|
||||||
if (other.apiParams) {
|
|
||||||
size_t apiParamsSize = 0;
|
|
||||||
while (other.apiParams[apiParamsSize] != nullptr) {
|
|
||||||
++apiParamsSize;
|
|
||||||
}
|
|
||||||
apiParams = new char*[apiParamsSize + 1];
|
|
||||||
for (size_t i = 0; i < apiParamsSize; ++i) {
|
|
||||||
apiParams[i] = strdup(other.apiParams[i]);
|
|
||||||
}
|
|
||||||
apiParams[apiParamsSize] = nullptr;
|
|
||||||
} else {
|
|
||||||
apiParams = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other.providerParams) {
|
|
||||||
size_t providerParamsSize = 0;
|
|
||||||
while (other.providerParams[providerParamsSize] != nullptr) {
|
|
||||||
++providerParamsSize;
|
|
||||||
}
|
|
||||||
providerParams = new char*[providerParamsSize + 1];
|
|
||||||
for (size_t i = 0; i < providerParamsSize; ++i) {
|
|
||||||
providerParams[i] = strdup(other.providerParams[i]);
|
|
||||||
}
|
|
||||||
providerParams[providerParamsSize] = nullptr;
|
|
||||||
} else {
|
|
||||||
providerParams = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~CSenseDeviceSpec(void)
|
|
||||||
{
|
|
||||||
free(implexor);
|
|
||||||
free(api);
|
|
||||||
free(provider);
|
|
||||||
free(deviceSelector);
|
|
||||||
|
|
||||||
if (apiParams)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; apiParams[i] != nullptr; ++i) {
|
|
||||||
free(apiParams[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] apiParams;
|
|
||||||
|
|
||||||
if (providerParams)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; providerParams[i] != nullptr; ++i) {
|
|
||||||
free(providerParams[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] providerParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string stringify() const
|
std::string stringify() const
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "Device: " << sensorType << ", Implexor: "
|
os << "Device: " << sensorType << ", Implexor: "
|
||||||
<< (implexor ? implexor : "NULL") << ", API: "
|
<< implexor << ", API: " << api << ", API Params: (";
|
||||||
<< (api ? api : "NULL") << ", API Params: (";
|
for (const auto& param : apiParams)
|
||||||
if (apiParams)
|
|
||||||
{
|
{
|
||||||
for (size_t i = 0; apiParams[i] != nullptr; ++i)
|
os << param << " ";
|
||||||
{
|
|
||||||
os << apiParams[i] << (apiParams[i + 1] == nullptr ? "" : " ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
os << "), Provider: " << (provider ? provider : "NULL")
|
os << "), Provider: " << provider << ", Provider Params: (";
|
||||||
<< ", Provider Params: (";
|
for (const auto& param : providerParams)
|
||||||
if (providerParams)
|
|
||||||
{
|
{
|
||||||
for (size_t i = 0; providerParams[i] != nullptr; ++i)
|
os << param << " ";
|
||||||
{
|
|
||||||
os << providerParams[i] << (providerParams[i + 1] == nullptr ? "" : " ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
os << "), Device Selector: "
|
os << "), Device Selector: " << deviceSelector << std::endl;
|
||||||
<< (deviceSelector ? deviceSelector : "NULL") << std::endl;
|
|
||||||
|
|
||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const CSenseDeviceSpec& other) const
|
|
||||||
{
|
|
||||||
return sensorType == other.sensorType &&
|
|
||||||
strcmp(provider, other.provider) == 0 &&
|
|
||||||
strcmp(deviceSelector, other.deviceSelector) == 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char sensorType;
|
|
||||||
char *implexor;
|
|
||||||
char *api;
|
|
||||||
char **apiParams;
|
|
||||||
char *provider;
|
|
||||||
char **providerParams;
|
|
||||||
char *deviceSelector;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& os, const CSenseDeviceSpec& spec)
|
class InteroceptorDeviceSpec : public SenseDeviceSpec
|
||||||
{
|
{
|
||||||
os << spec.stringify();
|
};
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
class ExtrospectorDeviceSpec : public SenseDeviceSpec
|
||||||
}
|
{
|
||||||
#endif
|
};
|
||||||
|
|
||||||
|
} // namespace device
|
||||||
|
} // namespace hk
|
||||||
|
|
||||||
#endif // SENSORDEVICESPEC_H
|
#endif // SENSORDEVICESPEC_H
|
||||||
|
|||||||
@@ -86,9 +86,9 @@ static int initializeHarikoff(int argc, char **argv, char **envp)
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceManager::getInstance().collateAllDeviceSpecs();
|
device::DeviceManager::getInstance().collateAllDeviceSpecs();
|
||||||
DeviceManager::getInstance().parseAllDeviceSpecs();
|
device::DeviceManager::getInstance().parseAllDeviceSpecs();
|
||||||
std::cout << DeviceManager::stringifyDeviceSpecs() << std::endl;
|
std::cout << device::DeviceManager::stringifyDeviceSpecs() << std::endl;
|
||||||
sense_api::SenseApiManager::getInstance().loadAllSenseApiLibsFromOptions();
|
sense_api::SenseApiManager::getInstance().loadAllSenseApiLibsFromOptions();
|
||||||
std::cout << sense_api::SenseApiManager::getInstance().stringifyLibs()
|
std::cout << sense_api::SenseApiManager::getInstance().stringifyLibs()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|||||||
@@ -3,23 +3,25 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <user/senseDeviceSpec.h>
|
||||||
|
#include <user/senseApiDesc.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include "xcbXorg.h"
|
#include "xcbXorg.h"
|
||||||
|
|
||||||
class AttachedDevice {
|
class AttachedDevice {
|
||||||
public:
|
public:
|
||||||
AttachedDevice(const CSenseDeviceSpec &spec) : deviceSpec(spec) {}
|
AttachedDevice(const hk::device::SenseDeviceSpec &spec)
|
||||||
|
: deviceSpec(spec)
|
||||||
|
{}
|
||||||
|
|
||||||
const CSenseDeviceSpec& getSpec() const {
|
const hk::device::SenseDeviceSpec& getSpec() const {
|
||||||
return deviceSpec;
|
return deviceSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CSenseDeviceSpec deviceSpec;
|
hk::device::SenseDeviceSpec deviceSpec;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<AttachedDevice> attachedDevices;
|
|
||||||
|
|
||||||
struct XcbConnectionInfo {
|
struct XcbConnectionInfo {
|
||||||
std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> connection;
|
std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> connection;
|
||||||
int screenNumber;
|
int screenNumber;
|
||||||
@@ -29,44 +31,33 @@ struct XcbConnectionInfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static XcbConnectionInfo xcbConn;
|
static XcbConnectionInfo xcbConn;
|
||||||
|
static std::vector<AttachedDevice> attachedDevices;
|
||||||
|
|
||||||
static CExportedImplexorApiDesc xcbXorgExportedImplexorApis[] =
|
static hk::sense_api::sal_mlo_initializeIndFn xcbXorg_initializeInd;
|
||||||
|
static hk::sense_api::sal_mlo_finalizeIndFn xcbXorg_finalizeInd;
|
||||||
|
static hk::sense_api::sal_mlo_attachDeviceReqFn xcbXorg_attachDeviceReq;
|
||||||
|
static hk::sense_api::sal_mlo_detachDeviceReqFn xcbXorg_detachDeviceReq;
|
||||||
|
|
||||||
|
static hk::sense_api::SenseApiDesc xcbXorgApiDesc =
|
||||||
{
|
{
|
||||||
{
|
.name = "xcb-xorg",
|
||||||
.name = "video-implexor"
|
.exportedImplexorApis = { { "video-implexor" } },
|
||||||
|
.sal_mgmt_libOps = {
|
||||||
|
.initializeInd = xcbXorg_initializeInd,
|
||||||
|
.finalizeInd = xcbXorg_finalizeInd,
|
||||||
|
.attachDeviceReq = xcbXorg_attachDeviceReq,
|
||||||
|
.detachDeviceReq = xcbXorg_detachDeviceReq
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static sal_mlo_initializeIndFn xcbXorg_initializeInd;
|
extern HK_UNMANGLED hk::sense_api::getSenseApiDescFn
|
||||||
static sal_mlo_finalizeIndFn xcbXorg_finalizeInd;
|
HK_GET_SENSE_API_DESC_FN_NAME;
|
||||||
static sal_mlo_attachDeviceReqFn xcbXorg_attachDeviceReq;
|
|
||||||
static sal_mlo_detachDeviceReqFn xcbXorg_detachDeviceReq;
|
|
||||||
|
|
||||||
static Csal_mgmt_libOps xcbXorgMgmtLibOps =
|
const hk::sense_api::SenseApiDesc &HK_GET_SENSE_API_DESC_FN_NAME(void)
|
||||||
{
|
{
|
||||||
.initializeInd = xcbXorg_initializeInd,
|
return xcbXorgApiDesc;
|
||||||
.finalizeInd = xcbXorg_finalizeInd,
|
|
||||||
.attachDeviceReq = xcbXorg_attachDeviceReq,
|
|
||||||
.detachDeviceReq = xcbXorg_detachDeviceReq
|
|
||||||
};
|
|
||||||
|
|
||||||
static CSenseApiDesc xcbXorgApiDesc =
|
|
||||||
{
|
|
||||||
.name = "xcb-xorg",
|
|
||||||
.numExportedImplexorApis = sizeof(xcbXorgExportedImplexorApis) /
|
|
||||||
sizeof(*xcbXorgExportedImplexorApis),
|
|
||||||
.exportedImplexorApis = xcbXorgExportedImplexorApis,
|
|
||||||
.sal_mgmt_libOps = &xcbXorgMgmtLibOps
|
|
||||||
};
|
|
||||||
|
|
||||||
extern HK_UNMANGLED getSenseApiDescFn HK_GET_SENSE_API_DESC_FN_NAME;
|
|
||||||
|
|
||||||
const CSenseApiDesc *HK_GET_SENSE_API_DESC_FN_NAME(void)
|
|
||||||
{
|
|
||||||
return &xcbXorgApiDesc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static sal_mlo_initializeIndFn xcbXorg_initializeInd;
|
|
||||||
int xcbXorg_initializeInd(void)
|
int xcbXorg_initializeInd(void)
|
||||||
{
|
{
|
||||||
xcbConn.connection.reset(
|
xcbConn.connection.reset(
|
||||||
@@ -83,7 +74,6 @@ int xcbXorg_initializeInd(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sal_mlo_finalizeIndFn xcbXorg_finalizeInd;
|
|
||||||
int xcbXorg_finalizeInd(void)
|
int xcbXorg_finalizeInd(void)
|
||||||
{
|
{
|
||||||
if (!xcbConn.connection) {
|
if (!xcbConn.connection) {
|
||||||
@@ -94,22 +84,20 @@ int xcbXorg_finalizeInd(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sal_mlo_attachDeviceReqFn xcbXorg_attachDeviceReq;
|
int xcbXorg_attachDeviceReq(const hk::device::SenseDeviceSpec *const desc)
|
||||||
int xcbXorg_attachDeviceReq(const CSenseDeviceSpec *const desc)
|
|
||||||
{
|
{
|
||||||
attachedDevices.emplace_back(*desc);
|
attachedDevices.emplace_back(*desc);
|
||||||
|
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
for (const auto& device : attachedDevices) {
|
for (const auto& device : attachedDevices) {
|
||||||
os << device.getSpec();
|
os << device.getSpec().stringify();
|
||||||
}
|
}
|
||||||
std::cout << __func__ << ": >>>> Attaching device spec: " << *desc << "\n"
|
std::cout << __func__ << ": >>>> Attaching device spec: " << desc->stringify() << "\n"
|
||||||
<< " >>>> Current attached devices:\n" << os.str();
|
<< " >>>> Current attached devices:\n" << os.str();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sal_mlo_detachDeviceReqFn xcbXorg_detachDeviceReq;
|
int xcbXorg_detachDeviceReq(const hk::device::SenseDeviceSpec *const spec)
|
||||||
int xcbXorg_detachDeviceReq(const CSenseDeviceSpec *const spec)
|
|
||||||
{
|
{
|
||||||
auto it = std::remove_if(attachedDevices.begin(), attachedDevices.end(),
|
auto it = std::remove_if(attachedDevices.begin(), attachedDevices.end(),
|
||||||
[spec](const AttachedDevice &device) {
|
[spec](const AttachedDevice &device) {
|
||||||
|
|||||||
Reference in New Issue
Block a user