Merge branch 'master' into release
authorLars Op den Kamp <lars@opdenkamp.eu>
Sun, 2 Oct 2011 10:11:18 +0000 (12:11 +0200)
committerLars Op den Kamp <lars@opdenkamp.eu>
Sun, 2 Oct 2011 10:11:18 +0000 (12:11 +0200)
ChangeLog
debian/changelog
project/libcec.vcxproj
src/lib/CECDetect.cpp

index 877a98213b4cc32a41ef590fc8fa58111c12b6b3..3a893f2308b54c90e862deced6121632d76fb0eb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
+libcec (0.3-1) unstable; urgency=low
+
+  * added device detection support for Windows
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com>  Sun, 02 Oct 2011 12:09:33 +0200
+
+libcec (0.2-1) unstable; urgency=low
+
+  * added a Close() method to the interface
+  * Added CEC command that were received by the adapter in a buffer that can be
+    read by a client with GetNextCommand()/cec_get_next_command(). added a
+    'help' command to the test client, that displays all available commands
+  * Fixed setting the ackmask. deprecated SetAckMask()/cec_set_ack_mask(). use
+    SetLogicalAddress()/cec_set_logical_address() instead. add 'la' command to
+    the testclient to set the logical address of the cec adapter
+  * Added optional logical and physical address parameters to
+    LoadLibCec()/cec_init() on the interface. fixed wrongly placed namespace
+    close tag in CECExports.h. updated interface documentation. bumped
+    interface version to 2.
+  * fixed hardcoded ackmask in SetAckMast(). set a shorter display name in the
+    test client. the previous one was too long and being rejected
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com>  Fri, 28 Sep 2011 01:33:00 +0200
+
 libcec (0.1-1) unstable; urgency=low
 
   * Initial release v0.1
 
- -- Lars Op den Kamp <info@pulse-eight.com>  Wed, 28 Sep 2011 21:42:48 +0200
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com>  Wed, 28 Sep 2011 23:55:48 +0200
index 76faddc15b900c629ac7392b2f6145fb52c215a3..3a893f2308b54c90e862deced6121632d76fb0eb 100644 (file)
@@ -1,3 +1,9 @@
+libcec (0.3-1) unstable; urgency=low
+
+  * added device detection support for Windows
+
+ -- Pulse-Eight Packaging <packaging@pulse-eight.com>  Sun, 02 Oct 2011 12:09:33 +0200
+
 libcec (0.2-1) unstable; urgency=low
 
   * added a Close() method to the interface
index 460586f54fe007b58eb5d4586fc5c90be7e42f2a..c4a3372883aaeb2773070bf6ce87b584ca6f80aa 100644 (file)
     <Link>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <OutputFile>$(SolutionDir)\..\$(TargetName)$(TargetExt)</OutputFile>
-      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
       <IgnoreSpecificDefaultLibraries>libcmtd</IgnoreSpecificDefaultLibraries>
       <Version>2</Version>
     </Link>
index 2a2668bd24ec2c5d423755ef1cb3608a378cc946..a8aa7e1cd531c29adbfb94572f8fabfdeaf06395 100644 (file)
 #include "CECDetect.h"
 #include "libPlatform/os-dependent.h"
 #include "util/StdString.h"
+#include <string.h>
+
 #if !defined(__WINDOWS__)
 #include <dirent.h>
 #include <libudev.h>
 #include <poll.h>
+#else
+#include <setupapi.h>
+
+// the virtual COM port only shows up when requesting devices with the raw device guid!
+static GUID USB_RAW_GUID =  { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };
 #endif
-#include <string.h>
 
 #define CEC_VID 0x2548
 #define CEC_PID 0x1001
@@ -152,6 +158,102 @@ int CCECDetect::FindDevices(vector<cec_device> &deviceList, const char *strDevic
 
   udev_enumerate_unref(enumerate);
   udev_unref(udev);
+#else
+  HDEVINFO hDevHandle;
+  DWORD    required = 0, iMemberIndex = 0;
+  int      nBufferSize = 0;
+
+  SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
+  deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+
+  SP_DEVINFO_DATA devInfoData;
+  devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+
+  if ((hDevHandle = SetupDiGetClassDevs(&USB_RAW_GUID, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) == INVALID_HANDLE_VALUE)
+    return iFound;
+
+  BOOL bResult = true;
+  TCHAR *buffer = NULL;
+  PSP_DEVICE_INTERFACE_DETAIL_DATA devicedetailData;
+  while(bResult)
+  {
+    bResult = SetupDiEnumDeviceInfo(hDevHandle, iMemberIndex, &devInfoData);
+
+    if (bResult)
+      bResult = SetupDiEnumDeviceInterfaces(hDevHandle, 0, &USB_RAW_GUID, iMemberIndex, &deviceInterfaceData);
+
+    if(!bResult)
+    {
+      SetupDiDestroyDeviceInfoList(hDevHandle);
+      delete []buffer;
+      buffer = NULL;
+      return iFound;
+    }
+
+    iMemberIndex++;
+    BOOL bDetailResult = false;
+    {
+      // As per MSDN, Get the required buffer size. Call SetupDiGetDeviceInterfaceDetail with a 
+      // NULL DeviceInterfaceDetailData pointer, a DeviceInterfaceDetailDataSize of zero, 
+      // and a valid RequiredSize variable. In response to such a call, this function returns 
+      // the required buffer size at RequiredSize and fails with GetLastError returning 
+      // ERROR_INSUFFICIENT_BUFFER. 
+      // Allocate an appropriately sized buffer and call the function again to get the interface details. 
+
+      SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, NULL, 0, &required, NULL);
+
+      buffer = new TCHAR[required];
+      devicedetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) buffer;
+      devicedetailData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
+      nBufferSize = required;
+    }
+
+    bDetailResult = SetupDiGetDeviceInterfaceDetail(hDevHandle, &deviceInterfaceData, devicedetailData, nBufferSize , &required, NULL);
+    if(!bDetailResult)
+      continue;
+
+    if (strDevicePath && strcmp(strDevicePath, devicedetailData->DevicePath) != 0)
+      continue;
+
+    CStdString strVendorId;
+    CStdString strProductId;
+    CStdString strTmp(devicedetailData->DevicePath);
+    strVendorId = strTmp.substr(strTmp.Find("vid_") + 4, 4);
+    strProductId = strTmp.substr(strTmp.Find("pid_") + 4, 4);
+    if (strTmp.Find("&mi_") >= 0 && strTmp.Find("&mi_00") < 0)
+      continue;
+
+    int iVendor, iProduct;
+    sscanf(strVendorId, "%x", &iVendor);
+    sscanf(strProductId, "%x", &iProduct);
+    if (iVendor != CEC_VID || iProduct != CEC_PID)
+      continue;
+
+    HKEY hDeviceKey = SetupDiOpenDevRegKey(hDevHandle, &devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
+    if (!hDeviceKey)
+      continue;
+
+    TCHAR strPortName[256];
+    strPortName[0] = _T('\0');
+    DWORD dwSize = sizeof(strPortName);
+    DWORD dwType = 0;
+
+    /* search the registry */
+    if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, reinterpret_cast<LPBYTE>(strPortName), &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
+    {
+      if (_tcslen(strPortName) > 3 && _tcsnicmp(strPortName, _T("COM"), 3) == 0 &&
+        _ttoi(&(strPortName[3])) > 0)
+      {
+        cec_device foundDev;
+        foundDev.path = devicedetailData->DevicePath;
+        foundDev.comm = strPortName;
+        deviceList.push_back(foundDev);
+        ++iFound;
+      }
+    }
+
+    RegCloseKey(hDeviceKey);
+  }
 #endif
 
   return iFound;