Skip to content

Commit

Permalink
Merge pull request #544 from jhsrennie/usbmappings
Browse files Browse the repository at this point in the history
Allow multiple ids per USB device
  • Loading branch information
John Rennie committed Nov 25, 2011
2 parents e86e4f4 + 17cc7e2 commit da3fabb
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 24 deletions.
12 changes: 2 additions & 10 deletions system/peripherals.xml
@@ -1,13 +1,5 @@
<peripherals>
<peripheral vendor="1915" product="003B" bus="usb" name="Motorola Nyxboard Hybrid" mapTo="nyxboard">
<setting key="keymap_enabled" type="bool" value="1" label="35008" />
<setting key="keymap" value="nyxboard" label="35007" configurable="0" />
<setting key="enable_flip_commands" type="bool" value="1" label="36005" />
<setting key="flip_keyboard" value="XBMC.VideoLibrary.Search" label="36002" />
<setting key="flip_remote" value="Dialog.Close(virtualkeyboard)" label="36003" />
<setting key="key_user" value="" label="36004" />
</peripheral>
<peripheral vendor="22B8" product="003B" bus="usb" name="Motorola Nyxboard Hybrid" mapTo="nyxboard">
<peripheral vendor_product="1915:003B,22B8:003B" bus="usb" name="Motorola Nyxboard Hybrid" mapTo="nyxboard">
<setting key="keymap_enabled" type="bool" value="1" label="35008" />
<setting key="keymap" value="nyxboard" label="35007" configurable="0" />
<setting key="enable_flip_commands" type="bool" value="1" label="36005" />
Expand All @@ -16,7 +8,7 @@
<setting key="key_user" value="" label="36004" />
</peripheral>

<peripheral vendor="2548" product="1001" bus="usb" name="Pulse-Eight CEC Adaptor" mapTo="cec">
<peripheral vendor_product="2548:1001" bus="usb" name="Pulse-Eight CEC Adaptor" mapTo="cec">
<setting key="enabled" type="bool" value="1" label="305" />
<setting key="port" type="string" value="" label="792" />
<setting key="cec_hdmi_port" type="int" value="1" min="1" max="16" label="36015" />
Expand Down
9 changes: 7 additions & 2 deletions xbmc/peripherals/PeripheralTypes.h
Expand Up @@ -62,10 +62,15 @@ namespace PERIPHERALS
PERIPHERAL_TUNER
};

struct PeripheralID
{
int m_iVendorId;
int m_iProductId;
};

struct PeripheralDeviceMapping
{
int m_iVendorId;
int m_iProductId;
std::vector<PeripheralID> m_PeripheralID;
PeripheralBusType m_busType;
PeripheralType m_class;
CStdString m_strDeviceName;
Expand Down
51 changes: 39 additions & 12 deletions xbmc/peripherals/Peripherals.cpp
Expand Up @@ -324,12 +324,16 @@ int CPeripherals::GetMappingForDevice(const CPeripheralBus &bus, const Periphera
for (unsigned int iMappingPtr = 0; iMappingPtr < m_mappings.size(); iMappingPtr++)
{
PeripheralDeviceMapping mapping = m_mappings.at(iMappingPtr);

bool bProductMatch = false;
for (unsigned int i = 0; i < mapping.m_PeripheralID.size(); i++)
if (mapping.m_PeripheralID[i].m_iVendorId == iVendorId && mapping.m_PeripheralID[i].m_iProductId == iProductId)
bProductMatch = true;

bool bBusMatch = (mapping.m_busType == PERIPHERAL_BUS_UNKNOWN || mapping.m_busType == bus.Type());
bool bVendorMatch = (mapping.m_iVendorId == 0 || mapping.m_iVendorId == iVendorId);
bool bProductMatch = (mapping.m_iProductId == 0 || mapping.m_iProductId == iProductId);
bool bClassMatch = (mapping.m_class == PERIPHERAL_UNKNOWN || mapping.m_class == classType);

if (bBusMatch && bVendorMatch && bProductMatch && bClassMatch)
if (bProductMatch && bBusMatch && bClassMatch)
{
CStdString strVendorId, strProductId;
PeripheralTypeTranslator::FormatHexString(iVendorId, strVendorId);
Expand All @@ -348,12 +352,16 @@ void CPeripherals::GetSettingsFromMapping(CPeripheral &peripheral) const
for (unsigned int iMappingPtr = 0; iMappingPtr < m_mappings.size(); iMappingPtr++)
{
const PeripheralDeviceMapping *mapping = &m_mappings.at(iMappingPtr);

bool bProductMatch = false;
for (unsigned int i = 0; i < mapping->m_PeripheralID.size(); i++)
if (mapping->m_PeripheralID[i].m_iVendorId == peripheral.VendorId() && mapping->m_PeripheralID[i].m_iProductId == peripheral.ProductId())
bProductMatch = true;

bool bBusMatch = (mapping->m_busType == PERIPHERAL_BUS_UNKNOWN || mapping->m_busType == peripheral.GetBusType());
bool bVendorMatch = (mapping->m_iVendorId == 0 || mapping->m_iVendorId == peripheral.VendorId());
bool bProductMatch = (mapping->m_iProductId == 0 || mapping->m_iProductId == peripheral.ProductId());
bool bClassMatch = (mapping->m_class == PERIPHERAL_UNKNOWN || mapping->m_class == peripheral.Type());

if (bBusMatch && bVendorMatch && bProductMatch && bClassMatch)
if (bBusMatch && bProductMatch && bClassMatch)
{
for (map<CStdString, CSetting *>::const_iterator itr = mapping->m_settings.begin(); itr != mapping->m_settings.end(); itr++)
peripheral.AddSetting((*itr).first, (*itr).second);
Expand All @@ -380,10 +388,29 @@ bool CPeripherals::LoadMappings(void)
TiXmlElement *currentNode = pRootElement->FirstChildElement("peripheral");
while (currentNode)
{
CStdStringArray vpArray, idArray;
PeripheralID id;
PeripheralDeviceMapping mapping;

mapping.m_iVendorId = currentNode->Attribute("vendor") ? PeripheralTypeTranslator::HexStringToInt(currentNode->Attribute("vendor")) : 0;
mapping.m_iProductId = currentNode->Attribute("product") ? PeripheralTypeTranslator::HexStringToInt(currentNode->Attribute("product")) : 0;
// If there is no vendor_product attribute ignore this entry
if (!currentNode->Attribute("vendor_product"))
continue;

This comment has been minimized.

Copy link
@chadoe

chadoe Nov 25, 2011

Contributor

if currentNode doesn't have a "vendor_product" attribute it will loop forever, same on line 412

This comment has been minimized.

Copy link
@opdenkamp

opdenkamp Nov 26, 2011

Member

vendor and product id are not required. you can also map generic devices ("catch-all" at the end of the peripherals.xml file)

sorry that I didn't' think about this earlier, but I was just describing a way for skinners to add a generic device mapping, so people without nyxboards and cec adapters can add things easily, when I noticed it wasn't working anymore :)

This comment has been minimized.

Copy link
@jhsrennie

jhsrennie Nov 27, 2011

Oops, I've been a bit too zealous in my error checking!

Can you give me an example of a generic device and how it would be used? Possibly one I can test myself. An obvious quick fix would be to make the vendor and product id default to zero if they aren't supplied, but that feels a little tacky to me and I wonder if there is a more elegant solution.

This comment has been minimized.

Copy link
@jhsrennie

jhsrennie Nov 29, 2011

@ghuron: you can just edit the entry in peripherals.xml to be:

<peripheral vendor_product="2548:1001,04D8:FF59" bus="usb" name="Pulse-Eight CEC Adaptor" mapTo="cec">

or maybe it's better to add a completely new entry if the CEC adaptor you're using is different enough.

This comment has been minimized.

Copy link
@opdenkamp

opdenkamp Nov 29, 2011

Member

@jhsrennie

<peripheral class="hid" name="Generic HID device" mapTo="hid">
  <setting key="keymap_enabled" type="bool" value="0" label="35008" />
  <setting key="keymap" value="" label="35007" />
</peripheral>

This comment has been minimized.

Copy link
@jhsrennie

jhsrennie Nov 30, 2011

@opdenkamp: I don't understand what this peripheral does in XBMC. I modified your example to be:

<peripheral class="hid" vendor_product="0000:0000" name="Generic HID device" mapTo="hid">

and this loaded fine, but I can't see what this peripheral actually does. Is it encapsulated in PeripheralHID.cpp? This class doesn't seem to do anything.


// The vendor_product attribute is a list of comma separated vendor:product pairs
StringUtils::SplitString(currentNode->Attribute("vendor_product"), ",", vpArray);
for (unsigned int i = 0; i < vpArray.size(); i++)
{
StringUtils::SplitString(vpArray[i], ":", idArray);
if (idArray.size() != 2)
continue;

id.m_iVendorId = PeripheralTypeTranslator::HexStringToInt(idArray[0]);
id.m_iProductId = PeripheralTypeTranslator::HexStringToInt(idArray[1]);
mapping.m_PeripheralID.push_back(id);
}
if (mapping.m_PeripheralID.size() == 0)
continue;

mapping.m_busType = PeripheralTypeTranslator::GetBusTypeFromString(currentNode->Attribute("bus"));
mapping.m_class = PeripheralTypeTranslator::GetTypeFromString(currentNode->Attribute("class"));
mapping.m_strDeviceName = currentNode->Attribute("name") ? CStdString(currentNode->Attribute("name")) : StringUtils::EmptyString;
Expand Down Expand Up @@ -432,10 +459,10 @@ void CPeripherals::GetSettingsFromMappingsFile(TiXmlElement *xmlNode, map<CStdSt
}
else if (strSettingsType.Equals("float"))
{
float fValue = currentNode->Attribute("value") ? atof(currentNode->Attribute("value")) : 0;
float fMin = currentNode->Attribute("min") ? atof(currentNode->Attribute("min")) : 0;
float fStep = currentNode->Attribute("step") ? atof(currentNode->Attribute("step")) : 0;
float fMax = currentNode->Attribute("max") ? atof(currentNode->Attribute("max")) : 0;
float fValue = currentNode->Attribute("value") ? (float) atof(currentNode->Attribute("value")) : 0;
float fMin = currentNode->Attribute("min") ? (float) atof(currentNode->Attribute("min")) : 0;
float fStep = currentNode->Attribute("step") ? (float) atof(currentNode->Attribute("step")) : 0;
float fMax = currentNode->Attribute("max") ? (float) atof(currentNode->Attribute("max")) : 0;
setting = new CSettingFloat(0, strKey, iLabelId, fValue, fMin, fStep, fMax, SPIN_CONTROL_FLOAT);
}
else
Expand Down

1 comment on commit da3fabb

@jhsrennie
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed in #547

Please sign in to comment.