/* Discolitez plugin, for controlling eight channels via
* www.obdev.at's AVR-USB PowerSwitch example
*
+080921 Uses the first PowerSwitch adapter found, but if DLL file name
has a number after a blank, that number is used (0-based).
Here, no editor facility is implemented, in opposite to DLO_Parallel
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shlwapi.h>
#include "libusb-win32-device-bin-0.1.12.1/include/usb.h" // requires _cdecl
// Opens the <n>th device (zero-based) that matches to
// Vendor, Product, Revision, Manufacturer string, and Product string.
// Zeroes given skip the match.
// Returns NULL when no match available
static usb_dev_handle* _stdcall usb_findA(int Vid, int Pid, int Rev,
const char *sManufacturer, const char *sProduct, int n) {
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *handle;
char string[64];
usb_init();
usb_find_busses();
usb_find_devices();
for (bus=usb_get_busses(); bus; bus=bus->next) {
for (dev=bus->devices; dev; dev=dev->next) {
if (Vid && dev->descriptor.idVendor!=Vid) continue;
if (Pid && dev->descriptor.idProduct!=Pid) continue;
if (Rev && dev->descriptor.bcdDevice!=Rev) continue;
handle = usb_open(dev); /* we need to open the device in order to query strings */
if (!handle) continue; /* now check whether the names match: */
if (sManufacturer) {
if (usb_get_string_simple(handle,dev->descriptor.iManufacturer,string,sizeof(string))<=0) goto closehandle;
if (lstrcmp(string,sManufacturer)) goto closehandle;
}
if (sProduct) {
if (usb_get_string_simple(handle,dev->descriptor.iProduct,string,sizeof(string))<=0) goto closehandle;
if (lstrcmp(string,sProduct)) goto closehandle;
}
if (n) { /* found, but take next match! */
n--;
closehandle:
usb_close(handle);
continue;
}
return handle;
}
}
return NULL;
}
static int DevNum;
// Opens the first PowerSwitch device, returns NULL when none available
static usb_dev_handle* OpenPowerSwitch(void) {
return usb_findA(0x16C0/*VOTI*/,0x05DC/*Obdev*/,0,"www.obdev.at","PowerSwitch",DevNum);
}
static usb_dev_handle *handle;
static HINSTANCE hInst;
static BOOL CALLBACK ConfigDlgProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
switch (Msg) {
case WM_INITDIALOG: {
// Show current state of PowerSwitch found
CheckDlgButton(Wnd,11,(UINT)handle);
}return TRUE;
case WM_COMMAND: switch (LOWORD(wParam)) {
case 1:
case 2: EndDialog(Wnd,wParam); break;
case 10: { // re-open PowerSwitch (in case of some disconnection meanwhile)
if (handle) usb_close(handle);
handle=OpenPowerSwitch();
CheckDlgButton(Wnd,11,(UINT)handle);
}break;
}break;
}
return FALSE;
}
static BYTE laststate;
/**********************
* exported functions *
**********************/
BYTE _declspec(dllexport) DLO_getnch(void) {
return 8;
}
LPSTR _declspec(dllexport) DLO_getname(void) {
if (DevNum) {
static char buf[32];
wnsprintf(buf,sizeof(buf),"USB PowerSwitch #%d",DevNum);
return buf;
}
return "USB PowerSwitch";
}
void _declspec(dllexport) DLO_datain(BYTE ch, BYTE val) {
BYTE mask;
if (!handle) return;
// avoid too many calls to usb_control_msg()
mask = 1 << (ch-1);
if (val) {
if (laststate&mask) return;
}else{
if (!(laststate&mask)) return;
}
laststate ^= mask;
usb_control_msg(handle,USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_IN,
val ? 2/*PSCMD_ON*/ : 3/*PSCMD_OFF*/, 0/*duration*/, ch-1,
NULL,0,200);
}
void _declspec(dllexport) DLO_init(void) {
handle=OpenPowerSwitch();
if (handle) {
int i;
for (i=0; i<8; i++) usb_control_msg(handle,
USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_ENDPOINT_IN,3,0,i,NULL,0,200);
laststate=0;
}
}
void _declspec(dllexport) DLO_done(void) {
if (handle) usb_close(handle);
}
void _declspec(dllexport) DLO_about(void) {
DialogBox(hInst,MAKEINTRESOURCE(100),0,ConfigDlgProc);
}
/********************
* main entry point *
********************/
void CALLBACK _DllMainCRTStartup(HINSTANCE hInstDll,DWORD fdwReason,LPVOID lpReserved) {
if (fdwReason==DLL_PROCESS_ATTACH) {
char DllName[MAX_PATH], *p;
hInst = hInstDll; // Where the (dialog) resource comes from - and the file name
if (GetModuleFileName(hInstDll,DllName,sizeof(DllName))
&& (p=StrChr(PathFindFileName(DllName),' ')))
DevNum = StrToInt(p);
DisableThreadLibraryCalls(hInstDll); // returns TRUE to continue DLL loading
}
}
Detected encoding: ASCII (7 bit) | 2
|