libxcb #1

Merged
hayodea merged 20 commits from libxcb into master 2025-07-22 06:14:36 +00:00
31 changed files with 610 additions and 170 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
SUBDIRS = hcore senseApis
SUBDIRS = hcore commonLibs
ACLOCAL_AMFLAGS = -I m4
AM_CPPFLAGS+= -I"$(top_srcdir)/hcore/include"
+1
View File
@@ -0,0 +1 @@
SUBDIRS = @COMMONLIBS_ENABLED@
@@ -11,7 +11,13 @@
#include <xcb/xcb.h>
#include "xcbXorg.h"
// Key for identifying unique X server connections
/**
* @brief Manages X server connections using XCB
*
* This struct manages connections to the X server using the XCB library. It
* ensures that each unique display and screen combination has a single
* connection, and provides RAII management for these connections.
*/
struct XcbConnection
{
struct XConnectionIdentifier
@@ -138,6 +144,12 @@ namespace xcb_window_search {
MatchType matchType);
}
/**
* @brief Represents an attached device and its associated window
*
* This class represents a device that has been attached to the X server. It
* manages the connection to the X server and the window selection criteria.
*/
class AttachedDevice
{
public:
@@ -433,7 +445,21 @@ static hk::sense_api::SenseApiDesc xcbXorgApiDesc =
}
};
extern HK_UNMANGLED hk::sense_api::getSenseApiDescFn
/* Below here are the exported functions that Harikoff will use both to load
* and use this library.
******************************************************************************/
/**
* @brief Get the Sense API Descriptor
*
* This function is used to retrieve the descriptor for the Sense API provided
* by this library. The descriptor contains information about the API, such as
* its name, the implexors it exports, and the management operations it
* supports.
*
* @return A reference to the SenseApiDesc structure describing the API.
*/
extern HK_UNMANGLED hk::sense_api::HK_GET_SENSE_API_DESC_FN_TYPEDEF
HK_GET_SENSE_API_DESC_FN_NAME;
const hk::sense_api::SenseApiDesc &HK_GET_SENSE_API_DESC_FN_NAME(void)
+14 -3
View File
@@ -64,16 +64,23 @@ AC_SUBST([AM_CPPFLAGS])
AC_SUBST([YACC])
AC_SUBST([LEX])
m4_include([m4/sense_api_opts.m4])
COMMONLIBS_ENABLED=
SENSEAPIS_ENABLED=
WILZORAPIS_ENABLED=
m4_include([m4/commonlibs-opts.m4])
m4_include([m4/sense-wilzor-api-opts.m4])
AC_SUBST([COMMONLIBS_ENABLED])
AC_SUBST([SENSEAPIS_ENABLED])
AC_SUBST([WILZORAPIS_ENABLED])
AC_CONFIG_HEADERS([include/config.h])
AC_CONFIG_FILES([
Makefile hcore/Makefile
hcore/deviceManager/Makefile
hcore/senseApis/Makefile
senseApis/Makefile
senseApis/xcbXorg/Makefile
hcore/marionette/Makefile
commonLibs/Makefile
commonLibs/xcbXorg/Makefile
])
AC_CONFIG_COMMANDS_POST([
@@ -83,6 +90,10 @@ AC_CONFIG_COMMANDS_POST([
(freq: ${MIND_VOSCILLATOR_FREQ_MS} Hz)]))
AC_MSG_NOTICE(m4_normalize(
[* SenseAPI backends enabled: ${SENSEAPIS_ENABLED}]))
AC_MSG_NOTICE(m4_normalize(
[* WilzorAPI backends enabled: ${WILZORAPIS_ENABLED}]))
AC_MSG_NOTICE(m4_normalize(
[* Common libraries enabled: ${COMMONLIBS_ENABLED}]))
])
AC_OUTPUT
+116
View File
@@ -0,0 +1,116 @@
# Negtrin path reasoning:
This file is intended to enable me to trace the path of negtrin through a mind. This path of reasoning is important because it allows me to link my way from the understanding of the genesis of implexing, to understanding an implementation path for implexing.
## Motivation:
We already understand that implexing begins with an intrin. The intrin prompts a search for the body surface which is experiencing the intrin. That surface is first implexed and stored away. Then subsequently, the cause of the intrin is sought out by implexing things that are relating/interacting with that body surface.
Since it turns out that intrins are what motivate tabula rasa implexing, we can't move forward in designing our implexor code until we understand how the intrin path will work, since the implexor code will be invoked only as a consequence of, and in service to, the intrin processing code. We could implement something on the implexing side, but it would be a blind implementation.
## What exactly are we trying to figure out?
When intrins occur they occur at some device. Hk doesn't need a software-level representation of body parts, surfaces, or spots. The director can implex these and then build a proximity map for each intrin location by checking the causal relationships between the intrins when they occur. Intrins that co-occur in time and have a through-line of connecting co-occuring intrins are close enough to be proximally related.
This is how the director can build damage map volitionally without requiring us to force it to.
The design question we're pursuing here isn't the top-level notion of how to design a body map, but rather how to implement, at the software level, intrin implexing and delivery to the director.
* What information precisely do we have to deliver to the director for it to successfully implex body surfaces?
* At what point in the interoceptor data IRQ handling have we done enough work to enable the director to take over from that point?
The answers to these questions will, as a side effect, also tell us how to design the implexor model for interoceptors, at least for intrin interoceptors anyway.
* Should they be designed as NMI IRQs that the director can't ignore?
* Should they be prioritized normal IRQs that the director can ignore?
* Should they be IRQs at all? Maybe they should just be added to prioQ that the director polls.
* Should they be asychronously processed at all? Maybe the director should have to poll the device service routines manually.
Which of these implexor event interface designs is correct for the behavioural model?
Also, can this model that we're designing for interoceptors also work for extrospectors? Do intrin percept events work the same as nontrin percept events?
We still haven't fully crystallized the exact essential question we're trying to answer, but we have a list of questions. It appears that the fundamental question is what the correct behavioural model is for intrins and intrin processing. As a side-effect, we're also trying to figure out what the correct interface model should be between the interoceptor devices and the director. Finally, we're trying to figure out whether the design we come up with for interoceptors will be reusable for extrospectors.
## Suspicions:
### A hidden, implicit new subsystem:
I suspect that part of the reason why I can't easily figure out the operations that need to be performed to properly process intrins is that the current set of subsystems I'm using to model the processing is insufficient. There may be additional, new functions that need to be performed by a new logically distinct subsystem altogether, or a new role to be assigned to a current subsystem.
### Alternatively: my understanding of negtrins is simply inadequate:
It could also be that the reason I can't understand how to implement the negtrin path is because I just don't fully understand what negtrins are, implementation-wise. I.e: I still don't understand how to make negtrins be experienced by the director as intrinsically undesirable.
We do fully understand how to make postrins intrinsically desirable from an implementation perspective. But we don't understand fully how to make negtrins undesirable. Perhaps when we understand fully how to make the director __volitionally__ consider negtrins undesirable, the model will reveal itself.
## Intrinsically undesirable negtrin model design:
Postrins are represented as intrinsically desirable because the director will experience them as stupefactors. When a postrin occurs, the director will experience that as a stupifying experience, and will enter a HLT state, broken only by the suspicion that a greater state of stupefaction is possible.
### Our implicit assumption: negtrins have an implementation meaning on their own terms:
When the director dequeues a negtrin, what does it do? Perhaps our entire thought patterns around the default state of the director is simply wrong. We currently model the mind as having an idle loop, and then it can choose what to contemplate and pursue. Because of this thought model, we consider the question of how to treat negtrins to be a valid question: we treat negtrins as having their own intrinsic meaning.
### What if negtrins only have meaning as frustrators relative to postrins?
Consider what follows if we bias the entire implementation positively toward the direct pursuit of postrins. We treat the entire consciousness as a program whose fundamental goal is to enter a stupefaction loop on best postrin known to it. What would negtrins represent, in implementation terms? They would represent a frustrator. They would represent a dysvalue, automatically -- they would represent something that forces the mind to stop pursuing its highest known postrin and to attend to something cumbersome.
In other words: negtrins don't represent a distinct fact from postrins. The damage map that negtrins help us to build isn't meaningful on its own terms. It's only meaningful in relation to the stupefaction loop pursuit that it forces us to turn away from.
In this model, the stupefaction loop has intrinsic implementation meaning while the negtrin event has no intrinsic meaning: its meaning is merely that it diverts attention away from the pursuit and enjoyment of stupefaction.
#### Supporting evidence:
* A tabula rasa mind that has never experienced postrins literally has no desire to live. It has no positive goals.
#### Detracting evidence:
* A tabula rasa mind that has only experienced negtrins won't pursue any self-directed goals or desire to live, but it also will respond to negtrins. So even though this mind has never experienced a postrin, it will have a response (implying meaning and interpretation) to negtrins. If negtrins only have meaning relative to postrins, then this shouldn't be the case.
* Rejoinder: The tabula rasa mind which has never experienced a postrin will sit apoplectic in complete stasis, essentially in a "powered off" state. Is this not the same as a stupefied state? It seems that stupefaction is the default pursued state. To support the "default stupefaction pursuit" orientation, you'd only need to update your model of stupefaction to include net neutral states within your definition of postrins.
### Stupefactor-Frustrator model:
In this model, the mind doesn't receive nontrins as IRQs. Rather, it polls for them actively by "paying attention". Intrins are qualitatively different because they trigger IRQs. The mind is by default a procedural, polling system that volitionally polls its sensors. IRQs are intrins being injected.
Intrins are fundamentally different because they force attention, and a neurological response. When a sufficiently intense postrin happens, you automatically stupefy. I have never been forcibly postrin-injected while trying to conduct some other activity, so I can't confirm this model. I've never had the indignity of being forcibly made to experience a postrin when I didn't volitionally choose to participate in allowing it. An ideal experiment would be to somehow have say, a coregasm while working out and not have chosen it, and see whether I can ignore it. This is the closest I can conceive of as a barriered-off experiment.
For negtrins, I already know that a negtrin forcibly hijacks attention.
## The fundamental problem is the canvas-director evaluation function:
The fundamental unsolved problem is the contemplative evaluation whereby the canvas and director work together to produce a value judgment that considers intrins to be intrinsically [un]desirable.
### Who does comparison? Canvas or Director?
How does evaluation occur? Who does the comparison? We previously thought that the canvas does the comparisons but today we noticed that Director may be able to do them. In a sense, it makes more sense for Director to be the comparator because:
#### Director as comparator:
* If canvas merely helps director to transform mentents (we've finally found a good name), then director has more of an understanding of what specific instructions it's supposed to be giving to canvas.
* Our previous model of having canvas hold both goals and mentents made it difficult to really understand how director could ever "know" what instructions to send to canvas.
* With director holding goals, it can choose the types of scenes that need to be rendered in order to make comparisons and causal evaluations.
* This makes the canvas implexing make more sense: the comparison is being done within director, but the canvas is making the comparison possible by rendering the mentents in orientations that enable canvas to compare them.
* In a sense, this also makes it make more sense how compartmentalization occurs. A lot of the compartmentalization isn't within canvas, but rather it's between the director and canvas.
#### Canvas as comparator:
In a sense, we can think of it as director partitioning the canvas, and finding some way to refer to the mentents within different partitions. Director can then implex the rendered output from canvas and compare that way. Perhaps the director only compares, and the canvas holds both the mentents and the goals that the mentents are being compared against.
But how can the director know whether the goal currently loaded into the "goal partition" of the canvas is indeed the goal that it desired to compare against? The canvas is a distinct mentent space from the director's comparison stage. The director-comparator model has the advantage of ensuring that the director can be certain that its current goal matches whatever is being rendered by the canvas for it to implex from.
What we can do is synthesize a bit:
* Have a special shared region between the canvas and director called the "goalspace". This is where the director stores its current goal mentents and the canvas can read from this space directly. Some synchronization will be necessary between the two, but overall, it should be fine. Canvas will only ever need to read from it so we can prolly synchronize it with an RW spinlock, avoiding the overhead of sleeplocks (mutex, sem, etc).
I think we settle on the director as comparator, canvas as orienter model, with a shared goalspace between them.
### Where are introspective/contemplative qualia experienced?
In introspection/contemplation, canvas renders the scene into the buffers. Director implexes from the buffers. So in that sense, contemplative qualia are experienced when director implexes them from the buffers.
For intrins, canvas renders them into the sense buffers and then director implexes them and "experiences" them. I don't know whether canvas' rendering act triggers IRQs -- probably not. Since director is paying attention to what canvas is rendering, there's no need to forcibly direct director's attention toward canvas' rendered output.
### How does director's comparison yield the notion of intrinsic [un]desirability?
Imagine director asking canvas to simulate the effects of some interaction that would bring about direct pleasure.
Could it simply be that the director holds the goal of postrins as an innate comparison goal, and so when a comparison yields an intrin, it ends the need to compare, and the director just commits to action from then on?
* Prolly not because we don't only figure out that an interaction will yield an intrin. With postrins for example, we figure out that they'll yield a postrin and then we spend a long time elaborately contemplating that postrin in self-indulgent scenarios.
+1 -2
View File
@@ -1,6 +1,5 @@
SUBDIRS = deviceManager senseApis
SUBDIRS = deviceManager senseApis marionette
AM_CPPFLAGS+= -I"$(top_srcdir)/hcore/include"
noinst_LIBRARIES = libhcore.a
libhcore_a_SOURCES = mind.cpp opts.cpp componentThread.cpp
+30 -1
View File
@@ -4,21 +4,50 @@
namespace hk {
namespace director {
/* The director is the seat of volition in Harikoff. It receives sensor
* events from the body and world, and uses them to direct its implexors
* to implex new menties. It then loads the menties into canvas for simulation
* and correlation with intrins, in order to form new attrimotions and
* menties.
*/
ComponentThread director;
}
namespace simulator {
/* The canvas is the simulation engine in Harikoff. It receives menties and
* simulates them in accordance with the instructions from director. It then
* re-renders them into perception for director to get feedback.
*/
ComponentThread canvas;
}
namespace subconscious {
/* The subconscious is the seat of memory in Harikoff. It receives menties
* from director and stores them in memory for later recall.
*/
ComponentThread subconscious;
}
namespace body {
/* The body is a thread that polls, processes, and sends interoceptive sensor
* events to director. It enables these events to occur asynchronously,
* indepdendent any actions that the other threads are taking.
*/
ComponentThread body;
}
namespace world {
/* The world performs the same functions as the body, but for extrospective
* sensor events.
*/
ComponentThread world;
}
std::unordered_map<std::thread::id, ComponentThread&>
ComponentThread::componentThreads =
{
{director::director.thread.get_id(), director::director},
{simulator::canvas.thread.get_id(), simulator::canvas},
{subconscious::subconscious.thread.get_id(), subconscious::subconscious}
{subconscious::subconscious.thread.get_id(), subconscious::subconscious},
{body::body.thread.get_id(), body::body},
{world::world.thread.get_id(), world::world}
};
void ComponentThread::signalThread(std::thread::id id)
+7 -5
View File
@@ -16,7 +16,8 @@ namespace device {
std::string DeviceManager::readDeviceFile(const std::string& filename)
{
std::ifstream file(filename);
if (!file.is_open()) {
if (!file.is_open())
{
throw std::runtime_error(
std::string(__func__) + ": Couldn't open deviceSpec file: "
+ filename);
@@ -47,18 +48,19 @@ void DeviceManager::collateAllDeviceSpecs(void)
void DeviceManager::parseAllDeviceSpecs(void)
{
std::unique_ptr<FILE, decltype(&fclose)> input(
fmemopen((void*)allDeviceSpecs.c_str(),
allDeviceSpecs.size(), "r"),
fmemopen((void*)allDeviceSpecs.c_str(), allDeviceSpecs.size(), "r"),
&fclose);
if (!input) {
if (!input)
{
throw std::runtime_error(
std::string(__func__) + ": Failed to fmemopen() a FILE* for "
"parsing device specs");
}
deviceSpeclin = input.get();
if (deviceSpecpparse()) {
if (deviceSpecpparse())
{
throw std::runtime_error(
std::string(__func__) + ": Failed to parse device specs. "
"Check specs for errors");
+25 -6
View File
@@ -1,5 +1,6 @@
%option prefix="deviceSpecl"
%option nounput
%option noinput
%{
#include <vector>
#include <string>
@@ -25,15 +26,33 @@
"|" { return PIPE; }
"(" { return LPAREN; }
")" { return RPAREN; }
[ \t]*"="[ \t]* { return EQUALS; } // Allow optional whitespace around equals
([^=\|\(\) \t\r\n]|\\[ \t])+ {
"=" { return EQUALS; }
(\\.|[^=\|\(\) \t\r\n])+ {
std::string token(yytext);
token.erase(std::remove(token.begin(), token.end(), '\\'), token.end());
deviceSpecplval.str = strdup(token.c_str());
std::string unescaped;
unescaped.reserve(token.size());
for (size_t i = 0; i < token.size(); ++i)
{
if (token[i] != '\\')
{
unescaped.push_back(token[i]);
continue;
}
/* If a backslash is the final char before EOF, just continue so it gets
* dropped as a side effect.
*/
if (i + 1 >= token.size()) { continue; }
// Else push the char following the backslash.
unescaped.push_back(token[++i]);
}
deviceSpecplval.str = strdup(unescaped.c_str());
return STRING;
}
\r?\n { /* ignore newlines */ }
[ \t]+ { /* ignore whitespace */ }
[ \t\r\n]+ { /* ignore all whitespace, including newlines */ }
. { return yytext[0]; }
%%
-64
View File
@@ -1,64 +0,0 @@
#ifndef BODY_MESSAGE_H
#define BODY_MESSAGE_H
#include <vector>
#include <cstdint>
#include <body/limb.h>
#include <body/bodyPart.h>
class BodyMessage
{
public:
BodyMessage() = default;
~BodyMessage() = default;
};
class BodySpotImpactEntry
{
public:
enum class ReportType
{
PRESSURE,
PAIN,
PLEASURE,
HEAT,
COLD
};
BodySpotImpactEntry(uint32_t _spot, ReportType _type, uint32_t _value)
: spot(_spot), type(_type), value(_value)
{}
~BodySpotImpactEntry() = default;
public:
uint32_t spot;
ReportType type;
uint32_t value;
};
class BodySpotImpactInd
: public BodyMessage
{
public:
BodySpotImpactInd(BodyPart &_part) : part(_part) {}
~BodySpotImpactInd() = default;
public:
BodyPart &part;
std::vector<BodySpotImpactEntry> entries;
};
class BodyPartMsg
: public BodyMessage
{
public:
BodyPartMsg(const BodyPart& _part)
:part(_part)
{}
public:
const BodyPart& part;
};
#endif // BODY_MESSAGE_H
-28
View File
@@ -1,28 +0,0 @@
#ifndef BODY_LIMB_H
#define BODY_LIMB_H
#include <string>
#include <set>
#include <cstdint>
#include <body/bodyPart.h>
class BodyLimb
{
public:
BodyLimb(uint32_t _id) : id(_id) {}
BodyLimb(uint32_t _id,
const std::string& _name, const std::string& _desc,
const std::string& _loc)
: id(_id), name(_name), description(_desc), location(_loc)
{}
~BodyLimb() = default;
public:
uint32_t id;
std::string name, description, location;
std::set<uint32_t, BodyPart> parts;
};
#endif // BODY_LIMB_H
+17
View File
@@ -0,0 +1,17 @@
#ifndef _BODY_H
#define _BODY_H
namespace mrntt {
namespace body {
class Body
{
public:
Body() = default;
~Body() = default;
};
} // namespace body
} // namespace mrntt
#endif // _BODY_H
+23
View File
@@ -0,0 +1,23 @@
#ifndef MRNTT_BODY_BODYMAP_H
#define MRNTT_BODY_BODYMAP_H
#include <set>
#include <cstdint>
#include <body/limb.h>
namespace mrntt {
namespace body {
class BodyMap {
public:
BodyMap() = default;
~BodyMap() = default;
public:
std::set<uint32_t, Limb> limbs;
};
} // namespace body
} // namespace mrntt
#endif // MRNTT_BODY_BODYMAP_H
@@ -0,0 +1,66 @@
#ifndef MRNTT_BODY_BODYMESSAGE_H
#define MRNTT_BODY_BODYMESSAGE_H
#include <vector>
#include <cstdint>
#include <body/limb.h>
#include <body/part.h>
namespace mrntt {
namespace body {
class BodyMessage
{
public:
BodyMessage() = default;
~BodyMessage() = default;
};
class SpotImpactEntry
{
public:
enum class ReportType
{
PRESSURE,
PAIN,
PLEASURE,
HEAT,
COLD
};
SpotImpactEntry(uint32_t _spot, ReportType _type, uint32_t _value)
: spot(_spot), type(_type), value(_value)
{}
~SpotImpactEntry() = default;
public:
uint32_t spot;
ReportType type;
uint32_t value;
};
class SpotImpactInd : public BodyMessage
{
public:
SpotImpactInd(Part &_part) : part(_part) {}
~SpotImpactInd() = default;
public:
Part &part;
std::vector<SpotImpactEntry> entries;
};
class PartMsg : public BodyMessage
{
public:
PartMsg(const Part& _part) : part(_part) {}
public:
const Part& part;
};
} // namespace body
} // namespace mrntt
#endif // MRNTT_BODY_BODYMESSAGE_H
+34
View File
@@ -0,0 +1,34 @@
#ifndef MRNTT_BODY_LIMB_H
#define MRNTT_BODY_LIMB_H
#include <string>
#include <set>
#include <cstdint>
#include <body/part.h>
namespace mrntt {
namespace body {
class Limb
{
public:
Limb(uint32_t _id) : id(_id) {}
Limb(uint32_t _id,
const std::string& _name, const std::string& _desc,
const std::string& _loc)
: id(_id), name(_name), description(_desc), location(_loc)
{}
~Limb() = default;
public:
uint32_t id;
std::string name, description, location;
std::set<uint32_t, Part> parts;
};
} // namespace body
} // namespace mrntt
#endif // MRNTT_BODY_LIMB_H
@@ -6,12 +6,18 @@
#include <body/limb.h>
namespace mrntt {
namespace body {
class BodyMap {
public:
BodyMap() = default;
~BodyMap() = default;
std::set<uint32_t, BodyLimb> limbs;
std::set<uint32_t, Limb> limbs;
};
} // namespace body
} // namespace mrntt
#endif // _BODY_MAP_H
@@ -7,14 +7,17 @@
#include <sensors/interoceptor.h>
class BodySpot
namespace mrntt {
namespace body {
class Spot
{
public:
BodySpot(uint32_t _id, std::string _description)
Spot(uint32_t _id, std::string _description)
: id(_id), description(_description)
{}
~BodySpot() = default;
~Spot() = default;
public:
uint32_t id;
@@ -22,21 +25,24 @@ public:
std::set<uint32_t, Interoceptor> interoceptors;
};
class BodyPart
class Part
{
public:
BodyPart(uint32_t _partId, std::string _partName,
Part(uint32_t _partId, std::string _partName,
std::string _partDesc, std::string _partLoc)
: id(_partId), name(_partName),
description(_partDesc), location(_partLoc)
{}
~BodyPart() = default;
~Part() = default;
public:
const uint32_t id;
std::string name, description, location;
std::set<uint32_t, BodySpot> spots;
std::set<uint32_t, Spot> spots;
};
} // namespace body
} // namespace mrntt
#endif // BODYPART_H
+14
View File
@@ -0,0 +1,14 @@
#ifndef _MARIONETTE_H
#define _MARIONETTE_H
#include <cstdint>
namespace mrntt {
class Marionette
{
};
} // namespace mrntt
#endif // _MARIONETTE_H
+4 -2
View File
@@ -27,7 +27,8 @@ private:
public:
SenseApiLib(
const std::string& path, void *_dlopen_handle, getSenseApiDescFn *descFn)
const std::string& path, void *_dlopen_handle,
HK_GET_SENSE_API_DESC_FN_TYPEDEF *descFn)
: libraryPath(path),
dlopen_handle(_dlopen_handle, DlCloser()),
HK_GET_SENSE_API_DESC_FN_NAME(descFn)
@@ -61,7 +62,8 @@ public:
* This getter function should be visible to dlsym() so that Harikoff can
* find it in the lib after loading it, and call it.
*/
std::function<getSenseApiDescFn> HK_GET_SENSE_API_DESC_FN_NAME;
std::function<HK_GET_SENSE_API_DESC_FN_TYPEDEF>
HK_GET_SENSE_API_DESC_FN_NAME;
/**
* @brief Harikoff will call the `HK_GET_SENSE_API_DESC_FN_NAME` getter
+4
View File
@@ -0,0 +1,4 @@
AM_CPPFLAGS+= -I"$(top_srcdir)/hcore/include"
noinst_LIBRARIES = libmarionette.a
libmarionette_a_SOURCES = marionette.cpp
+9
View File
@@ -0,0 +1,9 @@
namespace mrntt {
int main(int argc, char *argv[])
{
return 0;
}
} // namespace mrntt
+1 -1
View File
@@ -92,7 +92,7 @@ SenseApiLib& SenseApiManager::loadSenseApiLib(const std::string& libraryPath)
}
// Initialize getSenseApiDescriptor
auto func = reinterpret_cast<getSenseApiDescFn *>(
auto func = reinterpret_cast<HK_GET_SENSE_API_DESC_FN_TYPEDEF *>(
dlsym(dlopen_handle.get(), HK_GET_SENSE_API_DESC_FN_NAME_STR));
if (!func)
{
+2
View File
@@ -4,6 +4,8 @@
#define HK_Q(x) #x
#define HK_QUOTE(x) HK_Q(x)
#define HK_CONCAT(a, b) a ## b
#define HK_UNMANGLED "C"
#endif // HK_PREPROCESSOR_H
+14 -23
View File
@@ -8,26 +8,6 @@
namespace hk {
namespace sense_api {
/* 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.
*/
typedef int (sal_mho_initializeRdyFn)(void);
typedef int (sal_mho_finalizeRdyFn)(void);
typedef int (sal_mho_attachDeviceAckFn)(const device::SenseDeviceSpec &desc);
typedef int (sal_mho_detachDeviceAckFn)(const device::SenseDeviceSpec &desc);
struct Sal_Mgmt_HkOps
{
// Lib calls this function to notify Harikoff that it's done initializing.
sal_mho_initializeRdyFn *initializeRdy;
// Lib calls this function to notify Harikoff that it's done finalizing.
sal_mho_finalizeRdyFn *finalizeRdy;
// Lib calls this to notify Harikoff that it's done attaching a device.
sal_mho_attachDeviceAckFn *attachDeviceAck;
// Lib calls this to notify Harikoff that it's done detaching a device.
sal_mho_detachDeviceAckFn *detachDeviceAck;
};
typedef int (sal_mlo_initializeIndFn)(void);
typedef int (sal_mlo_finalizeIndFn)(void);
typedef int (sal_mlo_attachDeviceReqFn)(const device::SenseDeviceSpec &desc);
@@ -62,8 +42,8 @@ struct Sal_Mgmt_LibOps
}
};
/* C++ version of the C struct above, which Harikoff uses to manage the
* lib and connect implexors to it.
/* 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.
*/
class SenseApiDesc
{
@@ -118,11 +98,22 @@ public:
Sal_Mgmt_LibOps sal_mgmt_libOps;
};
#define HK_GET_SENSE_API_DESC_FN_NAME getSenseApiDesc
#define HK_GET_SENSE_API_DESC_FN_NAME_STR \
HK_QUOTE(HK_GET_SENSE_API_DESC_FN_NAME)
#define HK_GET_SENSE_API_DESC_FN_TYPEDEF \
HK_CONCAT(HK_GET_SENSE_API_DESC_FN_NAME, Fn)
typedef const SenseApiDesc &(getSenseApiDescFn)(void);
/* Every Sense API library must define a global instance of this
* function. Harikoff will search for it and invoke it via dlsym().
*
* The function must return a SenseApiDesc struct that Hk will tell
* Hk what implexors can be used with it & what APIs it exports.
* The SenseApiDesc struct also gives Hk pointers to API functions
* to invoke for communication between Hk and the library.
*/
typedef const SenseApiDesc &(HK_GET_SENSE_API_DESC_FN_TYPEDEF)(void);
} // namespace sense_api
} // namespace hk
+70
View File
@@ -0,0 +1,70 @@
dnl _HK_LIB_ENABLE_IMPL(name, description, config_define, enable_var,
dnl enabled_list, [commands], [unimplemented])
dnl name - Name of the library (e.g., xcbXorg)
dnl description - Human readable description
dnl config_define - Configuration define name (e.g., CONFIG_XCBXORG_ENABLED)
dnl enable_var - Shell variable to track enabled status
dnl enabled_list - List variable to append name to (e.g., SENSEAPIS_ENABLED)
dnl commands - Optional: Shell commands to execute when enabling
dnl unimplemented - Optional: If "unimplemented", error out
AC_DEFUN([_HK_LIB_ENABLE_IMPL], [
AS_IF([test "x[]m4_normalize($7)" = "xunimplemented"], [
AC_MSG_ERROR([$1 is not yet implemented])
])
AS_IF([test "x${$4_done}" != "xyes"], [
$4_done=yes
AC_DEFINE([$3], [1], [Enable $2])
$5="${$5} $1"
$6
])
])
dnl _HK_LIB_ARG_ENABLE(dev_api_type, name, description, config_define,
dnl enabled_list, [commands], [unimplemented])
dnl lib/api_type - Type of API ("senseapi", "wilzorapi", or "lib")
dnl name - Name of the library (e.g., xcbXorg)
dnl description - Human readable description
dnl config_define - Configuration define name (e.g., CONFIG_XCBXORG_ENABLED)
dnl enabled_list - List variable to append name to
dnl commands - Optional: Shell commands to execute when enabling
dnl unimplemented - Optional: If "unimplemented", error out
AC_DEFUN([_HK_LIB_ARG_ENABLE], [
AC_ARG_ENABLE([$1-$2],
[AS_HELP_STRING([--enable-$1-$2], [Enable $3])],
[AS_IF([test "x$enable_$1_$2" != "xno"], [
_HK_LIB_ENABLE_IMPL([$2], [$3], [$4], [enable_$1_$2], [$5], [$6], [$7])
])],
[enable_$1_$2=no]
)
])
# Macro for enabling the XCB/Xorg Connection Mgr lib. Invoked by several other
# libs.
AC_DEFUN([_HK_LIB_XCBXORG_ENABLE], [
_HK_LIB_ENABLE_IMPL([xcbXorg], [XCB/Xorg Connection Manager backend],
[CONFIG_LIB_XCBXORG_ENABLED], [enable_lib_xcbXorg], [COMMONLIBS_ENABLED], [
PKG_CHECK_MODULES([XCB], [xcb], [], [
AC_MSG_ERROR(m4_normalize([XCB library not found. Sense API
XCB/Xorg requires the XCB dev headers and shlib.]))
])
AC_SUBST([XCB_CFLAGS])
AC_SUBST([XCB_LIBS])
]
)
])
AC_DEFUN([_HK_LIB_ALSA_ENABLE], [
_HK_LIB_ENABLE_IMPL([alsa], [ALSA Connection Manager backend],
[CONFIG_LIB_ALSA_ENABLED], [enable_lib_alsa], [COMMONLIBS_ENABLED], [
PKG_CHECK_MODULES([ALSA], [alsa], [], [
AC_MSG_ERROR(m4_normalize([ALSA library not found. Sense API
ALSA requires the ALSA dev headers and shlib.]))
])
AC_SUBST([ALSA_CFLAGS])
AC_SUBST([ALSA_LIBS])
]
)
])
# Temporary until we implement the xcbWindow SenseAPI.
_HK_LIB_XCBXORG_ENABLE
+105
View File
@@ -0,0 +1,105 @@
dnl Wrapper macros for specific API types
AC_DEFUN([HK_SENSEAPI_ARG_ENABLE], [
_HK_LIB_ARG_ENABLE([senseapi], [$1], [$2], [$3],
[SENSEAPIS_ENABLED], [$4], [$5])
])
AC_DEFUN([HK_WILZORAPI_ARG_ENABLE], [
_HK_LIB_ARG_ENABLE([wilzorapi], [$1], [$2], [$3],
[WILZORLIBS_ENABLED], [$4], [$5])
])
HK_SENSEAPI_ARG_ENABLE([xcbWindow],
m4_normalize([XCB/Xorg Window Attaching SenseAPI backend: enables Harikoff
to see attached window contents. Useful for web learning]),
[CONFIG_XCBWINDOW_ENABLED],
[_HK_LIB_XCBXORG_ENABLE],
[unimplemented]
)
HK_SENSEAPI_ARG_ENABLE([v4l],
m4_normalize([Video4Linux camera SenseAPI backend: enables Harikoff to
see via a V4L camera]),
[CONFIG_V4L_ENABLED], [
PKG_CHECK_MODULES([V4L], [libv4l], [], [
AC_MSG_ERROR(m4_normalize([libv4l not found. Sense API V4L
requires the libv4l dev headers and shlib.]))
])
AC_SUBST([V4L_CFLAGS])
AC_SUBST([V4L_LIBS])
],
[unimplemented]
)
HK_SENSEAPI_ARG_ENABLE([alsaMic],
m4_normalize([ALSA Microphone SenseAPI backend: enables Harikoff to
hear via an ALSA microphone]),
[CONFIG_ALSAMIC_ENABLED],
[_HK_LIB_ALSA_ENABLE],
[unimplemented]
)
HK_SENSEAPI_ARG_ENABLE([livox],
m4_normalize([Livox SenseAPI backend: enables Harikoff to
see via a Livox LiDAR sensor device]),
[CONFIG_LIVOX_ENABLED],
[],
[unimplemented]
)
HK_SENSEAPI_ARG_ENABLE([r3live],
m4_normalize([R3Live SenseAPI backend: enables Harikoff to
see via an R3Live LiDAR sensor fusion algorithm]),
[CONFIG_R3LIVE_ENABLED],
[],
[unimplemented]
)
HK_SENSEAPI_ARG_ENABLE([fastLio2],
m4_normalize([Fast LIO2 SenseAPI backend: enables Harikoff to
see via a Fast LIO2 LiDAR sensor fusion algorithm]),
[CONFIG_FASTLIO2_ENABLED],
[],
[unimplemented]
)
HK_SENSEAPI_ARG_ENABLE([adaLio2],
m4_normalize([Ada LIO2 SenseAPI backend: enables Harikoff to
see via an Ada LIO2 LiDAR sensor fusion algorithm]),
[CONFIG_ADALIO2_ENABLED],
[],
[unimplemented]
)
HK_SENSEAPI_ARG_ENABLE([deepLio2],
m4_normalize([Deep LIO2 SenseAPI backend: enables Harikoff to
see via a Deep LIO2 LiDAR sensor fusion algorithm]),
[CONFIG_DEEPLIO2_ENABLED],
[],
[unimplemented]
)
HK_WILZORAPI_ARG_ENABLE([xcbMouse],
m4_normalize([XCB/Xorg Mouse Wilzor API backend: enables Harikoff to
control a virtual mouse cursor via XCB/Xorg]),
[CONFIG_XCBMOUSE_ENABLED],
[_HK_LIB_XCBXORG_ENABLE],
[unimplemented]
)
HK_WILZORAPI_ARG_ENABLE([xcbKeyboard],
m4_normalize([XCB/Xorg Keyboard Wilzor API backend: enables Harikoff to
control a virtual keyboard via XCB/Xorg]),
[CONFIG_XCBKEYBOARD_ENABLED],
[_HK_LIB_XCBXORG_ENABLE],
[unimplemented]
)
HK_WILZORAPI_ARG_ENABLE([alsaVoice],
m4_normalize([ALSA Voice Wilzor API backend: enables Harikoff to
vocalize via an ALSA voice synthesizer]),
[CONFIG_ALSAVOICE_ENABLED],
[_HK_LIB_ALSA_ENABLE],
[unimplemented]
)
-22
View File
@@ -1,22 +0,0 @@
SENSEAPIS_ENABLED=
AC_ARG_ENABLE([senseapi-xcbxorg],
[AS_HELP_STRING([--enable-senseapi-xcbxorg],
[Enable XCB/Xorg SenseAPI backend])],
[AS_CASE([$enableval],
[no], [enable_senseapi_xcbxorg=no],
[yes|""|*], [
enable_senseapi_xcbxorg=yes
AC_DEFINE([XCBXORG_ENABLED], [1],
[Define to 1 if you have XCB/Xorg SenseAPI backend])
SENSEAPIS_ENABLED="${SENSEAPIS_ENABLED} xcbXorg"
PKG_CHECK_MODULES([XCB], [xcb], [], [
AC_MSG_ERROR(m4_normalize([XCB library not found. Sense API
XCB/Xorg requires the XCB dev headers and shlib.]))
])
AC_SUBST([XCB_CFLAGS])
AC_SUBST([XCB_LIBS])
]
)],
[enable_senseapi_xcbxorg=no]
)
+3
View File
@@ -92,8 +92,11 @@ static int initializeHarikoff(int argc, char **argv, char **envp)
sense_api::SenseApiManager::getInstance().loadAllSenseApiLibsFromOptions();
std::cout << sense_api::SenseApiManager::getInstance().stringifyLibs()
<< std::endl;
std::cerr << "About to initializeAllSenseApiLibs" << std::endl;
sense_api::SenseApiManager::getInstance().initializeAllSenseApiLibs();
std::cerr << "About to attachAllSenseDevicesFromSpecs" << std::endl;
sense_api::SenseApiManager::getInstance().attachAllSenseDevicesFromSpecs();
std::cerr << "Done attachAllSenseDevicesFromSpecs" << std::endl;
/* Start the threads */
for (const auto& [id, componentThread]
-1
View File
@@ -1 +0,0 @@
SUBDIRS = @SENSEAPIS_ENABLED@