USB: clang-format

This commit is contained in:
Gauvain 'GovanifY' Roussel-Tarbouriech 2020-11-02 23:42:03 +01:00 committed by refractionpcsx2
parent 56e96a8ff9
commit 0c43fa92e5
121 changed files with 30422 additions and 26655 deletions

View File

@ -34,18 +34,21 @@ bool configChanged = false;
Config conf;
char USBfreezeID[] = "USBqemuW01";
typedef struct {
typedef struct
{
char freezeID[11];
s64 cycles;
s64 remaining;
OHCIState t;
struct {
struct
{
DeviceType index;
u32 size;
USBDevice dev;
} device[2];
struct usb_packet {
struct usb_packet
{
USBEndpoint ep; //usb packet endpoint
int dev_index;
int data_size;
@ -70,7 +73,8 @@ Display *g_GSdsp;
Window g_GSwin;
#endif
Config::Config(): Log(0)
Config::Config()
: Log(0)
{
memset(&WheelType, 0, sizeof(WheelType));
}
@ -86,7 +90,8 @@ void DestroyDevices()
{
for (int i = 0; i < 2; i++)
{
if(qemu_ohci && qemu_ohci->rhport[i].port.dev) {
if (qemu_ohci && qemu_ohci->rhport[i].port.dev)
{
qemu_ohci->rhport[i].port.dev->klass.unrealize(qemu_ohci->rhport[i].port.dev);
qemu_ohci->rhport[i].port.dev = nullptr;
}
@ -111,7 +116,8 @@ USBDevice* CreateDevice(DeviceType index, int port)
else
SysMessage(TEXT("Device %d: Unknown device type"), 1 - port);
if (!device) {
if (!device)
{
USB_LOG("USBqemu: failed to create device type %d on port %d\n", index, port);
}
return device;
@ -120,7 +126,8 @@ USBDevice* CreateDevice(DeviceType index, int port)
//TODO re-do sneaky attach
void USBAttach(int port, USBDevice* dev, bool sneaky = false)
{
if (!qemu_ohci) return;
if (!qemu_ohci)
return;
USBDevice* tmp = qemu_ohci->rhport[port].port.dev;
if (tmp)
@ -152,7 +159,8 @@ USBDevice* CreateDevice(const std::string& name, int port)
SysMessage(TEXT("Port %d: Unknown device type"), port);
}
if (!device) {
if (!device)
{
USB_LOG("USBqemu: failed to create device '%s' on port %d\n", name.c_str(), port);
}
return device;
@ -160,7 +168,8 @@ USBDevice* CreateDevice(const std::string& name, int port)
void CreateDevices()
{
if(!qemu_ohci) return; //No USBinit yet ie. called from config. dialog
if (!qemu_ohci)
return; //No USBinit yet ie. called from config. dialog
DestroyDevices();
for (int i = 0; i < 2; i++)
@ -170,7 +179,8 @@ void CreateDevices()
}
}
s32 USBinit() {
s32 USBinit()
{
OSDebugOut(TEXT("USBinit\n"));
RegisterDevice::Register();
@ -184,7 +194,8 @@ s32 USBinit() {
}
qemu_ohci = ohci_create(0x1f801600, 2);
if(!qemu_ohci) return 1;
if (!qemu_ohci)
return 1;
clocks = 0;
remaining = 0;
@ -192,7 +203,8 @@ s32 USBinit() {
return 0;
}
void USBshutdown() {
void USBshutdown()
{
OSDebugOut(TEXT("USBshutdown\n"));
DestroyDevices();
@ -203,14 +215,16 @@ void USBshutdown() {
ram = 0;
//#ifdef _DEBUG
if (conf.Log && usbLog) {
if (conf.Log && usbLog)
{
fclose(usbLog);
usbLog = nullptr;
}
//#endif
}
s32 USBopen(void *pDsp) {
s32 USBopen(void* pDsp)
{
if (conf.Log && !usbLog)
{
@ -245,9 +259,12 @@ s32 USBopen(void *pDsp) {
OSDebugOut("X11 display %p Xwindow %lu\n", g_GSdsp, g_GSwin);
#endif
try {
try
{
shared::Initialize(pDsp);
} catch (std::runtime_error &e) {
}
catch (std::runtime_error& e)
{
SysMessage(TEXT("%" SFMTs "\n"), e.what());
}
@ -267,7 +284,8 @@ s32 USBopen(void *pDsp) {
return 0;
}
void USBclose() {
void USBclose()
{
OSDebugOut(TEXT("USBclose\n"));
if (usb_device[0] && usb_device[0]->klass.close)
@ -277,20 +295,22 @@ void USBclose() {
usb_device[1]->klass.close(usb_device[1]);
shared::Uninitialize();
}
u8 USBread8(u32 addr) {
u8 USBread8(u32 addr)
{
USB_LOG("* Invalid 8bit read at address %lx\n", addr);
return 0;
}
u16 USBread16(u32 addr) {
u16 USBread16(u32 addr)
{
USB_LOG("* Invalid 16bit read at address %lx\n", addr);
return 0;
}
u32 USBread32(u32 addr) {
u32 USBread32(u32 addr)
{
u32 hard;
hard = ohci_mem_read(qemu_ohci, addr);
@ -300,27 +320,32 @@ u32 USBread32(u32 addr) {
return hard;
}
void USBwrite8(u32 addr, u8 value) {
void USBwrite8(u32 addr, u8 value)
{
USB_LOG("* Invalid 8bit write at address %lx value %x\n", addr, value);
}
void USBwrite16(u32 addr, u16 value) {
void USBwrite16(u32 addr, u16 value)
{
USB_LOG("* Invalid 16bit write at address %lx value %x\n", addr, value);
}
void USBwrite32(u32 addr, u32 value) {
void USBwrite32(u32 addr, u32 value)
{
USB_LOG("* Known 32bit write at address %lx value %lx\n", addr, value);
ohci_mem_write(qemu_ohci, addr, value);
}
extern u32 bits;
void USBsetRAM(void *mem) {
void USBsetRAM(void* mem)
{
ram = (u8*)mem;
Reset();
}
s32 USBfreeze(int mode, freezeData *data) {
s32 USBfreeze(int mode, freezeData* data)
{
USBfreezeData usbd = {0};
//TODO FREEZE_SIZE mismatch causes loading to fail in PCSX2 beforehand
@ -409,7 +434,8 @@ s32 USBfreeze(int mode, freezeData *data) {
memcpy(usb_device[i]->setup_buf, tmp.setup_buf, sizeof(tmp.setup_buf));
usb_desc_set_config(usb_device[i], tmp.configuration);
for (int k = 0; k < 16; k++) {
for (int k = 0; k < 16; k++)
{
usb_device[i]->altsetting[k] = tmp.altsetting[k];
usb_desc_set_interface(usb_device[i], k, tmp.altsetting[k]);
}
@ -454,12 +480,10 @@ s32 USBfreeze(int mode, freezeData *data) {
else //if (usbd.ep.pid == USB_TOKEN_OUT)
eps = usb_device[dev_index]->ep_out;
for (int k = 0; k < USB_MAX_ENDPOINTS; k++) {
for (int k = 0; k < USB_MAX_ENDPOINTS; k++)
{
if (usbd.usb_packet.ep.type == eps[k].type
&& usbd.usb_packet.ep.nr == eps[k].nr
&& usbd.usb_packet.ep.ifnum == eps[k].ifnum
&& usbd.usb_packet.ep.pid == eps[k].pid)
if (usbd.usb_packet.ep.type == eps[k].type && usbd.usb_packet.ep.nr == eps[k].nr && usbd.usb_packet.ep.ifnum == eps[k].ifnum && usbd.usb_packet.ep.pid == eps[k].pid)
{
qemu_ohci->usb_packet.ep = &eps[k];
break;
@ -552,7 +576,8 @@ s32 USBfreeze(int mode, freezeData *data) {
// PCSX2 queries size before load too, so can't use actual packet length which varies :(
data->size += 8192; // qemu_ohci->usb_packet.actual_length;
if (qemu_ohci->usb_packet.actual_length > 8192) {
if (qemu_ohci->usb_packet.actual_length > 8192)
{
fprintf(stderr, "Saving failed! USB packet is larger than 8K, try again later.\n");
return -1;
}

View File

@ -64,4 +64,3 @@ int InitWindow(HWND);
void UninitWindow();
#endif
#endif

View File

@ -25,7 +25,8 @@
HINSTANCE hInst;
extern bool configChanged;
void SysMessageA(const char *fmt, ...) {
void SysMessageA(const char* fmt, ...)
{
va_list list;
char tmp[512];
@ -35,7 +36,8 @@ void SysMessageA(const char *fmt, ...) {
MessageBoxA(0, tmp, "Qemu USB Msg", 0);
}
void SysMessageW(const wchar_t *fmt, ...) {
void SysMessageW(const wchar_t* fmt, ...)
{
va_list list;
wchar_t tmp[512];
@ -101,10 +103,12 @@ void PopulateAPIs(HWND hW, int port)
SendDlgItemMessage(hW, port ? IDC_COMBO_API1 : IDC_COMBO_API2, CB_SETCURSEL, sel, 0);
}
BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int port;
switch(uMsg) {
switch (uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessageA(hW, IDC_BUILD_DATE, WM_SETTEXT, 0, (LPARAM)__DATE__ " " __TIME__);
LoadConfig();
@ -154,7 +158,8 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
switch (HIWORD(wParam))
{
case CBN_SELCHANGE:
switch (LOWORD(wParam)) {
switch (LOWORD(wParam))
{
case IDC_COMBO_API1:
case IDC_COMBO_API2:
port = (LOWORD(wParam) == IDC_COMBO_API1) ? 1 : 0;
@ -168,7 +173,8 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
break;
case BN_CLICKED:
switch(LOWORD(wParam)) {
switch (LOWORD(wParam))
{
case IDC_CONFIGURE1:
case IDC_CONFIGURE2:
{
@ -227,13 +233,17 @@ BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
EXPORT_C_(BOOL) AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch(uMsg) {
EXPORT_C_(BOOL)
AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam)) {
switch (LOWORD(wParam))
{
case IDOK:
EndDialog(hW, FALSE);
return TRUE;
@ -242,7 +252,8 @@ EXPORT_C_(BOOL) AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
return FALSE;
}
void USBconfigure() {
void USBconfigure()
{
ScopedCoreThreadPause paused_core;
RegisterDevice::Register();
DialogBox(hInst,
@ -252,7 +263,9 @@ void USBconfigure() {
paused_core.AllowResume();
}
EXPORT_C_(void) USBabout() {
EXPORT_C_(void)
USBabout()
{
DialogBox(hInst,
MAKEINTRESOURCE(IDD_ABOUT),
GetActiveWindow(),
@ -261,7 +274,8 @@ EXPORT_C_(void) USBabout() {
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved) {
LPVOID lpReserved)
{
hInst = (HINSTANCE)hModule;
return TRUE;
}

View File

@ -21,15 +21,16 @@ typedef struct Win32Handles
{
HINSTANCE hInst;
HWND hWnd;
Win32Handles(HINSTANCE i, HWND w):
hInst(i),
hWnd(w)
Win32Handles(HINSTANCE i, HWND w)
: hInst(i)
, hWnd(w)
{
}
} Win32Handles;
#define CHECKED_SET_MAX_INT(var, hDlg, nIDDlgItem, bSigned, min, max) \
do {\
do \
{ \
/*CheckControlTextIsNumber(GetDlgItem(hDlg, nIDDlgItem), bSigned, 0);*/ \
var = GetDlgItemInt(hDlg, nIDDlgItem, NULL, bSigned); \
if (var < min) \

View File

@ -51,7 +51,8 @@ bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TC
{
CIniKey* key;
auto sect = ciniFile.GetSection(str_to_wstr(section));
if (sect && (key = sect->GetKey(str_to_wstr(param)))) {
if (sect && (key = sect->GetKey(str_to_wstr(param))))
{
value = wstr_to_str(key->GetValue());
return true;
}
@ -62,12 +63,15 @@ bool LoadSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TC
{
CIniKey* key;
auto sect = ciniFile.GetSection(str_to_wstr(section));
if (sect && (key = sect->GetKey(str_to_wstr(param)))) {
try {
if (sect && (key = sect->GetKey(str_to_wstr(param))))
{
try
{
value = std::stoi(key->GetValue());
return true;
}
catch (std::exception& err) {
catch (std::exception& err)
{
OSDebugOut(TEXT("%" SFMTs "\n"), err.what());
}
}
@ -86,7 +90,8 @@ bool SaveSettingValue(const TSTDSTRING& ini, const TSTDSTRING& section, const TC
return true;
}
void SaveConfig() {
void SaveConfig()
{
SaveSetting("MAIN", "log", conf.Log);
@ -105,8 +110,10 @@ void SaveConfig() {
OSDebugOut(_T("ciniFile.Save: %d [%s]\n"), ret, IniPath.c_str());
}
void LoadConfig() {
std::cerr << "USB load config\n" << std::endl;
void LoadConfig()
{
std::cerr << "USB load config\n"
<< std::endl;
ciniFile.Load(str_to_wstr(IniPath));
LoadSetting("MAIN", "log", conf.Log);
@ -149,7 +156,8 @@ void LoadConfig() {
void ClearSection(const TCHAR* section)
{
auto s = ciniFile.GetSection(str_to_wstr(section));
if (s) {
if (s)
{
s->RemoveAllKeys();
}
}

View File

@ -54,7 +54,8 @@
#define PLAYER_ONE_PORT 1
#define USB_PORT PLAYER_ONE_PORT
struct Config {
struct Config
{
int Log;
std::string Port[2];
int WheelType[2];

View File

@ -46,15 +46,22 @@ enum DeviceType
DEVTYPE_EYETOY,
};
struct SelectDeviceName {
struct SelectDeviceName
{
template <typename S>
std::string operator()(const std::pair<const DeviceType, S> &x) const { return x.second->TypeName(); }
std::string operator()(const std::pair<const DeviceType, S>& x) const
{
return x.second->TypeName();
}
};
class DeviceError : public std::runtime_error
{
public:
DeviceError(const char* msg) : std::runtime_error(msg) {}
DeviceError(const char* msg)
: std::runtime_error(msg)
{
}
virtual ~DeviceError() {}
};
@ -128,12 +135,17 @@ class RegisterProxy
public:
typedef std::map<std::string, std::unique_ptr<T>> RegisterProxyMap;
static RegisterProxy& instance() {
static RegisterProxy& instance()
{
static RegisterProxy registerProxy;
return registerProxy;
}
virtual ~RegisterProxy() { Clear(); OSDebugOut("%p\n", this); }
virtual ~RegisterProxy()
{
Clear();
OSDebugOut("%p\n", this);
}
void Clear()
{
@ -186,7 +198,8 @@ class RegisterDevice
public:
typedef std::map<DeviceType, std::unique_ptr<DeviceProxyBase>> RegisterDeviceMap;
static RegisterDevice& instance() {
static RegisterDevice& instance()
{
if (!registerDevice)
registerDevice = new RegisterDevice();
return *registerDevice;
@ -211,8 +224,7 @@ class RegisterDevice
return nullptr;*/
auto proxy = std::find_if(registerDeviceMap.begin(),
registerDeviceMap.end(),
[&name](const RegisterDeviceMap::value_type& val) -> bool
{
[&name](const RegisterDeviceMap::value_type& val) -> bool {
return val.second->TypeName() == name;
});
if (proxy != registerDeviceMap.end())
@ -233,8 +245,7 @@ class RegisterDevice
{
auto proxy = std::find_if(registerDeviceMap.begin(),
registerDeviceMap.end(),
[&name](RegisterDeviceMap::value_type& val) -> bool
{
[&name](RegisterDeviceMap::value_type& val) -> bool {
return val.second->TypeName() == name;
});
if (proxy != registerDeviceMap.end())

View File

@ -15,4 +15,3 @@
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#include <gtk/gtk.h>

View File

@ -16,9 +16,13 @@
#ifndef HELPERS_H
#define HELPERS_H
struct SelectKey {
struct SelectKey
{
template <typename F, typename S>
F operator()(const std::pair<const F, S> &x) const { return x.first; }
F operator()(const std::pair<const F, S>& x) const
{
return x.first;
}
};
#endif

View File

@ -15,68 +15,580 @@
#include "icon_buzz_24.h"
const unsigned char icon_buzz_24[]{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xa6, 0xf5,
0xfd, 0xff, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xfd,
0xfd, 0xff, 0xfd, 0xf6, 0xa6, 0x39, 0x00, 0x00, 0x00,
0x00, 0x00, 0x50, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xd6, 0x50, 0x00, 0x00, 0x00, 0x1e, 0xce,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xce, 0x1e, 0x00, 0x00, 0x8b, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8b, 0x00,
0x11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x5e, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x5e, 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, 0x5e, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x5e, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
0x00, 0x8b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x8b, 0x00, 0x00, 0x1e, 0xce,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xce, 0x1e, 0x00, 0x00, 0x00, 0x50, 0xd6, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xd6, 0x50, 0x00, 0x00,
0x00, 0x00, 0x00, 0x39, 0xa6, 0xf0, 0xfd, 0xff, 0xfe,
0xfe, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xfd,
0xf0, 0xa6, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x39,
0xa6,
0xf5,
0xfd,
0xff,
0xfd,
0xfe,
0xfe,
0xff,
0xff,
0xff,
0xfd,
0xfd,
0xff,
0xfd,
0xf6,
0xa6,
0x39,
0x00,
0x00,
0x00,
0x00,
0x00,
0x50,
0xd6,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xd6,
0x50,
0x00,
0x00,
0x00,
0x1e,
0xce,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xce,
0x1e,
0x00,
0x00,
0x8b,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x8b,
0x00,
0x11,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x11,
0x5e,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x5e,
0xe4,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xe4,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xe4,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xe4,
0x5e,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x5e,
0x11,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x11,
0x00,
0x8b,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0x8b,
0x00,
0x00,
0x1e,
0xce,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xce,
0x1e,
0x00,
0x00,
0x00,
0x50,
0xd6,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xd6,
0x50,
0x00,
0x00,
0x00,
0x00,
0x00,
0x39,
0xa6,
0xf0,
0xfd,
0xff,
0xfe,
0xfe,
0xff,
0xff,
0xff,
0xff,
0xfe,
0xfe,
0xff,
0xfd,
0xf0,
0xa6,
0x39,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};

View File

@ -203,7 +203,8 @@ static GtkWidget* new_frame(const char *label, GtkWidget *box)
}
void USBconfigure() {
void USBconfigure()
{
ScopedCoreThreadPause paused_core;
RegisterDevice::Register();
@ -319,5 +320,6 @@ void USBconfigure() {
paused_core.AllowResume();
}
void CALLBACK USBabout() {
void CALLBACK USBabout()
{
}

View File

@ -15,7 +15,8 @@
#include "osdebugout.h"
std::wostream& operator<<(std::wostream& os, const std::string& s) {
std::wostream& operator<<(std::wostream& os, const std::string& s)
{
std::wstring ws;
ws.assign(s.begin(), s.end());
return os << ws;

View File

@ -31,23 +31,59 @@ std::wostream& operator<<(std::wostream& os, const std::string& s);
#ifdef _DEBUG
#define OSDebugOut(psz_fmt, ...) _OSDebugOut(TEXT("[USBqemu] [%" SFMTs "]:%d\t") psz_fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define OSDebugOut_noprfx(psz_fmt, ...) _OSDebugOut(TEXT(psz_fmt), ##__VA_ARGS__)
#define OSDebugOutStream_noprfx(psz_str) do{ TSTDSTRINGSTREAM ss; ss << psz_str; _OSDebugOut(_T("%s\n"), ss.str().c_str()); }while(0)
#define OSDebugOutStream_noprfx(psz_str) \
do \
{ \
TSTDSTRINGSTREAM ss; \
ss << psz_str; \
_OSDebugOut(_T("%s\n"), ss.str().c_str()); \
} while (0)
#else
#define OSDebugOut(psz_fmt, ...) do{}while(0)
#define OSDebugOut_noprfx(psz_fmt, ...) do{}while(0)
#define OSDebugOutStream_noprfx(str) do{}while(0)
#define OSDebugOut(psz_fmt, ...) \
do \
{ \
} while (0)
#define OSDebugOut_noprfx(psz_fmt, ...) \
do \
{ \
} while (0)
#define OSDebugOutStream_noprfx(str) \
do \
{ \
} while (0)
#endif
#else //_WIN32
#ifdef _DEBUG
#define OSDebugOut(psz_fmt, ...) do{ fprintf(stderr, "[USBqemu] [%s]:%d\t" psz_fmt, __func__, __LINE__, ##__VA_ARGS__); }while(0)
#define OSDebugOut_noprfx(psz_fmt, ...) do{ fprintf(stderr, psz_fmt, ##__VA_ARGS__); }while(0)
#define OSDebugOutStream_noprfx(str) do{ std::cerr << str << std::endl; }while(0)
#define OSDebugOut(psz_fmt, ...) \
do \
{ \
fprintf(stderr, "[USBqemu] [%s]:%d\t" psz_fmt, __func__, __LINE__, ##__VA_ARGS__); \
} while (0)
#define OSDebugOut_noprfx(psz_fmt, ...) \
do \
{ \
fprintf(stderr, psz_fmt, ##__VA_ARGS__); \
} while (0)
#define OSDebugOutStream_noprfx(str) \
do \
{ \
std::cerr << str << std::endl; \
} while (0)
#else
#define OSDebugOut(psz_fmt, ...) do{}while(0)
#define OSDebugOut_noprfx(psz_fmt, ...) do{}while(0)
#define OSDebugOutStream_noprfx(str) do{}while(0)
#define OSDebugOut(psz_fmt, ...) \
do \
{ \
} while (0)
#define OSDebugOut_noprfx(psz_fmt, ...) \
do \
{ \
} while (0)
#define OSDebugOutStream_noprfx(str) \
do \
{ \
} while (0)
#endif
#endif //_WIN32

View File

@ -99,8 +99,7 @@ errno_t mbstowcs_s(
size_t* pReturnValue,
wchar_t (&wcstr)[size],
const char* mbstr,
size_t count
)
size_t count)
{
return mbstowcs_s(pReturnValue, wcstr, size, mbstr, count);
}
@ -110,8 +109,7 @@ errno_t wcstombs_s(
size_t* pReturnValue,
char (&mbstr)[size],
const wchar_t* wcstr,
size_t count
)
size_t count)
{
return wcstombs_s(pReturnValue, mbstr, size, wcstr, count);
}

View File

@ -25,20 +25,22 @@
/* Number of Downstream Ports on the root hub. */
#define OHCI_MAX_PORTS 15 // status regs from 0x0c54 but usb snooping
#define OHCI_MAX_PORTS 15 // status regs from 0x0c54 but usb snooping \
// reg is at 0x0c80, so only 11 ports?
extern int64_t usb_frame_time;
extern int64_t usb_bit_time;
typedef struct OHCIPort {
typedef struct OHCIPort
{
USBPort port;
uint32_t ctrl;
} OHCIPort;
typedef uint32_t target_phys_addr_t;
typedef struct OHCIState {
typedef struct OHCIState
{
target_phys_addr_t mem_base;
int mem;
uint32_t num_ports;
@ -85,7 +87,8 @@ typedef struct OHCIState {
} OHCIState;
/* Host Controller Communications Area */
struct ohci_hcca {
struct ohci_hcca
{
uint32_t intr[32];
uint16_t frame, pad;
uint32_t done;
@ -165,13 +168,16 @@ struct ohci_hcca {
#define OHCI_BM(val, field) \
(((val)&OHCI_##field##_MASK) >> OHCI_##field##_SHIFT)
#define OHCI_SET_BM(val, field, newval) do { \
#define OHCI_SET_BM(val, field, newval) \
do \
{ \
val &= ~OHCI_##field##_MASK; \
val |= ((newval) << OHCI_##field##_SHIFT) & OHCI_##field##_MASK; \
} while (0)
/* endpoint descriptor */
struct ohci_ed {
struct ohci_ed
{
uint32_t flags;
uint32_t tail;
uint32_t head;
@ -179,7 +185,8 @@ struct ohci_ed {
};
/* General transfer descriptor */
struct ohci_td {
struct ohci_td
{
uint32_t flags;
uint32_t cbp;
uint32_t next;
@ -187,7 +194,8 @@ struct ohci_td {
};
/* Isochronous transfer descriptor */
struct ohci_iso_td {
struct ohci_iso_td
{
uint32_t flags;
uint32_t bp;
uint32_t next;
@ -268,8 +276,7 @@ struct ohci_iso_td {
#define OHCI_PORT_PSSC (1 << 18)
#define OHCI_PORT_OCIC (1 << 19)
#define OHCI_PORT_PRSC (1 << 20)
#define OHCI_PORT_WTC (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \
|OHCI_PORT_OCIC|OHCI_PORT_PRSC)
#define OHCI_PORT_WTC (OHCI_PORT_CSC | OHCI_PORT_PESC | OHCI_PORT_PSSC | OHCI_PORT_OCIC | OHCI_PORT_PRSC)
#define OHCI_TD_DIR_SETUP 0x0
#define OHCI_TD_DIR_OUT 0x1

View File

@ -22,7 +22,8 @@ static void usb_device_realize(USBDevice *dev/*, Error **errp*/)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->realize) {
if (klass->realize)
{
klass->realize(dev /*, errp*/);
}
}
@ -30,7 +31,8 @@ static void usb_device_realize(USBDevice *dev/*, Error **errp*/)
USBDevice* usb_device_find_device(USBDevice* dev, uint8_t addr)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->find_device) {
if (klass->find_device)
{
return klass->find_device(dev, addr);
}
return NULL;
@ -40,7 +42,8 @@ static void usb_device_unrealize(USBDevice *dev/*, Error **errp*/)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->unrealize) {
if (klass->unrealize)
{
klass->unrealize(dev /*, errp*/);
}
}
@ -48,7 +51,8 @@ static void usb_device_unrealize(USBDevice *dev/*, Error **errp*/)
void usb_device_cancel_packet(USBDevice* dev, USBPacket* p)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->cancel_packet) {
if (klass->cancel_packet)
{
klass->cancel_packet(dev, p);
}
}
@ -56,7 +60,8 @@ void usb_device_cancel_packet(USBDevice *dev, USBPacket *p)
void usb_device_handle_attach(USBDevice* dev)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->handle_attach) {
if (klass->handle_attach)
{
klass->handle_attach(dev);
}
}
@ -64,7 +69,8 @@ void usb_device_handle_attach(USBDevice *dev)
void usb_device_handle_reset(USBDevice* dev)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->handle_reset) {
if (klass->handle_reset)
{
klass->handle_reset(dev);
}
}
@ -73,7 +79,8 @@ void usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
int value, int index, int length, uint8_t* data)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->handle_control) {
if (klass->handle_control)
{
klass->handle_control(dev, p, request, value, index, length, data);
}
}
@ -81,7 +88,8 @@ void usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
void usb_device_handle_data(USBDevice* dev, USBPacket* p)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->handle_data) {
if (klass->handle_data)
{
klass->handle_data(dev, p);
}
}
@ -95,7 +103,8 @@ void usb_device_handle_data(USBDevice *dev, USBPacket *p)
const USBDesc* usb_device_get_usb_desc(USBDevice* dev)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (dev->usb_desc) {
if (dev->usb_desc)
{
return dev->usb_desc;
}
return klass->usb_desc;
@ -105,7 +114,8 @@ void usb_device_set_interface(USBDevice *dev, int intf,
int alt_old, int alt_new)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->set_interface) {
if (klass->set_interface)
{
klass->set_interface(dev, intf, alt_old, alt_new);
}
}
@ -113,7 +123,8 @@ void usb_device_set_interface(USBDevice *dev, int intf,
void usb_device_flush_ep_queue(USBDevice* dev, USBEndpoint* ep)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->flush_ep_queue) {
if (klass->flush_ep_queue)
{
klass->flush_ep_queue(dev, ep);
}
}
@ -121,7 +132,8 @@ void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
void usb_device_ep_stopped(USBDevice* dev, USBEndpoint* ep)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->ep_stopped) {
if (klass->ep_stopped)
{
klass->ep_stopped(dev, ep);
}
}
@ -130,7 +142,8 @@ int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
int streams)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->alloc_streams) {
if (klass->alloc_streams)
{
return klass->alloc_streams(dev, eps, nr_eps, streams);
}
return 0;
@ -139,7 +152,8 @@ int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps,
void usb_device_free_streams(USBDevice* dev, USBEndpoint** eps, int nr_eps)
{
USBDeviceClass* klass = USB_DEVICE_GET_CLASS(dev);
if (klass->free_streams) {
if (klass->free_streams)
{
klass->free_streams(dev, eps, nr_eps);
}
}

View File

@ -40,9 +40,11 @@ void usb_pick_speed(USBPort *port)
USBDevice* udev = port->dev;
int i;
for (i = 0; i < (int)ARRAY_SIZE(speeds); i++) {
for (i = 0; i < (int)ARRAY_SIZE(speeds); i++)
{
if ((udev->speedmask & (1 << speeds[i])) &&
(port->speedmask & (1 << speeds[i]))) {
(port->speedmask & (1 << speeds[i])))
{
udev->speed = speeds[i];
return;
}
@ -91,7 +93,8 @@ void usb_port_reset(USBPort *port)
void usb_device_reset(USBDevice* dev)
{
if (dev == NULL || !dev->attached) {
if (dev == NULL || !dev->attached)
{
return;
}
dev->remote_wakeup = 0;
@ -105,10 +108,12 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
USBDevice* dev = ep->dev;
USBBus* bus = dev->bus; //usb_bus_from_device(dev);
if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup)
{
dev->port->ops->wakeup(dev->port);
}
if (bus && bus->ops->wakeup_endpoint) {
if (bus && bus->ops->wakeup_endpoint)
{
bus->ops->wakeup_endpoint(bus, ep, stream);
}
}
@ -130,7 +135,8 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
{
int request, value, index;
if (p->iov.size != 8) {
if (p->iov.size != 8)
{
p->status = USB_RET_STALL;
return;
}
@ -139,7 +145,8 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
s->setup_index = 0;
p->actual_length = 0;
s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
if (s->setup_len > (int32_t)sizeof(s->data_buf)) {
if (s->setup_len > (int32_t)sizeof(s->data_buf))
{
fprintf(stderr,
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
s->setup_len, sizeof(s->data_buf));
@ -151,21 +158,27 @@ static void do_token_setup(USBDevice *s, USBPacket *p)
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
index = (s->setup_buf[5] << 8) | s->setup_buf[4];
if (s->setup_buf[0] & USB_DIR_IN) {
if (s->setup_buf[0] & USB_DIR_IN)
{
usb_device_handle_control(s, p, request, value, index,
s->setup_len, s->data_buf);
if (p->status == USB_RET_ASYNC) {
if (p->status == USB_RET_ASYNC)
{
s->setup_state = SETUP_STATE_SETUP;
}
if (p->status != USB_RET_SUCCESS) {
if (p->status != USB_RET_SUCCESS)
{
return;
}
if (p->actual_length < s->setup_len) {
if (p->actual_length < s->setup_len)
{
s->setup_len = p->actual_length;
}
s->setup_state = SETUP_STATE_DATA;
} else {
}
else
{
if (s->setup_len == 0)
s->setup_state = SETUP_STATE_ACK;
else
@ -185,12 +198,15 @@ static void do_token_in(USBDevice *s, USBPacket *p)
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
index = (s->setup_buf[5] << 8) | s->setup_buf[4];
switch(s->setup_state) {
switch (s->setup_state)
{
case SETUP_STATE_ACK:
if (!(s->setup_buf[0] & USB_DIR_IN)) {
if (!(s->setup_buf[0] & USB_DIR_IN))
{
usb_device_handle_control(s, p, request, value, index,
s->setup_len, s->data_buf);
if (p->status == USB_RET_ASYNC) {
if (p->status == USB_RET_ASYNC)
{
return;
}
s->setup_state = SETUP_STATE_IDLE;
@ -199,14 +215,17 @@ static void do_token_in(USBDevice *s, USBPacket *p)
break;
case SETUP_STATE_DATA:
if (s->setup_buf[0] & USB_DIR_IN) {
if (s->setup_buf[0] & USB_DIR_IN)
{
int len = s->setup_len - s->setup_index;
if ((size_t)len > p->iov.size) {
if ((size_t)len > p->iov.size)
{
len = p->iov.size;
}
usb_packet_copy(p, s->data_buf + s->setup_index, len);
s->setup_index += len;
if (s->setup_index >= s->setup_len) {
if (s->setup_index >= s->setup_len)
{
s->setup_state = SETUP_STATE_ACK;
}
return;
@ -224,25 +243,32 @@ static void do_token_out(USBDevice *s, USBPacket *p)
{
assert(p->ep->nr == 0);
switch(s->setup_state) {
switch (s->setup_state)
{
case SETUP_STATE_ACK:
if (s->setup_buf[0] & USB_DIR_IN) {
if (s->setup_buf[0] & USB_DIR_IN)
{
s->setup_state = SETUP_STATE_IDLE;
/* transfer OK */
} else {
}
else
{
/* ignore additional output */
}
break;
case SETUP_STATE_DATA:
if (!(s->setup_buf[0] & USB_DIR_IN)) {
if (!(s->setup_buf[0] & USB_DIR_IN))
{
int len = s->setup_len - s->setup_index;
if ((size_t)len > p->iov.size) {
if ((size_t)len > p->iov.size)
{
len = p->iov.size;
}
usb_packet_copy(p, s->data_buf + s->setup_index, len);
s->setup_index += len;
if (s->setup_index >= s->setup_len) {
if (s->setup_index >= s->setup_len)
{
s->setup_state = SETUP_STATE_ACK;
}
return;
@ -260,7 +286,8 @@ static void do_parameter(USBDevice *s, USBPacket *p)
{
int i, request, value, index;
for (i = 0; i < 8; i++) {
for (i = 0; i < 8; i++)
{
s->setup_buf[i] = p->parameter >> (i * 8);
}
@ -272,7 +299,8 @@ static void do_parameter(USBDevice *s, USBPacket *p)
value = (s->setup_buf[3] << 8) | s->setup_buf[2];
index = (s->setup_buf[5] << 8) | s->setup_buf[4];
if (s->setup_len > (int32_t)sizeof(s->data_buf)) {
if (s->setup_len > (int32_t)sizeof(s->data_buf))
{
fprintf(stderr,
"usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
s->setup_len, sizeof(s->data_buf));
@ -280,20 +308,24 @@ static void do_parameter(USBDevice *s, USBPacket *p)
return;
}
if (p->pid == USB_TOKEN_OUT) {
if (p->pid == USB_TOKEN_OUT)
{
usb_packet_copy(p, s->data_buf, s->setup_len);
}
usb_device_handle_control(s, p, request, value, index,
s->setup_len, s->data_buf);
if (p->status == USB_RET_ASYNC) {
if (p->status == USB_RET_ASYNC)
{
return;
}
if (p->actual_length < s->setup_len) {
if (p->actual_length < s->setup_len)
{
s->setup_len = p->actual_length;
}
if (p->pid == USB_TOKEN_IN) {
if (p->pid == USB_TOKEN_IN)
{
p->actual_length = 0;
usb_packet_copy(p, s->data_buf, s->setup_len);
}
@ -305,13 +337,16 @@ static void do_parameter(USBDevice *s, USBPacket *p)
usb_packet_complete to complete their async control packets. */
void usb_generic_async_ctrl_complete(USBDevice* s, USBPacket* p)
{
if (p->status < 0) {
if (p->status < 0)
{
s->setup_state = SETUP_STATE_IDLE;
}
switch (s->setup_state) {
switch (s->setup_state)
{
case SETUP_STATE_SETUP:
if (p->actual_length < s->setup_len) {
if (p->actual_length < s->setup_len)
{
s->setup_len = p->actual_length;
}
s->setup_state = SETUP_STATE_DATA;
@ -324,10 +359,12 @@ void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p)
break;
case SETUP_STATE_PARAM:
if (p->actual_length < s->setup_len) {
if (p->actual_length < s->setup_len)
{
s->setup_len = p->actual_length;
}
if (p->pid == USB_TOKEN_IN) {
if (p->pid == USB_TOKEN_IN)
{
p->actual_length = 0;
usb_packet_copy(p, s->data_buf, s->setup_len);
}
@ -343,10 +380,12 @@ USBDevice *usb_find_device(USBPort *port, uint8_t addr)
{
USBDevice* dev = port->dev;
if (dev == NULL || !dev->attached || dev->state != USB_STATE_DEFAULT) {
if (dev == NULL || !dev->attached || dev->state != USB_STATE_DEFAULT)
{
return NULL;
}
if (dev->addr == addr) {
if (dev->addr == addr)
{
return dev;
}
return usb_device_find_device(dev, addr);
@ -363,13 +402,16 @@ static void usb_process_one(USBPacket *p)
*/
p->status = USB_RET_SUCCESS;
if (p->ep->nr == 0) {
if (p->ep->nr == 0)
{
/* control pipe */
if (p->parameter) {
if (p->parameter)
{
do_parameter(dev, p);
return;
}
switch (p->pid) {
switch (p->pid)
{
case USB_TOKEN_SETUP:
do_token_setup(dev, p);
break;
@ -382,7 +424,9 @@ static void usb_process_one(USBPacket *p)
default:
p->status = USB_RET_STALL;
}
} else {
}
else
{
/* data pipe */
usb_device_handle_data(dev, p);
}
@ -400,7 +444,8 @@ static void usb_queue_one(USBPacket *p)
driver will call usb_packet_complete() when done processing it. */
void usb_handle_packet(USBDevice* dev, USBPacket* p)
{
if (dev == NULL) {
if (dev == NULL)
{
p->status = USB_RET_NODEV;
return;
}
@ -410,14 +455,17 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
assert(p->ep != NULL);
/* Submitting a new packet clears halt */
if (p->ep->halted) {
if (p->ep->halted)
{
assert(QTAILQ_EMPTY(&p->ep->queue));
p->ep->halted = false;
}
if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline || p->stream) {
if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline || p->stream)
{
usb_process_one(p);
if (p->status == USB_RET_ASYNC) {
if (p->status == USB_RET_ASYNC)
{
/* hcd drivers cannot handle async for isoc */
assert(p->ep->type != USB_ENDPOINT_XFER_ISOC);
/* using async for interrupt packets breaks migration */
@ -425,20 +473,27 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
(dev->flags & (1 << USB_DEV_FLAG_IS_HOST)));
usb_packet_set_state(p, USB_PACKET_ASYNC);
QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
} else if (p->status == USB_RET_ADD_TO_QUEUE) {
}
else if (p->status == USB_RET_ADD_TO_QUEUE)
{
usb_queue_one(p);
} else {
}
else
{
/*
* When pipelining is enabled usb-devices must always return async,
* otherwise packets can complete out of order!
*/
assert(p->stream || !p->ep->pipeline ||
QTAILQ_EMPTY(&p->ep->queue));
if (p->status != USB_RET_NAK) {
if (p->status != USB_RET_NAK)
{
usb_packet_set_state(p, USB_PACKET_COMPLETE);
}
}
} else {
}
else
{
usb_queue_one(p);
}
}
@ -451,7 +506,8 @@ void usb_packet_complete_one(USBDevice *dev, USBPacket *p)
assert(p->status != USB_RET_ASYNC && p->status != USB_RET_NAK);
if (p->status != USB_RET_SUCCESS ||
(p->short_not_ok && ((size_t)p->actual_length < p->iov.size))) {
(p->short_not_ok && ((size_t)p->actual_length < p->iov.size)))
{
ep->halted = true;
}
usb_packet_set_state(p, USB_PACKET_COMPLETE);
@ -469,20 +525,24 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
usb_packet_check_state(p, USB_PACKET_ASYNC);
usb_packet_complete_one(dev, p);
while (!QTAILQ_EMPTY(&ep->queue)) {
while (!QTAILQ_EMPTY(&ep->queue))
{
p = QTAILQ_FIRST(&ep->queue);
if (ep->halted) {
if (ep->halted)
{
/* Empty the queue on a halt */
p->status = USB_RET_REMOVE_FROM_QUEUE;
dev->port->ops->complete(dev->port, p);
continue;
}
if (p->state == USB_PACKET_ASYNC) {
if (p->state == USB_PACKET_ASYNC)
{
break;
}
usb_packet_check_state(p, USB_PACKET_QUEUED);
usb_process_one(p);
if (p->status == USB_RET_ASYNC) {
if (p->status == USB_RET_ASYNC)
{
usb_packet_set_state(p, USB_PACKET_ASYNC);
break;
}
@ -499,7 +559,8 @@ void usb_cancel_packet(USBPacket * p)
assert(usb_packet_is_inflight(p));
usb_packet_set_state(p, USB_PACKET_CANCELED);
QTAILQ_REMOVE(&p->ep->queue, p, queue);
if (callback) {
if (callback)
{
usb_device_cancel_packet(p->ep->dev, p);
}
}
@ -520,7 +581,8 @@ static const char *usb_packet_state_name(USBPacketState state)
/*[USB_PACKET_COMPLETE] =*/"complete",
/*[USB_PACKET_CANCELED] =*/"canceled",
};
if (state < ARRAY_SIZE(name)) {
if (state < ARRAY_SIZE(name))
{
return name[state];
}
return "INVALID";
@ -528,7 +590,8 @@ static const char *usb_packet_state_name(USBPacketState state)
void usb_packet_check_state(USBPacket* p, USBPacketState expected)
{
if (p->state == expected) {
if (p->state == expected)
{
return;
}
//trace_usb_packet_state_fault(bus->busnr, dev->port->path, p->ep->nr, p,
@ -585,7 +648,8 @@ void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes)
assert(bytes <= INT_MAX);
assert(p->actual_length >= 0);
assert(p->actual_length + bytes <= iov->size);
switch (p->pid) {
switch (p->pid)
{
case USB_TOKEN_SETUP:
case USB_TOKEN_OUT:
iov_to_buf(iov->iov, iov->niov, p->actual_length, ptr, bytes);
@ -607,7 +671,8 @@ void usb_packet_skip(USBPacket *p, size_t bytes)
assert(bytes <= INT_MAX);
assert(p->actual_length >= 0);
assert(p->actual_length + bytes <= iov->size);
if (p->pid == USB_TOKEN_IN) {
if (p->pid == USB_TOKEN_IN)
{
iov_memset(iov->iov, iov->niov, p->actual_length, 0, bytes);
}
p->actual_length += bytes;
@ -635,7 +700,8 @@ void usb_ep_reset(USBDevice *dev)
dev->ep_ctl.max_streams = 0;
dev->ep_ctl.dev = dev;
dev->ep_ctl.pipeline = false;
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++)
{
dev->ep_in[ep].nr = ep + 1;
dev->ep_out[ep].nr = ep + 1;
dev->ep_in[ep].pid = USB_TOKEN_IN;
@ -661,7 +727,8 @@ void usb_ep_init(USBDevice *dev)
usb_ep_reset(dev);
QTAILQ_INIT(&dev->ep_ctl.queue);
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++)
{
QTAILQ_INIT(&dev->ep_in[ep].queue);
QTAILQ_INIT(&dev->ep_out[ep].queue);
}
@ -679,12 +746,16 @@ void usb_ep_dump(USBDevice *dev)
fprintf(stderr, "Device \"%s\", config %d\n",
dev->product_desc, dev->configuration);
for (ifnum = 0; ifnum < 16; ifnum++) {
for (ifnum = 0; ifnum < 16; ifnum++)
{
first = 1;
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++)
{
if (dev->ep_in[ep].type != USB_ENDPOINT_XFER_INVALID &&
dev->ep_in[ep].ifnum == ifnum) {
if (first) {
dev->ep_in[ep].ifnum == ifnum)
{
if (first)
{
first = 0;
fprintf(stderr, " Interface %d, alternative %d\n",
ifnum, dev->altsetting[ifnum]);
@ -694,8 +765,10 @@ void usb_ep_dump(USBDevice *dev)
dev->ep_in[ep].max_packet_size);
}
if (dev->ep_out[ep].type != USB_ENDPOINT_XFER_INVALID &&
dev->ep_out[ep].ifnum == ifnum) {
if (first) {
dev->ep_out[ep].ifnum == ifnum)
{
if (first)
{
first = 0;
fprintf(stderr, " Interface %d, alternative %d\n",
ifnum, dev->altsetting[ifnum]);
@ -713,11 +786,13 @@ struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
{
struct USBEndpoint* eps;
if (dev == NULL) {
if (dev == NULL)
{
return NULL;
}
eps = (pid == USB_TOKEN_IN) ? dev->ep_in : dev->ep_out;
if (ep == 0) {
if (ep == 0)
{
return &dev->ep_ctl;
}
assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
@ -750,7 +825,8 @@ void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
int size, microframes;
size = raw & 0x7ff;
switch ((raw >> 11) & 3) {
switch ((raw >> 11) & 3)
{
case 1:
microframes = 2;
break;
@ -770,9 +846,12 @@ void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw)
int MaxStreams;
MaxStreams = raw & 0x1f;
if (MaxStreams) {
if (MaxStreams)
{
uep->max_streams = 1 << MaxStreams;
} else {
}
else
{
uep->max_streams = 0;
}
}
@ -789,8 +868,10 @@ USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
struct USBEndpoint* uep = usb_ep_get(dev, pid, ep);
USBPacket* p;
QTAILQ_FOREACH(p, &uep->queue, queue) {
if (p->id == id) {
QTAILQ_FOREACH(p, &uep->queue, queue)
{
if (p->id == id)
{
return p;
}
}
@ -800,7 +881,8 @@ USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
void usb_wakeup(USBDevice* dev)
{
if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup)
{
dev->port->ops->wakeup(dev->port);
}
}

View File

@ -27,14 +27,16 @@ int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
uint8_t bLength = 0x12;
USBDescriptor* d = (USBDescriptor*)dest;
if (len < bLength) {
if (len < bLength)
{
return -1;
}
d->bLength = bLength;
d->bDescriptorType = USB_DT_DEVICE;
if (msos && dev->bcdUSB < 0x0200) {
if (msos && dev->bcdUSB < 0x0200)
{
/*
* Version 2.0+ required for microsoft os descriptors to work.
* Done this way so msos-desc compat property will handle both
@ -42,7 +44,9 @@ int usb_desc_device(const USBDescID *id, const USBDescDevice *dev,
*/
d->u.device.bcdUSB_lo = usb_lo(0x0200);
d->u.device.bcdUSB_hi = usb_hi(0x0200);
} else {
}
else
{
d->u.device.bcdUSB_lo = usb_lo(dev->bcdUSB);
d->u.device.bcdUSB_hi = usb_hi(dev->bcdUSB);
}
@ -72,7 +76,8 @@ int usb_desc_device_qualifier(const USBDescDevice *dev,
uint8_t bLength = 0x0a;
USBDescriptor* d = (USBDescriptor*)dest;
if (len < bLength) {
if (len < bLength)
{
return -1;
}
@ -99,7 +104,8 @@ int usb_desc_config(const USBDescConfig& conf, int flags,
USBDescriptor* d = (USBDescriptor*)dest;
int rc;
if (len < bLength) {
if (len < bLength)
{
return -1;
}
@ -114,21 +120,25 @@ int usb_desc_config(const USBDescConfig& conf, int flags,
wTotalLength += bLength;
/* handle grouped interfaces if any */
for (auto& i : conf.if_groups) {
for (auto& i : conf.if_groups)
{
rc = usb_desc_iface_group(i, flags,
dest + wTotalLength,
len - wTotalLength);
if (rc < 0) {
if (rc < 0)
{
return rc;
}
wTotalLength += rc;
}
/* handle normal (ungrouped / no IAD) interfaces if any */
for (auto& i : conf.ifs) {
for (auto& i : conf.ifs)
{
rc = usb_desc_iface(i, flags,
dest + wTotalLength, len - wTotalLength);
if (rc < 0) {
if (rc < 0)
{
return rc;
}
wTotalLength += rc;
@ -147,7 +157,8 @@ int usb_desc_iface_group(const USBDescIfaceAssoc& iad, int flags,
/* handle interface association descriptor */
uint8_t bLength = 0x08;
if (len < bLength) {
if (len < bLength)
{
return -1;
}
@ -162,9 +173,11 @@ int usb_desc_iface_group(const USBDescIfaceAssoc& iad, int flags,
pos += bLength;
/* handle associated interfaces in this group */
for (auto& i : iad.ifs) {
for (auto& i : iad.ifs)
{
int rc = usb_desc_iface(i, flags, dest + pos, len - pos);
if (rc < 0) {
if (rc < 0)
{
return rc;
}
pos += rc;
@ -180,7 +193,8 @@ int usb_desc_iface(const USBDescIface& iface, int flags,
int rc, pos = 0;
USBDescriptor* d = (USBDescriptor*)dest;
if (len < bLength) {
if (len < bLength)
{
return -1;
}
@ -196,17 +210,21 @@ int usb_desc_iface(const USBDescIface& iface, int flags,
d->u.intf.iInterface = iface.iInterface;
pos += bLength;
for (auto& i : iface.descs) {
for (auto& i : iface.descs)
{
rc = usb_desc_other(i, dest + pos, len - pos);
if (rc < 0) {
if (rc < 0)
{
return rc;
}
pos += rc;
}
for (auto& i : iface.eps) {
for (auto& i : iface.eps)
{
rc = usb_desc_endpoint(i, flags, dest + pos, len - pos);
if (rc < 0) {
if (rc < 0)
{
return rc;
}
pos += rc;
@ -223,7 +241,8 @@ int usb_desc_endpoint(const USBDescEndpoint& ep, int flags,
uint8_t superlen = (flags & USB_DESC_FLAG_SUPER) ? 0x06 : 0;
USBDescriptor* d = (USBDescriptor*)dest;
if (len < (size_t)(bLength + extralen + superlen)) {
if (len < (size_t)(bLength + extralen + superlen))
{
return -1;
}
@ -235,12 +254,14 @@ int usb_desc_endpoint(const USBDescEndpoint& ep, int flags,
d->u.endpoint.wMaxPacketSize_lo = usb_lo(ep.wMaxPacketSize);
d->u.endpoint.wMaxPacketSize_hi = usb_hi(ep.wMaxPacketSize);
d->u.endpoint.bInterval = ep.bInterval;
if (ep.is_audio) {
if (ep.is_audio)
{
d->u.endpoint.bRefresh = ep.bRefresh;
d->u.endpoint.bSynchAddress = ep.bSynchAddress;
}
if (superlen) {
if (superlen)
{
USBDescriptor* d = (USBDescriptor*)(dest + bLength);
d->bLength = 0x06;
@ -254,7 +275,8 @@ int usb_desc_endpoint(const USBDescEndpoint& ep, int flags,
usb_hi(ep.wBytesPerInterval);
}
if (ep.extra) {
if (ep.extra)
{
memcpy(dest + bLength + superlen, ep.extra, extralen);
}
@ -265,7 +287,8 @@ int usb_desc_other(const USBDescOther& desc, uint8_t *dest, size_t len)
{
int bLength = desc.length ? desc.length : desc.data[0];
if (len < (size_t)bLength) {
if (len < (size_t)bLength)
{
return -1;
}
@ -278,7 +301,8 @@ static int usb_desc_cap_usb2_ext(const USBDesc *desc, uint8_t *dest, size_t len)
uint8_t bLength = 0x07;
USBDescriptor* d = (USBDescriptor*)dest;
if (len < bLength) {
if (len < bLength)
{
return -1;
}
@ -299,7 +323,8 @@ static int usb_desc_cap_super(const USBDesc *desc, uint8_t *dest, size_t len)
uint8_t bLength = 0x0a;
USBDescriptor* d = (USBDescriptor*)dest;
if (len < bLength) {
if (len < bLength)
{
return -1;
}
@ -315,19 +340,24 @@ static int usb_desc_cap_super(const USBDesc *desc, uint8_t *dest, size_t len)
d->u.cap.u.super.wU2DevExitLat_lo = 0x20;
d->u.cap.u.super.wU2DevExitLat_hi = 0;
if (desc->full) {
if (desc->full)
{
d->u.cap.u.super.wSpeedsSupported_lo |= (1 << 1);
d->u.cap.u.super.bFunctionalitySupport = 1;
}
if (desc->high) {
if (desc->high)
{
d->u.cap.u.super.wSpeedsSupported_lo |= (1 << 2);
if (!d->u.cap.u.super.bFunctionalitySupport) {
if (!d->u.cap.u.super.bFunctionalitySupport)
{
d->u.cap.u.super.bFunctionalitySupport = 2;
}
}
if (desc->super) {
if (desc->super)
{
d->u.cap.u.super.wSpeedsSupported_lo |= (1 << 3);
if (!d->u.cap.u.super.bFunctionalitySupport) {
if (!d->u.cap.u.super.bFunctionalitySupport)
{
d->u.cap.u.super.bFunctionalitySupport = 3;
}
}
@ -343,7 +373,8 @@ static int usb_desc_bos(const USBDesc *desc, uint8_t *dest, size_t len)
USBDescriptor* d = (USBDescriptor*)dest;
int rc;
if (len < bLength) {
if (len < bLength)
{
return -1;
}
@ -352,20 +383,24 @@ static int usb_desc_bos(const USBDesc *desc, uint8_t *dest, size_t len)
wTotalLength += bLength;
if (desc->high != NULL) {
if (desc->high != NULL)
{
rc = usb_desc_cap_usb2_ext(desc, dest + wTotalLength,
len - wTotalLength);
if (rc < 0) {
if (rc < 0)
{
return rc;
}
wTotalLength += rc;
bNumDeviceCaps++;
}
if (desc->super != NULL) {
if (desc->super != NULL)
{
rc = usb_desc_cap_super(desc, dest + wTotalLength,
len - wTotalLength);
if (rc < 0) {
if (rc < 0)
{
return rc;
}
wTotalLength += rc;
@ -516,14 +551,18 @@ static void usb_desc_ep_init(USBDevice *dev)
int i, e, pid, ep;
usb_ep_init(dev);
for (i = 0; i < dev->ninterfaces; i++) {
for (i = 0; i < dev->ninterfaces; i++)
{
iface = dev->ifaces[i];
if (iface == NULL) {
if (iface == NULL)
{
continue;
}
for (e = 0; e < iface->bNumEndpoints; e++) {
for (e = 0; e < iface->bNumEndpoints; e++)
{
pid = (iface->eps[e].bEndpointAddress & USB_DIR_IN) ?
USB_TOKEN_IN : USB_TOKEN_OUT;
USB_TOKEN_IN :
USB_TOKEN_OUT;
ep = iface->eps[e].bEndpointAddress & 0x0f;
usb_ep_set_type(dev, pid, ep, iface->eps[e].bmAttributes & 0x03);
usb_ep_set_ifnum(dev, pid, ep, iface->bInterfaceNumber);
@ -538,20 +577,26 @@ static void usb_desc_ep_init(USBDevice *dev)
static const USBDescIface* usb_desc_find_interface(USBDevice* dev,
int nif, int alt)
{
if (!dev->config) {
if (!dev->config)
{
return NULL;
}
for (auto& g : dev->config->if_groups) {
for (auto& iface : g.ifs) {
for (auto& g : dev->config->if_groups)
{
for (auto& iface : g.ifs)
{
if (iface.bInterfaceNumber == nif &&
iface.bAlternateSetting == alt) {
iface.bAlternateSetting == alt)
{
return &iface;
}
}
}
for (auto& iface : dev->config->ifs) {
for (auto& iface : dev->config->ifs)
{
if (iface.bInterfaceNumber == nif &&
iface.bAlternateSetting == alt) {
iface.bAlternateSetting == alt)
{
return &iface;
}
}
@ -565,7 +610,8 @@ int usb_desc_set_interface(USBDevice *dev, int index, int value)
int old;
iface = usb_desc_find_interface(dev, index, value);
if (iface == NULL) {
if (iface == NULL)
{
return -1;
}
@ -574,7 +620,8 @@ int usb_desc_set_interface(USBDevice *dev, int index, int value)
dev->ifaces[index] = iface;
usb_desc_ep_init(dev);
if (old != value) {
if (old != value)
{
usb_device_set_interface(dev, index, old, value);
}
return 0;
@ -585,13 +632,18 @@ int usb_desc_set_config(USBDevice *dev, int value)
{
int i;
if (value == 0) {
if (value == 0)
{
dev->configuration = 0;
dev->ninterfaces = 0;
dev->config = NULL;
} else {
for (auto& i : dev->device->confs) {
if (i.bConfigurationValue == value) {
}
else
{
for (auto& i : dev->device->confs)
{
if (i.bConfigurationValue == value)
{
dev->configuration = value;
dev->ninterfaces = i.bNumInterfaces;
dev->config = &i;
@ -603,10 +655,12 @@ int usb_desc_set_config(USBDevice *dev, int value)
}*/
}
for (i = 0; i < dev->ninterfaces; i++) {
for (i = 0; i < dev->ninterfaces; i++)
{
usb_desc_set_interface(dev, i, 0);
}
for (; i < USB_MAX_INTERFACES; i++) {
for (; i < USB_MAX_INTERFACES; i++)
{
dev->altsetting[i] = 0;
dev->ifaces[i] = NULL;
}
@ -619,7 +673,8 @@ static void usb_desc_setdefaults(USBDevice *dev)
const USBDesc* desc = usb_device_get_usb_desc(dev);
assert(desc != NULL);
switch (dev->speed) {
switch (dev->speed)
{
case USB_SPEED_LOW:
case USB_SPEED_FULL:
dev->device = desc->full;
@ -643,7 +698,8 @@ void usb_desc_init(USBDevice *dev)
assert(desc != NULL);
dev->speed = USB_SPEED_FULL;
dev->speedmask = 0;
if (desc->full) {
if (desc->full)
{
dev->speedmask |= USB_SPEED_MASK_FULL;
}
usb_desc_setdefaults(dev);
@ -659,11 +715,13 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len)
uint8_t bLength, pos, i;
const char* str;
if (len < 4) {
if (len < 4)
{
return -1;
}
if (index == 0) {
if (index == 0)
{
/* language ids */
dest[0] = 4;
dest[1] = USB_DT_STRING;
@ -673,15 +731,18 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len)
}
str = usb_device_get_usb_desc(dev)->str[index];
if (str == NULL) {
if (str == NULL)
{
return 0;
}
bLength = strlen(str) * 2 + 2;
dest[0] = bLength;
dest[1] = USB_DT_STRING;
i = 0; pos = 2;
while (pos+1 < bLength && (size_t)(pos+1) < len) {
i = 0;
pos = 2;
while (pos + 1 < bLength && (size_t)(pos + 1) < len)
{
dest[pos++] = str[i++];
dest[pos++] = 0;
}
@ -699,24 +760,30 @@ int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
uint8_t index = value & 0xff;
int flags, ret = -1;
if (dev->speed == USB_SPEED_HIGH) {
if (dev->speed == USB_SPEED_HIGH)
{
other_dev = usb_device_get_usb_desc(dev)->full;
} else {
}
else
{
other_dev = usb_device_get_usb_desc(dev)->high;
}
flags = 0;
if (dev->device->bcdUSB >= 0x0300) {
if (dev->device->bcdUSB >= 0x0300)
{
flags |= USB_DESC_FLAG_SUPER;
}
switch(type) {
switch (type)
{
case USB_DT_DEVICE:
ret = usb_desc_device(&desc->id, dev->device, msos, buf, sizeof(buf));
//trace_usb_desc_device(dev->addr, len, ret);
break;
case USB_DT_CONFIG:
if (index < dev->device->bNumConfigurations) {
if (index < dev->device->bNumConfigurations)
{
ret = usb_desc_config(dev->device->confs[index], flags,
buf, sizeof(buf));
}
@ -728,13 +795,15 @@ int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
//trace_usb_desc_string(dev->addr, index, len, ret);
break;
case USB_DT_DEVICE_QUALIFIER:
if (other_dev != NULL) {
if (other_dev != NULL)
{
ret = usb_desc_device_qualifier(other_dev, buf, sizeof(buf));
}
//trace_usb_desc_device_qualifier(dev->addr, len, ret);
break;
case USB_DT_OTHER_SPEED_CONFIG:
if (other_dev != NULL && index < other_dev->bNumConfigurations) {
if (other_dev != NULL && index < other_dev->bNumConfigurations)
{
ret = usb_desc_config(other_dev->confs[index], flags,
buf, sizeof(buf));
buf[0x01] = USB_DT_OTHER_SPEED_CONFIG;
@ -756,8 +825,10 @@ int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
break;
}
if (ret > 0) {
if ((size_t)ret > len) {
if (ret > 0)
{
if ((size_t)ret > len)
{
ret = len;
}
memcpy(dest, buf, ret);
@ -773,7 +844,8 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
assert(usb_device_get_usb_desc(dev) != NULL);
int ret = -1;
switch(request) {
switch (request)
{
case DeviceOutRequest | USB_REQ_SET_ADDRESS:
dev->addr = value;
//trace_usb_set_addr(dev->addr);
@ -798,9 +870,11 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
//trace_usb_set_config(dev->addr, value, ret);
break;
case DeviceRequest | USB_REQ_GET_STATUS: {
case DeviceRequest | USB_REQ_GET_STATUS:
{
const USBDescConfig* config = dev->config ?
dev->config : &dev->device->confs[0];
dev->config :
&dev->device->confs[0];
data[0] = 0;
/*
@ -809,10 +883,12 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
* We return the same value that a configured device would return if
* it used the first configuration.
*/
if (config->bmAttributes & USB_CFG_ATT_SELFPOWER) {
if (config->bmAttributes & USB_CFG_ATT_SELFPOWER)
{
data[0] |= 1 << USB_DEVICE_SELF_POWERED;
}
if (dev->remote_wakeup) {
if (dev->remote_wakeup)
{
data[0] |= 1 << USB_DEVICE_REMOTE_WAKEUP;
}
data[1] = 0x00;
@ -821,14 +897,16 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
break;
}
case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
if (value == USB_DEVICE_REMOTE_WAKEUP) {
if (value == USB_DEVICE_REMOTE_WAKEUP)
{
dev->remote_wakeup = 0;
ret = 0;
}
//trace_usb_clear_device_feature(dev->addr, value, ret);
break;
case DeviceOutRequest | USB_REQ_SET_FEATURE:
if (value == USB_DEVICE_REMOTE_WAKEUP) {
if (value == USB_DEVICE_REMOTE_WAKEUP)
{
dev->remote_wakeup = 1;
ret = 0;
}
@ -843,7 +921,8 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
break;
*/
case InterfaceRequest | USB_REQ_GET_INTERFACE:
if (index < 0 || index >= dev->ninterfaces) {
if (index < 0 || index >= dev->ninterfaces)
{
break;
}
data[0] = dev->altsetting[index];

View File

@ -20,11 +20,14 @@
#include "../platcompat.h"
/* binary representation */
PACK(typedef struct USBDescriptor {
PACK(
typedef struct USBDescriptor {
uint8_t bLength;
uint8_t bDescriptorType;
union {
struct {
union
{
struct
{
uint8_t bcdUSB_lo;
uint8_t bcdUSB_hi;
uint8_t bDeviceClass;
@ -42,7 +45,8 @@ PACK(typedef struct USBDescriptor {
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} device;
struct {
struct
{
uint8_t bcdUSB_lo;
uint8_t bcdUSB_hi;
uint8_t bDeviceClass;
@ -52,7 +56,8 @@ PACK(typedef struct USBDescriptor {
uint8_t bNumConfigurations;
uint8_t bReserved;
} device_qualifier;
struct {
struct
{
uint8_t wTotalLength_lo;
uint8_t wTotalLength_hi;
uint8_t bNumInterfaces;
@ -61,7 +66,8 @@ PACK(typedef struct USBDescriptor {
uint8_t bmAttributes;
uint8_t bMaxPower;
} config;
struct {
struct
{
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
@ -70,7 +76,8 @@ PACK(typedef struct USBDescriptor {
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} intf;
struct {
struct
{
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint8_t wMaxPacketSize_lo;
@ -79,27 +86,33 @@ PACK(typedef struct USBDescriptor {
uint8_t bRefresh; /* only audio ep */
uint8_t bSynchAddress; /* only audio ep */
} endpoint;
struct {
struct
{
uint8_t bMaxBurst;
uint8_t bmAttributes;
uint8_t wBytesPerInterval_lo;
uint8_t wBytesPerInterval_hi;
} super_endpoint;
struct {
struct
{
uint8_t wTotalLength_lo;
uint8_t wTotalLength_hi;
uint8_t bNumDeviceCaps;
} bos;
struct {
struct
{
uint8_t bDevCapabilityType;
union {
struct {
union
{
struct
{
uint8_t bmAttributes_1;
uint8_t bmAttributes_2;
uint8_t bmAttributes_3;
uint8_t bmAttributes_4;
} usb2_ext;
struct {
struct
{
uint8_t bmAttributes;
uint8_t wSpeedsSupported_lo;
uint8_t wSpeedsSupported_hi;
@ -111,9 +124,11 @@ PACK(typedef struct USBDescriptor {
} u;
} cap;
} u;
}, USBDescriptor);
},
USBDescriptor);
struct USBDescID {
struct USBDescID
{
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
@ -122,7 +137,8 @@ struct USBDescID {
uint8_t iSerialNumber;
};
struct USBDescDevice {
struct USBDescDevice
{
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
@ -133,7 +149,8 @@ struct USBDescDevice {
std::vector<USBDescConfig> confs;
};
struct USBDescConfig {
struct USBDescConfig
{
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
@ -150,7 +167,8 @@ struct USBDescConfig {
};
/* conceptually an Interface Association Descriptor, and releated interfaces */
struct USBDescIfaceAssoc {
struct USBDescIfaceAssoc
{
uint8_t bFirstInterface;
uint8_t bInterfaceCount;
uint8_t bFunctionClass;
@ -162,7 +180,8 @@ struct USBDescIfaceAssoc {
std::vector<USBDescIface> ifs;
};
struct USBDescIface {
struct USBDescIface
{
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
@ -176,7 +195,8 @@ struct USBDescIface {
std::vector<USBDescEndpoint> eps;
};
struct USBDescEndpoint {
struct USBDescEndpoint
{
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
@ -193,12 +213,14 @@ struct USBDescEndpoint {
uint16_t wBytesPerInterval;
};
struct USBDescOther {
struct USBDescOther
{
uint8_t length;
const uint8_t* data;
};
struct USBDescMSOS {
struct USBDescMSOS
{
const char* CompatibleID;
const wchar_t* Label;
bool SelectiveSuspendEnabled;
@ -206,7 +228,8 @@ struct USBDescMSOS {
typedef const char* USBDescStrings[256];
struct USBDesc {
struct USBDesc
{
USBDescID id;
const USBDescDevice* full;
const USBDescDevice* high;

View File

@ -28,8 +28,7 @@
*
* Returns: a pointer to the allocated memory
*/
void*
my_g_malloc (size_t n_bytes)
void* my_g_malloc(size_t n_bytes)
{
if (G_LIKELY(n_bytes))
{
@ -57,8 +56,7 @@ my_g_malloc (size_t n_bytes)
*
* Returns: a pointer to the allocated memory
*/
void*
my_g_malloc0 (size_t n_bytes)
void* my_g_malloc0(size_t n_bytes)
{
if (G_LIKELY(n_bytes))
{
@ -88,8 +86,7 @@ my_g_malloc0 (size_t n_bytes)
* Since: 2.24
* Returns: a pointer to the allocated memory
*/
void*
my_g_malloc_n (size_t n_blocks,
void* my_g_malloc_n(size_t n_blocks,
size_t n_block_bytes)
{
if (SIZE_OVERFLOWS(n_blocks, n_block_bytes))
@ -114,8 +111,7 @@ my_g_malloc_n (size_t n_blocks,
*
* Returns: the new address of the allocated memory
*/
void*
my_g_realloc (void* mem,
void* my_g_realloc(void* mem,
size_t n_bytes)
{
void* newmem;
@ -151,8 +147,7 @@ my_g_realloc (void* mem,
* Since: 2.24
* Returns: the new address of the allocated memory
*/
void*
my_g_realloc_n (void* mem,
void* my_g_realloc_n(void* mem,
size_t n_blocks,
size_t n_block_bytes)
{

View File

@ -33,39 +33,263 @@
/* Indices are QEMU keycodes, values are from HID Usage Table. Indices
* above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
static const uint8_t hid_usage_keys[0x100] = {
0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
0x5a, 0x5b, 0x62, 0x63, 0x46, 0x00, 0x64, 0x44,
0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
0x00,
0x29,
0x1e,
0x1f,
0x20,
0x21,
0x22,
0x23,
0x24,
0x25,
0x26,
0x27,
0x2d,
0x2e,
0x2a,
0x2b,
0x14,
0x1a,
0x08,
0x15,
0x17,
0x1c,
0x18,
0x0c,
0x12,
0x13,
0x2f,
0x30,
0x28,
0xe0,
0x04,
0x16,
0x07,
0x09,
0x0a,
0x0b,
0x0d,
0x0e,
0x0f,
0x33,
0x34,
0x35,
0xe1,
0x31,
0x1d,
0x1b,
0x06,
0x19,
0x05,
0x11,
0x10,
0x36,
0x37,
0x38,
0xe5,
0x55,
0xe2,
0x2c,
0x39,
0x3a,
0x3b,
0x3c,
0x3d,
0x3e,
0x3f,
0x40,
0x41,
0x42,
0x43,
0x53,
0x47,
0x5f,
0x60,
0x61,
0x56,
0x5c,
0x5d,
0x5e,
0x57,
0x59,
0x5a,
0x5b,
0x62,
0x63,
0x46,
0x00,
0x64,
0x44,
0x45,
0x68,
0x69,
0x6a,
0x6b,
0x6c,
0x6d,
0x6e,
0xe8,
0xe9,
0x71,
0x72,
0x73,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x85,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xe3,
0xe7,
0x65,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x48, 0x4a,
0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x66, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x58,
0xe4,
0x00,
0x00,
0x7f,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x81,
0x00,
0x80,
0x00,
0x00,
0x00,
0x00,
0x54,
0x00,
0x46,
0xe6,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x48,
0x48,
0x4a,
0x52,
0x4b,
0x00,
0x50,
0x00,
0x4f,
0x00,
0x4d,
0x51,
0x4e,
0x49,
0x4c,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xe3,
0xe7,
0x65,
0x66,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
bool hid_has_events(HIDState* hs)
@ -111,8 +335,7 @@ static void hid_pointer_event(HIDState *hs, InputEvent *evt)
/*[INPUT_BUTTON_LEFT] =*/0x01,
/*[INPUT_BUTTON_MIDDLE] =*/0x04,
/*[INPUT_BUTTON_RIGHT] =*/0x02,
0,0,0,0
};
0, 0, 0, 0};
HIDPointerEvent* e;
InputMoveEvent* move;
InputBtnEvent* btn;
@ -120,39 +343,48 @@ static void hid_pointer_event(HIDState *hs, InputEvent *evt)
assert(hs->n < QUEUE_LENGTH);
e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
switch (evt->type) {
switch (evt->type)
{
case INPUT_EVENT_KIND_REL:
move = &evt->u.rel;
if (move->axis == INPUT_AXIS_X) {
if (move->axis == INPUT_AXIS_X)
{
e->xdx += move->value;
}
else if (move->axis == INPUT_AXIS_Y) {
else if (move->axis == INPUT_AXIS_Y)
{
e->ydy += move->value;
}
break;
case INPUT_EVENT_KIND_ABS:
move = &evt->u.abs;
if (move->axis == INPUT_AXIS_X) {
if (move->axis == INPUT_AXIS_X)
{
e->xdx = move->value;
}
else if (move->axis == INPUT_AXIS_Y) {
else if (move->axis == INPUT_AXIS_Y)
{
e->ydy = move->value;
}
break;
case INPUT_EVENT_KIND_BTN:
btn = &evt->u.btn;
if (btn->down) {
if (btn->down)
{
e->buttons_state |= bmap[btn->button];
if (btn->button == INPUT_BUTTON_WHEEL_UP) {
if (btn->button == INPUT_BUTTON_WHEEL_UP)
{
e->dz--;
}
else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
else if (btn->button == INPUT_BUTTON_WHEEL_DOWN)
{
e->dz++;
}
}
else {
else
{
e->buttons_state &= ~bmap[btn->button];
}
break;
@ -161,7 +393,6 @@ static void hid_pointer_event(HIDState *hs, InputEvent *evt)
/* keep gcc happy */
break;
}
}
static void hid_pointer_sync(HIDState* hs)
@ -169,7 +400,8 @@ static void hid_pointer_sync(HIDState *hs)
HIDPointerEvent *prev, *curr, *next;
bool event_compression = false;
if (hs->n == QUEUE_LENGTH - 1) {
if (hs->n == QUEUE_LENGTH - 1)
{
/*
* Queue full. We are losing information, but we at least
* keep track of most recent button state.
@ -181,40 +413,48 @@ static void hid_pointer_sync(HIDState *hs)
curr = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
next = &hs->ptr.queue[(hs->head + hs->n + 1) & QUEUE_MASK];
if (hs->n > 0) {
if (hs->n > 0)
{
/*
* No button state change between previous and current event
* (and previous wasn't seen by the guest yet), so there is
* motion information only and we can combine the two event
* into one.
*/
if (curr->buttons_state == prev->buttons_state) {
if (curr->buttons_state == prev->buttons_state)
{
event_compression = true;
}
}
if (event_compression) {
if (event_compression)
{
/* add current motion to previous, clear current */
if (hs->kind == HID_MOUSE) {
if (hs->kind == HID_MOUSE)
{
prev->xdx += curr->xdx;
curr->xdx = 0;
prev->ydy += curr->ydy;
curr->ydy = 0;
}
else {
else
{
prev->xdx = curr->xdx;
prev->ydy = curr->ydy;
}
prev->dz += curr->dz;
curr->dz = 0;
}
else {
else
{
/* prepate next (clear rel, copy abs + btns) */
if (hs->kind == HID_MOUSE) {
if (hs->kind == HID_MOUSE)
{
next->xdx = 0;
next->ydy = 0;
}
else {
else
{
next->xdx = curr->xdx;
next->ydy = curr->ydy;
}
@ -235,12 +475,15 @@ static void hid_keyboard_event(HIDState *hs, InputEvent *evt)
count = qemu_input_key_value_to_scancode(&key->key,
key->down,
scancodes);
if (hs->n + count > QUEUE_LENGTH) {
if (hs->n + count > QUEUE_LENGTH)
{
//trace_hid_kbd_queue_full();
return;
}
for (i = 0; i < count; i++) {
slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
for (i = 0; i < count; i++)
{
slot = (hs->head + hs->n) & QUEUE_MASK;
hs->n++;
hs->kbd.keycodes[slot] = scancodes[i];
}
hs->event(hs);
@ -251,13 +494,17 @@ static void hid_keyboard_process_keycode(HIDState *hs)
uint8_t hid_code, index, key;
int i, keycode, slot;
if (hs->n == 0) {
if (hs->n == 0)
{
return;
}
slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
slot = hs->head & QUEUE_MASK;
QUEUE_INCR(hs->head);
hs->n--;
keycode = hs->kbd.keycodes[slot];
if (!hs->n) {
if (!hs->n)
{
//trace_hid_kbd_queue_empty();
}
@ -266,13 +513,15 @@ static void hid_keyboard_process_keycode(HIDState *hs)
hid_code = hid_usage_keys[index];
hs->kbd.modifiers &= ~(1 << 8);
switch (hid_code) {
switch (hid_code)
{
case 0x00:
return;
case 0xe0:
assert(key == 0x1d);
if (hs->kbd.modifiers & (1 << 9)) {
if (hs->kbd.modifiers & (1 << 9))
{
/* The hid_codes for the 0xe1/0x1d scancode sequence are 0xe9/0xe0.
* Here we're processing the second hid_code. By dropping bit 9
* and setting bit 8, the scancode after 0x1d will access the
@ -294,7 +543,8 @@ static void hid_keyboard_process_keycode(HIDState *hs)
/* Ctrl_L/Ctrl_R, Shift_L/Shift_R, Alt_L/Alt_R, Win_L/Win_R.
* Handle releases here, or fall through to process presses.
*/
if (keycode & (1 << 7)) {
if (keycode & (1 << 7))
{
hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f));
return;
}
@ -323,30 +573,40 @@ static void hid_keyboard_process_keycode(HIDState *hs)
break;
}
if (keycode & (1 << 7)) {
for (i = hs->kbd.keys - 1; i >= 0; i--) {
if (hs->kbd.key[i] == hid_code) {
if (keycode & (1 << 7))
{
for (i = hs->kbd.keys - 1; i >= 0; i--)
{
if (hs->kbd.key[i] == hid_code)
{
hs->kbd.key[i] = hs->kbd.key[--hs->kbd.keys];
hs->kbd.key[hs->kbd.keys] = 0x00;
break;
}
}
if (i < 0) {
if (i < 0)
{
return;
}
}
else {
for (i = hs->kbd.keys - 1; i >= 0; i--) {
if (hs->kbd.key[i] == hid_code) {
else
{
for (i = hs->kbd.keys - 1; i >= 0; i--)
{
if (hs->kbd.key[i] == hid_code)
{
break;
}
}
if (i < 0) {
if (hs->kbd.keys < (int32_t)sizeof(hs->kbd.key)) {
if (i < 0)
{
if (hs->kbd.keys < (int32_t)sizeof(hs->kbd.key))
{
hs->kbd.key[hs->kbd.keys++] = hid_code;
}
}
else {
else
{
return;
}
}
@ -354,20 +614,24 @@ static void hid_keyboard_process_keycode(HIDState *hs)
static inline int int_clamp(int val, int vmin, int vmax)
{
if (val < vmin) {
if (val < vmin)
{
return vmin;
}
else if (val > vmax) {
else if (val > vmax)
{
return vmax;
}
else {
else
{
return val;
}
}
void hid_pointer_activate(HIDState* hs)
{
if (!hs->ptr.mouse_grabbed) {
if (!hs->ptr.mouse_grabbed)
{
//qemu_input_handler_activate(hs->s);
hs->ptr.mouse_grabbed = 1;
}
@ -388,13 +652,15 @@ int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
index = (hs->n ? hs->head : hs->head - 1);
e = &hs->ptr.queue[index & QUEUE_MASK];
if (hs->kind == HID_MOUSE) {
if (hs->kind == HID_MOUSE)
{
dx = int_clamp(e->xdx, -127, 127);
dy = int_clamp(e->ydy, -127, 127);
e->xdx -= dx;
e->ydy -= dy;
}
else {
else
{
dx = e->xdx;
dy = e->ydy;
}
@ -403,7 +669,8 @@ int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
if (hs->n &&
!e->dz &&
(hs->kind == HID_TABLET || (!e->xdx && !e->ydy))) {
(hs->kind == HID_TABLET || (!e->xdx && !e->ydy)))
{
/* that deals with this event */
QUEUE_INCR(hs->head);
hs->n--;
@ -412,39 +679,50 @@ int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
/* Appears we have to invert the wheel direction */
dz = 0 - dz;
l = 0;
switch (hs->kind) {
switch (hs->kind)
{
case HID_MOUSE:
if (len > l) {
if (len > l)
{
buf[l++] = e->buttons_state;
}
if (len > l) {
if (len > l)
{
buf[l++] = dx;
}
if (len > l) {
if (len > l)
{
buf[l++] = dy;
}
if (len > l) {
if (len > l)
{
buf[l++] = dz;
}
break;
case HID_TABLET:
if (len > l) {
if (len > l)
{
buf[l++] = e->buttons_state;
}
if (len > l) {
if (len > l)
{
buf[l++] = dx & 0xff;
}
if (len > l) {
if (len > l)
{
buf[l++] = dx >> 8;
}
if (len > l) {
if (len > l)
{
buf[l++] = dy & 0xff;
}
if (len > l) {
if (len > l)
{
buf[l++] = dy >> 8;
}
if (len > l) {
if (len > l)
{
buf[l++] = dz;
}
break;
@ -460,7 +738,8 @@ int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
{
hs->idle_pending = false;
if (len < 2) {
if (len < 2)
{
return 0;
}
@ -468,10 +747,12 @@ int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
buf[0] = hs->kbd.modifiers & 0xff;
buf[1] = 0;
if (hs->kbd.keys > 6) {
if (hs->kbd.keys > 6)
{
memset(buf + 2, HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
}
else {
else
{
memcpy(buf + 2, hs->kbd.key, MIN(8, len) - 2);
}
@ -480,7 +761,8 @@ int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
int hid_keyboard_write(HIDState* hs, uint8_t* buf, int len)
{
if (len > 0) {
if (len > 0)
{
int ledstate = 0;
/* 0x01: Num Lock LED
* 0x02: Caps Lock LED
@ -488,13 +770,16 @@ int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
* 0x08: Compose LED
* 0x10: Kana LED */
hs->kbd.leds = buf[0];
if (hs->kbd.leds & 0x04) {
if (hs->kbd.leds & 0x04)
{
ledstate |= QEMU_SCROLL_LOCK_LED;
}
if (hs->kbd.leds & 0x01) {
if (hs->kbd.leds & 0x01)
{
ledstate |= QEMU_NUM_LOCK_LED;
}
if (hs->kbd.leds & 0x02) {
if (hs->kbd.leds & 0x02)
{
ledstate |= QEMU_CAPS_LOCK_LED;
}
//kbd_put_ledstate(ledstate);
@ -504,7 +789,8 @@ int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
void hid_reset(HIDState* hs)
{
switch (hs->kind) {
switch (hs->kind)
{
case HID_KEYBOARD:
memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
@ -535,11 +821,13 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event)
hs->kind = kind;
hs->event = event;
if (hs->kind == HID_KEYBOARD) {
if (hs->kind == HID_KEYBOARD)
{
hs->kbd.eh_entry = hid_keyboard_event;
} else if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
}
else if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET)
{
hs->ptr.eh_entry = hid_pointer_event;
hs->ptr.eh_sync = hid_pointer_sync;
}
}

View File

@ -50,7 +50,8 @@
#define SCANCODE_ALT 0x400
#define SCANCODE_ALTGR 0x800
typedef enum QKeyCode {
typedef enum QKeyCode
{
Q_KEY_CODE_UNMAPPED = 0,
Q_KEY_CODE_SHIFT = 1,
Q_KEY_CODE_SHIFT_R = 2,
@ -202,7 +203,8 @@ typedef enum QKeyCode {
Q_KEY_CODE__MAX = 148,
} QKeyCode;
typedef enum InputEventKind {
typedef enum InputEventKind
{
INPUT_EVENT_KIND_KEY = 0,
INPUT_EVENT_KIND_BTN = 1,
INPUT_EVENT_KIND_REL = 2,
@ -210,19 +212,22 @@ typedef enum InputEventKind {
INPUT_EVENT_KIND__MAX = 4,
} InputEventKind;
typedef enum KeyValueKind {
typedef enum KeyValueKind
{
KEY_VALUE_KIND_NUMBER = 0,
KEY_VALUE_KIND_QCODE = 1,
KEY_VALUE_KIND__MAX = 2,
} KeyValueKind;
typedef enum InputAxis {
typedef enum InputAxis
{
INPUT_AXIS_X = 0,
INPUT_AXIS_Y = 1,
INPUT_AXIS__MAX = 2,
} InputAxis;
typedef enum InputButton {
typedef enum InputButton
{
INPUT_BUTTON_LEFT = 0,
INPUT_BUTTON_MIDDLE = 1,
INPUT_BUTTON_RIGHT = 2,
@ -233,32 +238,39 @@ typedef enum InputButton {
INPUT_BUTTON__MAX = 7,
} InputButton;
struct KeyValue {
struct KeyValue
{
KeyValueKind type;
union {
union
{
int number;
QKeyCode qcode;
} u;
};
struct InputKeyEvent {
struct InputKeyEvent
{
KeyValue key;
bool down;
};
struct InputBtnEvent {
struct InputBtnEvent
{
InputButton button;
bool down;
};
struct InputMoveEvent {
struct InputMoveEvent
{
InputAxis axis;
int64_t value;
};
struct InputEvent {
struct InputEvent
{
InputEventKind type;
union {
union
{
InputKeyEvent key;
InputBtnEvent btn;
InputMoveEvent rel;
@ -273,7 +285,8 @@ typedef void QEMUPutKBDEvent(HIDState *hs, InputEvent *evt);
typedef void QEMUPutLEDEvent(void* opaque, int ledstate);
typedef void QEMUPutMouseEvent(HIDState* hs, InputEvent* evt);
typedef struct HIDPointerEvent {
typedef struct HIDPointerEvent
{
int32_t xdx, ydy; /* relative if it's a mouse, otherwise absolute */
int32_t dz, buttons_state;
} HIDPointerEvent;
@ -282,14 +295,16 @@ typedef struct HIDPointerEvent {
#define QUEUE_MASK (QUEUE_LENGTH - 1u)
#define QUEUE_INCR(v) ((v)++, (v) &= QUEUE_MASK)
typedef struct HIDMouseState {
typedef struct HIDMouseState
{
HIDPointerEvent queue[QUEUE_LENGTH];
int mouse_grabbed;
QEMUPutMouseEvent* eh_entry;
HIDEventFunc eh_sync;
} HIDMouseState;
typedef struct HIDKeyboardState {
typedef struct HIDKeyboardState
{
uint32_t keycodes[QUEUE_LENGTH];
uint16_t modifiers;
uint8_t leds;
@ -298,8 +313,10 @@ typedef struct HIDKeyboardState {
QEMUPutKBDEvent* eh_entry;
} HIDKeyboardState;
struct HIDState {
union {
struct HIDState
{
union
{
HIDMouseState ptr;
HIDKeyboardState kbd;
};

View File

@ -176,10 +176,12 @@ int qemu_input_qcode_to_number(const QKeyCode value)
int qemu_input_key_value_to_number(const KeyValue* value)
{
if (value->type == KEY_VALUE_KIND_QCODE) {
if (value->type == KEY_VALUE_KIND_QCODE)
{
return qemu_input_qcode_to_number(value->u.qcode);
}
else {
else
{
assert(value->type == KEY_VALUE_KIND_NUMBER);
return value->u.number;
}
@ -192,7 +194,8 @@ int qemu_input_key_value_to_scancode(const KeyValue *value, bool down,
int count = 0;
if (value->type == KEY_VALUE_KIND_QCODE &&
value->u.qcode == Q_KEY_CODE_PAUSE) {
value->u.qcode == Q_KEY_CODE_PAUSE)
{
/* specific case */
int v = down ? 0 : 0x80;
codes[count++] = 0xe1;
@ -200,11 +203,13 @@ int qemu_input_key_value_to_scancode(const KeyValue *value, bool down,
codes[count++] = 0x45 | v;
return count;
}
if (keycode & SCANCODE_GREY) {
if (keycode & SCANCODE_GREY)
{
codes[count++] = SCANCODE_EMUL0;
keycode &= ~SCANCODE_GREY;
}
if (!down) {
if (!down)
{
keycode |= SCANCODE_UP;
}
codes[count++] = keycode;

View File

@ -29,13 +29,17 @@ size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
{
size_t done;
unsigned int i;
for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
if (offset < iov[i].iov_len) {
for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++)
{
if (offset < iov[i].iov_len)
{
size_t len = MIN(iov[i].iov_len - offset, bytes - done);
memcpy((char*)iov[i].iov_base + offset, (char*)buf + done, len);
done += len;
offset = 0;
} else {
}
else
{
offset -= iov[i].iov_len;
}
}
@ -48,13 +52,17 @@ size_t iov_to_buf_full(const struct iovec *iov, const unsigned int iov_cnt,
{
size_t done;
unsigned int i;
for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
if (offset < iov[i].iov_len) {
for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++)
{
if (offset < iov[i].iov_len)
{
size_t len = MIN(iov[i].iov_len - offset, bytes - done);
memcpy((char*)buf + done, (char*)iov[i].iov_base + offset, len);
done += len;
offset = 0;
} else {
}
else
{
offset -= iov[i].iov_len;
}
}
@ -67,13 +75,17 @@ size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
{
size_t done;
unsigned int i;
for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++) {
if (offset < iov[i].iov_len) {
for (i = 0, done = 0; (offset || done < bytes) && i < iov_cnt; i++)
{
if (offset < iov[i].iov_len)
{
size_t len = MIN(iov[i].iov_len - offset, bytes - done);
memset((char*)iov[i].iov_base + offset, fillc, len);
done += len;
offset = 0;
} else {
}
else
{
offset -= iov[i].iov_len;
}
}
@ -87,7 +99,8 @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt)
unsigned int i;
len = 0;
for (i = 0; i < iov_cnt; i++) {
for (i = 0; i < iov_cnt; i++)
{
len += iov[i].iov_len;
}
return len;
@ -100,8 +113,10 @@ unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
size_t len;
unsigned int i, j;
for (i = 0, j = 0;
i < iov_cnt && j < dst_iov_cnt && (offset || bytes); i++) {
if (offset >= iov[i].iov_len) {
i < iov_cnt && j < dst_iov_cnt && (offset || bytes); i++)
{
if (offset >= iov[i].iov_len)
{
offset -= iov[i].iov_len;
continue;
}
@ -143,7 +158,8 @@ void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
{
assert(qiov->nalloc != -1);
if (qiov->niov == qiov->nalloc) {
if (qiov->niov == qiov->nalloc)
{
qiov->nalloc = 2 * qiov->nalloc + 1;
qiov->iov = my_g_renew(struct iovec, qiov->iov, qiov->nalloc);
}
@ -170,17 +186,22 @@ size_t qemu_iovec_concat_iov(QEMUIOVector *dst,
unsigned int i;
size_t done;
if (!sbytes) {
if (!sbytes)
{
return 0;
}
assert(dst->nalloc != -1);
for (i = 0, done = 0; done < sbytes && i < src_cnt; i++) {
if (soffset < src_iov[i].iov_len) {
for (i = 0, done = 0; done < sbytes && i < src_cnt; i++)
{
if (soffset < src_iov[i].iov_len)
{
size_t len = MIN(src_iov[i].iov_len - soffset, sbytes - done);
qemu_iovec_add(dst, (char*)src_iov[i].iov_base + soffset, len);
done += len;
soffset = 0;
} else {
}
else
{
soffset -= src_iov[i].iov_len;
}
}
@ -278,26 +299,30 @@ ssize_t qemu_iovec_compare(QEMUIOVector *a, QEMUIOVector *b)
ssize_t offset = 0;
assert(a->niov == b->niov);
for (i = 0; i < a->niov; i++) {
for (i = 0; i < a->niov; i++)
{
size_t len = 0;
uint8_t* p = (uint8_t*)a->iov[i].iov_base;
uint8_t* q = (uint8_t*)b->iov[i].iov_base;
assert(a->iov[i].iov_len == b->iov[i].iov_len);
while (len < a->iov[i].iov_len && *p++ == *q++) {
while (len < a->iov[i].iov_len && *p++ == *q++)
{
len++;
}
offset += len;
if (len != a->iov[i].iov_len) {
if (len != a->iov[i].iov_len)
{
return offset;
}
}
return -1;
}
typedef struct {
typedef struct
{
int src_index;
struct iovec* src_iov;
void* dest_base;
@ -309,11 +334,16 @@ static int sortelem_cmp_src_base(const void *a, const void *b)
const IOVectorSortElem* elem_b = (const IOVectorSortElem*)b;
/* Don't overflow */
if (elem_a->src_iov->iov_base < elem_b->src_iov->iov_base) {
if (elem_a->src_iov->iov_base < elem_b->src_iov->iov_base)
{
return -1;
} else if (elem_a->src_iov->iov_base > elem_b->src_iov->iov_base) {
}
else if (elem_a->src_iov->iov_base > elem_b->src_iov->iov_base)
{
return 1;
} else {
}
else
{
return 0;
}
}
@ -332,8 +362,10 @@ size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt,
size_t total = 0;
struct iovec* cur;
for (cur = *iov; *iov_cnt > 0; cur++) {
if (cur->iov_len > bytes) {
for (cur = *iov; *iov_cnt > 0; cur++)
{
if (cur->iov_len > bytes)
{
cur->iov_base = (uint8_t*)cur->iov_base + bytes;
cur->iov_len -= bytes;
total += bytes;
@ -355,14 +387,17 @@ size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt,
size_t total = 0;
struct iovec* cur;
if (*iov_cnt == 0) {
if (*iov_cnt == 0)
{
return 0;
}
cur = iov + (*iov_cnt - 1);
while (*iov_cnt > 0) {
if (cur->iov_len > bytes) {
while (*iov_cnt > 0)
{
if (cur->iov_len > bytes)
{
cur->iov_len -= bytes;
total += bytes;
break;

View File

@ -15,7 +15,8 @@
#define IOV_H
#if !defined(_BITS_UIO_H) && !defined(__iovec_defined) /* /usr/include/bits/uio.h */
struct iovec {
struct iovec
{
void* iov_base;
size_t iov_len;
};
@ -54,10 +55,13 @@ iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
size_t offset, const void* buf, size_t bytes)
{
if (__builtin_constant_p(bytes) && iov_cnt &&
offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset) {
offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset)
{
memcpy((char*)iov[0].iov_base + offset, buf, bytes);
return bytes;
} else {
}
else
{
return iov_from_buf_full(iov, iov_cnt, offset, buf, bytes);
}
}
@ -67,10 +71,13 @@ iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
size_t offset, void* buf, size_t bytes)
{
if (__builtin_constant_p(bytes) && iov_cnt &&
offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset) {
offset <= iov[0].iov_len && bytes <= iov[0].iov_len - offset)
{
memcpy(buf, (char*)iov[0].iov_base + offset, bytes);
return bytes;
} else {
}
else
{
return iov_to_buf_full(iov, iov_cnt, offset, buf, bytes);
}
}
@ -143,7 +150,8 @@ size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt,
size_t iov_discard_back(struct iovec* iov, unsigned int* iov_cnt,
size_t bytes);
typedef struct QEMUIOVector {
typedef struct QEMUIOVector
{
struct iovec* iov;
int niov;
int nalloc;

View File

@ -84,15 +84,19 @@
* List definitions.
*/
#define QLIST_HEAD(name, type) \
struct name { \
struct name \
{ \
struct type* lh_first; /* first element */ \
}
#define QLIST_HEAD_INITIALIZER(head) \
{ NULL }
{ \
NULL \
}
#define QLIST_ENTRY(type) \
struct { \
struct \
{ \
struct type* le_next; /* next element */ \
struct type** le_prev; /* address of previous next element */ \
}
@ -100,24 +104,32 @@ struct { \
/*
* List functions.
*/
#define QLIST_INIT(head) do { \
#define QLIST_INIT(head) \
do \
{ \
(head)->lh_first = NULL; \
} while (/*CONSTCOND*/ 0)
#define QLIST_SWAP(dstlist, srclist, field) do { \
#define QLIST_SWAP(dstlist, srclist, field) \
do \
{ \
void* tmplist; \
tmplist = (srclist)->lh_first; \
(srclist)->lh_first = (dstlist)->lh_first; \
if ((srclist)->lh_first != NULL) { \
if ((srclist)->lh_first != NULL) \
{ \
(srclist)->lh_first->field.le_prev = &(srclist)->lh_first; \
} \
(dstlist)->lh_first = tmplist; \
if ((dstlist)->lh_first != NULL) { \
if ((dstlist)->lh_first != NULL) \
{ \
(dstlist)->lh_first->field.le_prev = &(dstlist)->lh_first; \
} \
} while (/*CONSTCOND*/ 0)
#define QLIST_INSERT_AFTER(listelm, elm, field) do { \
#define QLIST_INSERT_AFTER(listelm, elm, field) \
do \
{ \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
@ -125,21 +137,27 @@ struct { \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (/*CONSTCOND*/ 0)
#define QLIST_INSERT_BEFORE(listelm, elm, field) do { \
#define QLIST_INSERT_BEFORE(listelm, elm, field) \
do \
{ \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (/*CONSTCOND*/ 0)
#define QLIST_INSERT_HEAD(head, elm, field) do { \
#define QLIST_INSERT_HEAD(head, elm, field) \
do \
{ \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next; \
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (/*CONSTCOND*/ 0)
#define QLIST_REMOVE(elm, field) do { \
#define QLIST_REMOVE(elm, field) \
do \
{ \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
@ -168,52 +186,71 @@ struct { \
* Singly-linked List definitions.
*/
#define QSLIST_HEAD(name, type) \
struct name { \
struct name \
{ \
struct type* slh_first; /* first element */ \
}
#define QSLIST_HEAD_INITIALIZER(head) \
{ NULL }
{ \
NULL \
}
#define QSLIST_ENTRY(type) \
struct { \
struct \
{ \
struct type* sle_next; /* next element */ \
}
/*
* Singly-linked List functions.
*/
#define QSLIST_INIT(head) do { \
#define QSLIST_INIT(head) \
do \
{ \
(head)->slh_first = NULL; \
} while (/*CONSTCOND*/ 0)
#define QSLIST_INSERT_AFTER(slistelm, elm, field) do { \
#define QSLIST_INSERT_AFTER(slistelm, elm, field) \
do \
{ \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (/*CONSTCOND*/ 0)
#define QSLIST_INSERT_HEAD(head, elm, field) do { \
#define QSLIST_INSERT_HEAD(head, elm, field) \
do \
{ \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (/*CONSTCOND*/ 0)
#define QSLIST_INSERT_HEAD_ATOMIC(head, elm, field) do { \
#define QSLIST_INSERT_HEAD_ATOMIC(head, elm, field) \
do \
{ \
typeof(elm) save_sle_next; \
do { \
do \
{ \
save_sle_next = (elm)->field.sle_next = (head)->slh_first; \
} while (atomic_cmpxchg(&(head)->slh_first, save_sle_next, (elm)) != \
save_sle_next); \
} while (/*CONSTCOND*/ 0)
#define QSLIST_MOVE_ATOMIC(dest, src) do { \
#define QSLIST_MOVE_ATOMIC(dest, src) \
do \
{ \
(dest)->slh_first = atomic_xchg(&(src)->slh_first, NULL); \
} while (/*CONSTCOND*/ 0)
#define QSLIST_REMOVE_HEAD(head, field) do { \
#define QSLIST_REMOVE_HEAD(head, field) \
do \
{ \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (/*CONSTCOND*/ 0)
#define QSLIST_REMOVE_AFTER(slistelm, field) do { \
#define QSLIST_REMOVE_AFTER(slistelm, field) \
do \
{ \
(slistelm)->field.sle_next = \
QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field); \
} while (/*CONSTCOND*/ 0)
@ -238,54 +275,72 @@ struct { \
* Simple queue definitions.
*/
#define QSIMPLEQ_HEAD(name, type) \
struct name { \
struct name \
{ \
struct type* sqh_first; /* first element */ \
struct type** sqh_last; /* addr of last next element */ \
}
#define QSIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
{ \
NULL, &(head).sqh_first \
}
#define QSIMPLEQ_ENTRY(type) \
struct { \
struct \
{ \
struct type* sqe_next; /* next element */ \
}
/*
* Simple queue functions.
*/
#define QSIMPLEQ_INIT(head) do { \
#define QSIMPLEQ_INIT(head) \
do \
{ \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (/*CONSTCOND*/ 0)
#define QSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
#define QSIMPLEQ_INSERT_HEAD(head, elm, field) \
do \
{ \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (/*CONSTCOND*/ 0)
#define QSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
#define QSIMPLEQ_INSERT_TAIL(head, elm, field) \
do \
{ \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (/*CONSTCOND*/ 0)
#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) \
do \
{ \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (/*CONSTCOND*/ 0)
#define QSIMPLEQ_REMOVE_HEAD(head, field) do { \
#define QSIMPLEQ_REMOVE_HEAD(head, field) \
do \
{ \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (/*CONSTCOND*/ 0)
#define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do { \
#define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) \
do \
{ \
QSIMPLEQ_INIT(removed); \
if (((removed)->sqh_first = (head)->sqh_first) != NULL) { \
if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) { \
if (((removed)->sqh_first = (head)->sqh_first) != NULL) \
{ \
if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \
{ \
(head)->sqh_last = &(head)->sqh_first; \
} \
(removed)->sqh_last = &(elm)->field.sqe_next; \
@ -293,10 +348,15 @@ struct { \
} \
} while (/*CONSTCOND*/ 0)
#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \
if ((head)->sqh_first == (elm)) { \
#define QSIMPLEQ_REMOVE(head, elm, type, field) \
do \
{ \
if ((head)->sqh_first == (elm)) \
{ \
QSIMPLEQ_REMOVE_HEAD((head), field); \
} else { \
} \
else \
{ \
struct type* curelm = (head)->sqh_first; \
while (curelm->field.sqe_next != (elm)) \
curelm = curelm->field.sqe_next; \
@ -316,8 +376,11 @@ struct { \
(var) && ((next = ((var)->field.sqe_next)), 1); \
(var) = (next))
#define QSIMPLEQ_CONCAT(head1, head2) do { \
if (!QSIMPLEQ_EMPTY((head2))) { \
#define QSIMPLEQ_CONCAT(head1, head2) \
do \
{ \
if (!QSIMPLEQ_EMPTY((head2))) \
{ \
*(head1)->sqh_last = (head2)->sqh_first; \
(head1)->sqh_last = (head2)->sqh_last; \
QSIMPLEQ_INIT((head2)); \
@ -327,8 +390,7 @@ struct { \
#define QSIMPLEQ_LAST(head, type, field) \
(QSIMPLEQ_EMPTY((head)) ? \
NULL : \
((struct type *)(void *) \
((char *)((head)->sqh_last) - offsetof(struct type, field))))
((struct type*)(void*)((char*)((head)->sqh_last) - offsetof(struct type, field))))
/*
* Simple queue access methods.
@ -342,17 +404,21 @@ struct { \
* Tail queue definitions.
*/
#define Q_TAILQ_HEAD(name, type, qual) \
struct name { \
struct name \
{ \
qual type* tqh_first; /* first element */ \
qual type* qual* tqh_last; /* addr of last next element */ \
}
#define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type, )
#define QTAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
{ \
NULL, &(head).tqh_first \
}
#define Q_TAILQ_ENTRY(type, qual) \
struct { \
struct \
{ \
qual type* tqe_next; /* next element */ \
qual type* qual* tqe_prev; /* address of previous next element */ \
}
@ -361,12 +427,16 @@ struct { \
/*
* Tail queue functions.
*/
#define QTAILQ_INIT(head) do { \
#define QTAILQ_INIT(head) \
do \
{ \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (/*CONSTCOND*/ 0)
#define QTAILQ_INSERT_HEAD(head, elm, field) do { \
#define QTAILQ_INSERT_HEAD(head, elm, field) \
do \
{ \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
@ -376,14 +446,18 @@ struct { \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (/*CONSTCOND*/ 0)
#define QTAILQ_INSERT_TAIL(head, elm, field) do { \
#define QTAILQ_INSERT_TAIL(head, elm, field) \
do \
{ \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (/*CONSTCOND*/ 0)
#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) \
do \
{ \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
@ -393,14 +467,18 @@ struct { \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (/*CONSTCOND*/ 0)
#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do { \
#define QTAILQ_INSERT_BEFORE(listelm, elm, field) \
do \
{ \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (/*CONSTCOND*/ 0)
#define QTAILQ_REMOVE(head, elm, field) do { \
#define QTAILQ_REMOVE(head, elm, field) \
do \
{ \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
@ -444,12 +522,16 @@ struct { \
typedef struct DUMMY_Q_ENTRY DUMMY_Q_ENTRY;
typedef struct DUMMY_Q DUMMY_Q;
struct DUMMY_Q_ENTRY {
QTAILQ_ENTRY(DUMMY_Q_ENTRY) next;
struct DUMMY_Q_ENTRY
{
QTAILQ_ENTRY(DUMMY_Q_ENTRY)
next;
};
struct DUMMY_Q {
QTAILQ_HEAD(DUMMY_Q_HEAD, DUMMY_Q_ENTRY) head;
struct DUMMY_Q
{
QTAILQ_HEAD(DUMMY_Q_HEAD, DUMMY_Q_ENTRY)
head;
};
#define dummy_q ((DUMMY_Q*)0)
@ -491,7 +573,9 @@ struct DUMMY_Q {
/*
* Tail queue insertion using pointer arithmetic.
*/
#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do { \
#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) \
do \
{ \
QTAILQ_RAW_NEXT(elm, entry) = NULL; \
QTAILQ_RAW_TQE_PREV(elm, entry) = QTAILQ_RAW_TQH_LAST(head); \
*QTAILQ_RAW_TQH_LAST(head) = (elm); \

View File

@ -281,16 +281,19 @@ typedef struct USBDescOther USBDescOther;
typedef struct USBDescString USBDescString;
typedef struct USBDescMSOS USBDescMSOS;
struct USBDescString {
struct USBDescString
{
uint8_t index;
char* str;
QLIST_ENTRY(USBDescString) next;
QLIST_ENTRY(USBDescString)
next;
};
#define USB_MAX_ENDPOINTS 15
#define USB_MAX_INTERFACES 16
struct USBEndpoint {
struct USBEndpoint
{
uint8_t nr;
uint8_t pid;
uint8_t type;
@ -300,10 +303,12 @@ struct USBEndpoint {
bool pipeline;
bool halted;
USBDevice* dev;
QTAILQ_HEAD(, USBPacket) queue;
QTAILQ_HEAD(, USBPacket)
queue;
};
enum USBDeviceFlags {
enum USBDeviceFlags
{
USB_DEV_FLAG_FULL_PATH,
USB_DEV_FLAG_IS_HOST,
USB_DEV_FLAG_MSOS_DESC_ENABLE,
@ -313,7 +318,8 @@ enum USBDeviceFlags {
typedef void (*USBDeviceRealize)(USBDevice* dev /*, Error **errp*/);
typedef void (*USBDeviceUnrealize)(USBDevice* dev /*, Error **errp*/);
typedef struct USBDeviceClass {
typedef struct USBDeviceClass
{
//DeviceClass parent_class;
USBDeviceRealize realize;
@ -391,7 +397,8 @@ typedef struct USBDeviceClass {
} USBDeviceClass;
/* definition of a USB device */
struct USBDevice {
struct USBDevice
{
USBDeviceClass klass;
USBPort* port;
USBBus* bus;
@ -429,7 +436,8 @@ struct USBDevice {
const USBDescIface* ifaces[USB_MAX_INTERFACES];
};
typedef struct USBPortOps {
typedef struct USBPortOps
{
void (*attach)(USBPort* port);
void (*detach)(USBPort* port);
/*
@ -446,7 +454,8 @@ typedef struct USBPortOps {
} USBPortOps;
/* USB port on which a device can be connected */
struct USBPort {
struct USBPort
{
USBDevice* dev;
int speedmask;
USBPortOps* ops;
@ -457,7 +466,8 @@ struct USBPort {
typedef void USBCallback(USBPacket* packet, void* opaque);
typedef enum USBPacketState {
typedef enum USBPacketState
{
USB_PACKET_UNDEFINED = 0,
USB_PACKET_SETUP,
USB_PACKET_QUEUED,
@ -467,7 +477,8 @@ typedef enum USBPacketState {
} USBPacketState;
/* Structure used to hold information about an active USB packet. */
struct USBPacket {
struct USBPacket
{
/* Data fields for use by the driver. */
int pid;
uint64_t id;
@ -482,13 +493,17 @@ struct USBPacket {
/* Internal use by the USB layer. */
USBPacketState state;
USBCombinedPacket* combined;
QTAILQ_ENTRY(USBPacket) queue;
QTAILQ_ENTRY(USBPacket) combined_entry;
QTAILQ_ENTRY(USBPacket)
queue;
QTAILQ_ENTRY(USBPacket)
combined_entry;
};
struct USBCombinedPacket {
struct USBCombinedPacket
{
USBPacket* first;
QTAILQ_HEAD(packets_head, USBPacket) packets;
QTAILQ_HEAD(packets_head, USBPacket)
packets;
QEMUIOVector iov;
};
@ -512,21 +527,27 @@ static inline bool usb_packet_is_inflight(USBPacket *p)
p->state == USB_PACKET_ASYNC);
}
struct USBBus {
struct USBBus
{
//BusState qbus;
USBBusOps* ops;
int busnr;
int nfree;
int nused;
QTAILQ_HEAD(, USBPort) free;
QTAILQ_HEAD(, USBPort) used;
QTAILQ_ENTRY(USBBus) next;
QTAILQ_HEAD(, USBPort)
free;
QTAILQ_HEAD(, USBPort)
used;
QTAILQ_ENTRY(USBBus)
next;
};
struct USBBusOps {
struct USBBusOps
{
void (*register_companion)(USBBus* bus, USBPort* ports[],
uint32_t portcount, uint32_t firstport /*,
Error **errp*/);
Error **errp*/
);
void (*wakeup_endpoint)(USBBus* bus, USBEndpoint* ep, unsigned int stream);
};

View File

@ -27,13 +27,15 @@
#define MAX_PORTS 8
typedef struct USBHubPort {
typedef struct USBHubPort
{
USBPort port;
uint16_t wPortStatus;
uint16_t wPortChange;
} USBHubPort;
typedef struct USBHubState {
typedef struct USBHubState
{
USBDevice dev;
int nb_ports;
USBHubPort ports[MAX_PORTS];
@ -168,7 +170,8 @@ static void usb_hub_attach(USBPort *port1, USBDevice *dev)
USBHubState* s = (USBHubState*)port1->opaque;
USBHubPort* port = (USBHubPort*)&s->ports[port1->index];
if (dev) {
if (dev)
{
if (port->port.dev)
usb_attach(port1, NULL);
@ -182,12 +185,16 @@ static void usb_hub_attach(USBPort *port1, USBDevice *dev)
/* send the attach message */
dev->handle_packet(dev,
USB_MSG_ATTACH, 0, 0, NULL, 0);
} else {
}
else
{
dev = port->port.dev;
if (dev) {
if (dev)
{
port->wPortStatus &= ~PORT_STAT_CONNECTION;
port->wPortChange |= PORT_STAT_C_CONNECTION;
if (port->wPortStatus & PORT_STAT_ENABLE) {
if (port->wPortStatus & PORT_STAT_ENABLE)
{
port->wPortStatus &= ~PORT_STAT_ENABLE;
port->wPortChange |= PORT_STAT_C_ENABLE;
}
@ -210,7 +217,8 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value,
USBHubState* s = (USBHubState*)dev;
int ret;
switch(request) {
switch (request)
{
case DeviceRequest | USB_REQ_GET_STATUS:
data[0] = (1 << USB_DEVICE_SELF_POWERED) |
(dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
@ -218,23 +226,30 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value,
ret = 2;
break;
case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
if (value == USB_DEVICE_REMOTE_WAKEUP) {
if (value == USB_DEVICE_REMOTE_WAKEUP)
{
dev->remote_wakeup = 0;
} else {
}
else
{
goto fail;
}
ret = 0;
break;
case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
if (value == 0 && index != 0x81) { /* clear ep halt */
if (value == 0 && index != 0x81)
{ /* clear ep halt */
goto fail;
}
ret = 0;
break;
case DeviceOutRequest | USB_REQ_SET_FEATURE:
if (value == USB_DEVICE_REMOTE_WAKEUP) {
if (value == USB_DEVICE_REMOTE_WAKEUP)
{
dev->remote_wakeup = 1;
} else {
}
else
{
goto fail;
}
ret = 0;
@ -244,7 +259,8 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value,
ret = 0;
break;
case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
switch(value >> 8) {
switch (value >> 8)
{
case USB_DT_DEVICE:
memcpy(data, qemu_hub_dev_descriptor,
sizeof(qemu_hub_dev_descriptor));
@ -261,7 +277,8 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value,
ret = sizeof(qemu_hub_config_descriptor);
break;
case USB_DT_STRING:
switch(value & 0xff) {
switch (value & 0xff)
{
case 0:
/* language ids */
data[0] = 4;
@ -328,8 +345,11 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value,
break;
case SetHubFeature:
case ClearHubFeature:
if (value == 0 || value == 1) {
} else {
if (value == 0 || value == 1)
{
}
else
{
goto fail;
}
ret = 0;
@ -343,12 +363,14 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value,
goto fail;
port = &s->ports[n];
dev = port->port.dev;
switch(value) {
switch (value)
{
case PORT_SUSPEND:
port->wPortStatus |= PORT_STAT_SUSPEND;
break;
case PORT_RESET:
if (dev) {
if (dev)
{
dev->handle_packet(dev,
USB_MSG_RESET, 0, 0, NULL, 0);
port->wPortChange |= PORT_STAT_C_RESET;
@ -373,7 +395,8 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value,
goto fail;
port = &s->ports[n];
dev = port->port.dev;
switch(value) {
switch (value)
{
case PORT_ENABLE:
port->wPortStatus &= ~PORT_STAT_ENABLE;
break;
@ -410,14 +433,16 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value,
/* fill DeviceRemovable bits */
limit = ((s->nb_ports + 1 + 7) / 8) + 7;
for (n = 7; n < limit; n++) {
for (n = 7; n < limit; n++)
{
data[n] = 0x00;
var_hub_size++;
}
/* fill PortPwrCtrlMask bits */
limit = limit + ((s->nb_ports + 7) / 8);
for (;n < limit; n++) {
for (; n < limit; n++)
{
data[n] = 0xff;
var_hub_size++;
}
@ -440,33 +465,45 @@ static int usb_hub_handle_data(USBDevice *dev, int pid,
USBHubState* s = (USBHubState*)dev;
int ret;
switch(pid) {
switch (pid)
{
case USB_TOKEN_IN:
if (devep == 1) {
if (devep == 1)
{
USBHubPort* port;
unsigned int status;
int i, n;
n = (s->nb_ports + 1 + 7) / 8;
if (len == 1) { /* FreeBSD workaround */
if (len == 1)
{ /* FreeBSD workaround */
n = 1;
} else if (n > len) {
}
else if (n > len)
{
return USB_RET_BABBLE;
}
status = 0;
for(i = 0; i < s->nb_ports; i++) {
for (i = 0; i < s->nb_ports; i++)
{
port = &s->ports[i];
if (port->wPortChange)
status |= (1 << (i + 1));
}
if (status != 0) {
for(i = 0; i < n; i++) {
if (status != 0)
{
for (i = 0; i < n; i++)
{
data[i] = status >> (8 * i);
}
ret = n;
} else {
}
else
{
ret = USB_RET_NAK; /* usb11 11.13.1 */
}
} else {
}
else
{
goto fail;
}
break;
@ -487,14 +524,17 @@ static int usb_hub_broadcast_packet(USBHubState *s, int pid,
USBDevice* dev;
int i, ret;
for(i = 0; i < s->nb_ports; i++) {
for (i = 0; i < s->nb_ports; i++)
{
port = &s->ports[i];
dev = port->port.dev;
if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) {
if (dev && (port->wPortStatus & PORT_STAT_ENABLE))
{
ret = dev->handle_packet(dev, pid,
devaddr, devep,
data, len);
if (ret != USB_RET_NODEV) {
if (ret != USB_RET_NODEV)
{
return ret;
}
}
@ -516,7 +556,8 @@ static int usb_hub_handle_packet(USBDevice *dev, int pid,
devaddr != dev->addr &&
(pid == USB_TOKEN_SETUP ||
pid == USB_TOKEN_OUT ||
pid == USB_TOKEN_IN)) {
pid == USB_TOKEN_IN))
{
/* broadcast the packet to the devices */
return usb_hub_broadcast_packet(s, pid, devaddr, devep, data, len);
}
@ -553,7 +594,8 @@ USBDevice *usb_hub_init(int nb_ports)
strncpy(s->dev.devname, "QEMU USB Hub", sizeof(s->dev.devname));
s->nb_ports = nb_ports;
for(i = 0; i < s->nb_ports; i++) {
for (i = 0; i < s->nb_ports; i++)
{
port = &s->ports[i];
port->port.opaque = s;
port->port.index = i;

View File

@ -96,8 +96,10 @@ static void ohci_attach2(USBPort *port1, USBDevice *dev)
OHCIPort* port = (OHCIPort*)&s->rhport[port1->index];
uint32_t old_state = port->ctrl;
if (dev) {
if (port1->dev) {
if (dev)
{
if (port1->dev)
{
ohci_attach2(port1, NULL);
}
/* set connect status */
@ -112,19 +114,24 @@ static void ohci_attach2(USBPort *port1, USBDevice *dev)
port1->dev = dev;
dev->state = USB_STATE_ATTACHED;
OSDebugOut(TEXT("usb-ohci: Attached port %d\n"), port1->index);
} else {
}
else
{
/* set connect status */
if (port->ctrl & OHCI_PORT_CCS) {
if (port->ctrl & OHCI_PORT_CCS)
{
port->ctrl &= ~OHCI_PORT_CCS;
port->ctrl |= OHCI_PORT_CSC;
}
/* disable port */
if (port->ctrl & OHCI_PORT_PES) {
if (port->ctrl & OHCI_PORT_PES)
{
port->ctrl &= ~OHCI_PORT_PES;
port->ctrl |= OHCI_PORT_PESC;
}
dev = port1->dev;
if (dev) {
if (dev)
{
dev->port = NULL;
/* send the detach message */
dev->state = USB_STATE_NOTATTACHED;
@ -151,20 +158,25 @@ static void ohci_attach(USBPort *port1)
port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;
/* update speed */
if (port->port.dev->speed == USB_SPEED_LOW) {
if (port->port.dev->speed == USB_SPEED_LOW)
{
port->ctrl |= OHCI_PORT_LSDA;
} else {
}
else
{
port->ctrl &= ~OHCI_PORT_LSDA;
}
/* notify of remote-wakeup */
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND)
{
ohci_set_interrupt(s, OHCI_INTR_RD);
}
//trace_usb_ohci_port_attach(port1->index);
if (old_state != port->ctrl) {
if (old_state != port->ctrl)
{
ohci_set_interrupt(s, OHCI_INTR_RHSC);
}
}
@ -180,18 +192,21 @@ static void ohci_detach(USBPort *port1)
ohci_async_cancel_device(s, port1->dev);
/* set connect status */
if (port->ctrl & OHCI_PORT_CCS) {
if (port->ctrl & OHCI_PORT_CCS)
{
port->ctrl &= ~OHCI_PORT_CCS;
port->ctrl |= OHCI_PORT_CSC;
}
/* disable port */
if (port->ctrl & OHCI_PORT_PES) {
if (port->ctrl & OHCI_PORT_PES)
{
port->ctrl &= ~OHCI_PORT_PES;
port->ctrl |= OHCI_PORT_PESC;
}
//trace_usb_ohci_port_detach(port1->index);
if (old_state != port->ctrl) {
if (old_state != port->ctrl)
{
ohci_set_interrupt(s, OHCI_INTR_RHSC);
}
}
@ -201,14 +216,16 @@ static void ohci_wakeup(USBPort *port1)
OHCIState* s = (OHCIState*)port1->opaque;
OHCIPort* port = (OHCIPort*)&s->rhport[port1->index];
uint32_t intr = 0;
if (port->ctrl & OHCI_PORT_PSS) {
if (port->ctrl & OHCI_PORT_PSS)
{
//trace_usb_ohci_port_wakeup(port1->index);
port->ctrl |= OHCI_PORT_PSSC;
port->ctrl &= ~OHCI_PORT_PSS;
intr = OHCI_INTR_RHSC;
}
/* Note that the controller can be suspended even if this port is not */
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND)
{
//trace_usb_ohci_remote_wakeup(s->name);
/* This is the one state transition the controller can do by itself */
s->ctl &= ~OHCI_CTL_HCFS;
@ -226,12 +243,15 @@ static USBDevice *ohci_find_device(OHCIState *ohci, uint8_t addr)
USBDevice* dev;
int i;
for (i = 0; i < ohci->num_ports; i++) {
if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0) {
for (i = 0; i < ohci->num_ports; i++)
{
if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
{
continue;
}
dev = usb_find_device(&ohci->rhport[i].port, addr);
if (dev != NULL) {
if (dev != NULL)
{
return dev;
}
}
@ -244,11 +264,14 @@ static void ohci_stop_endpoints(OHCIState *ohci)
USBDevice* dev;
int i, j;
for (i = 0; i < ohci->num_ports; i++) {
for (i = 0; i < ohci->num_ports; i++)
{
dev = ohci->rhport[i].port.dev;
if (dev && dev->attached) {
if (dev && dev->attached)
{
usb_device_ep_stopped(dev, &dev->ep_ctl);
for (j = 0; j < USB_MAX_ENDPOINTS; j++) {
for (j = 0; j < USB_MAX_ENDPOINTS; j++)
{
usb_device_ep_stopped(dev, &dev->ep_in[j]);
usb_device_ep_stopped(dev, &dev->ep_out[j]);
}
@ -266,14 +289,17 @@ static void ohci_roothub_reset(OHCIState *ohci)
ohci->rhdesc_b = 0x0; /* Impl. specific */
ohci->rhstatus = 0;
for (i = 0; i < ohci->num_ports; i++) {
for (i = 0; i < ohci->num_ports; i++)
{
port = &ohci->rhport[i];
port->ctrl = 0;
if (port->port.dev && port->port.dev->attached) {
if (port->port.dev && port->port.dev->attached)
{
usb_port_reset(&port->port);
}
}
if (ohci->async_td) {
if (ohci->async_td)
{
usb_cancel_packet(&ohci->usb_packet);
ohci->async_td = 0;
}
@ -327,7 +353,8 @@ static inline int get_dwords(uint32_t addr, uint32_t *buf, int num)
{
int i;
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf))
{
if (cpu_physical_memory_rw(addr, (uint8_t*)buf, sizeof(*buf), 0))
return 0;
*buf = le32_to_cpu(*buf);
@ -341,7 +368,8 @@ static inline int get_words(uint32_t addr, uint16_t *buf, int num)
{
int i;
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf))
{
if (cpu_physical_memory_rw(addr, (uint8_t*)buf, sizeof(*buf), 0))
return 0;
*buf = le16_to_cpu(*buf);
@ -355,7 +383,8 @@ static inline int put_dwords(uint32_t addr, uint32_t *buf, int num)
{
int i;
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf))
{
uint32_t tmp = cpu_to_le32(*buf);
if (cpu_physical_memory_rw(addr, (uint8_t*)&tmp, sizeof(tmp), 1))
return 0;
@ -369,7 +398,8 @@ static inline int put_words(uint32_t addr, uint16_t *buf, int num)
{
int i;
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf))
{
uint16_t tmp = cpu_to_le16(*buf);
if (cpu_physical_memory_rw(addr, (uint8_t*)&tmp, sizeof(tmp), 1))
return 0;
@ -497,7 +527,8 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
addr = ed->head & OHCI_DPTR_MASK;
if (!ohci_read_iso_td(ohci, addr, &iso_td)) {
if (!ohci_read_iso_td(ohci, addr, &iso_td))
{
//trace_usb_ohci_iso_td_read_failed(addr);
ohci_die(ohci);
return 1;
@ -518,10 +549,13 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
iso_td.offset[4], iso_td.offset[5],
iso_td.offset[6], iso_td.offset[7]);
*/
if (relative_frame_number < 0) {
if (relative_frame_number < 0)
{
//trace_usb_ohci_iso_td_relative_frame_number_neg(relative_frame_number);
return 1;
} else if (relative_frame_number > frame_count) {
}
else if (relative_frame_number > frame_count)
{
/* ISO TD expired - retire the TD to the Done Queue and continue with
the next ISO TD of the same ED */
//trace_usb_ohci_iso_td_relative_frame_number_big(relative_frame_number,
@ -534,7 +568,8 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
i = OHCI_BM(iso_td.flags, TD_DI);
if (i < ohci->done_count)
ohci->done_count = i;
if (!ohci_put_iso_td(ohci, addr, &iso_td)) {
if (!ohci_put_iso_td(ohci, addr, &iso_td))
{
ohci_die(ohci);
return 1;
}
@ -542,7 +577,8 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
}
dir = OHCI_BM(ed->flags, ED_D);
switch (dir) {
switch (dir)
{
case OHCI_TD_DIR_IN:
str = "in";
pid = USB_TOKEN_IN;
@ -560,7 +596,8 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
return 1;
}
if (!iso_td.bp || !iso_td.be) {
if (!iso_td.bp || !iso_td.be)
{
//trace_usb_ohci_iso_td_bad_bp_be(iso_td.bp, iso_td.be);
return 1;
}
@ -570,54 +607,70 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) ||
((relative_frame_number < frame_count) &&
!(OHCI_BM(next_offset, TD_PSW_CC) & 0xe))) {
!(OHCI_BM(next_offset, TD_PSW_CC) & 0xe)))
{
//trace_usb_ohci_iso_td_bad_cc_not_accessed(start_offset, next_offset);
return 1;
}
if ((relative_frame_number < frame_count) && (start_offset > next_offset)) {
if ((relative_frame_number < frame_count) && (start_offset > next_offset))
{
//trace_usb_ohci_iso_td_bad_cc_overrun(start_offset, next_offset);
return 1;
}
if ((start_offset & 0x1000) == 0) {
if ((start_offset & 0x1000) == 0)
{
start_addr = (iso_td.bp & OHCI_PAGE_MASK) |
(start_offset & OHCI_OFFSET_MASK);
} else {
}
else
{
start_addr = (iso_td.be & OHCI_PAGE_MASK) |
(start_offset & OHCI_OFFSET_MASK);
}
if (relative_frame_number < frame_count) {
if (relative_frame_number < frame_count)
{
end_offset = next_offset - 1;
if ((end_offset & 0x1000) == 0) {
if ((end_offset & 0x1000) == 0)
{
end_addr = (iso_td.bp & OHCI_PAGE_MASK) |
(end_offset & OHCI_OFFSET_MASK);
} else {
}
else
{
end_addr = (iso_td.be & OHCI_PAGE_MASK) |
(end_offset & OHCI_OFFSET_MASK);
}
} else {
}
else
{
/* Last packet in the ISO TD */
end_addr = iso_td.be;
}
if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK)) {
len = (end_addr & OHCI_OFFSET_MASK) + 0x1001
- (start_addr & OHCI_OFFSET_MASK);
} else {
if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK))
{
len = (end_addr & OHCI_OFFSET_MASK) + 0x1001 - (start_addr & OHCI_OFFSET_MASK);
}
else
{
len = end_addr - start_addr + 1;
}
if (len && dir != OHCI_TD_DIR_IN) {
if (len && dir != OHCI_TD_DIR_IN)
{
if (ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len,
DMA_DIRECTION_TO_DEVICE)) {
DMA_DIRECTION_TO_DEVICE))
{
ohci_die(ohci);
return 1;
}
}
if (!completion) {
if (!completion)
{
bool int_req = relative_frame_number == frame_count &&
OHCI_BM(iso_td.flags, TD_DI) == 0;
dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA));
@ -625,14 +678,18 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
usb_packet_setup(&ohci->usb_packet, pid, ep, 0, addr, false, int_req);
usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len);
usb_handle_packet(dev, &ohci->usb_packet);
if (ohci->usb_packet.status == USB_RET_ASYNC) {
if (ohci->usb_packet.status == USB_RET_ASYNC)
{
usb_device_flush_ep_queue(dev, ep);
return 1;
}
}
if (ohci->usb_packet.status == USB_RET_SUCCESS) {
if (ohci->usb_packet.status == USB_RET_SUCCESS)
{
ret = ohci->usb_packet.actual_length;
} else {
}
else
{
ret = ohci->usb_packet.status;
}
@ -640,34 +697,46 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
// str, len, ret);
/* Writeback */
if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) {
if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len)
{
/* IN transfer succeeded */
if (ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret,
DMA_DIRECTION_FROM_DEVICE)) {
DMA_DIRECTION_FROM_DEVICE))
{
ohci_die(ohci);
return 1;
}
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
OHCI_CC_NOERROR);
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret);
} else if (dir == OHCI_TD_DIR_OUT && ret == len) {
}
else if (dir == OHCI_TD_DIR_OUT && ret == len)
{
/* OUT transfer succeeded */
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
OHCI_CC_NOERROR);
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 0);
} else {
if (ret > (ssize_t) len) {
}
else
{
if (ret > (ssize_t)len)
{
//trace_usb_ohci_iso_td_data_overrun(ret, len);
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
OHCI_CC_DATAOVERRUN);
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE,
len);
} else if (ret >= 0) {
}
else if (ret >= 0)
{
//trace_usb_ohci_iso_td_data_underrun(ret);
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
OHCI_CC_DATAUNDERRUN);
} else {
switch (ret) {
}
else
{
switch (ret)
{
case USB_RET_IOERROR:
case USB_RET_NODEV:
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
@ -692,7 +761,8 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
}
}
if (relative_frame_number == frame_count) {
if (relative_frame_number == frame_count)
{
/* Last data packet of ISO TD - retire the TD to the Done Queue */
OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_NOERROR);
ed->head &= ~OHCI_DPTR_MASK;
@ -703,7 +773,8 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
if (i < ohci->done_count)
ohci->done_count = i;
}
if (!ohci_put_iso_td(ohci, addr, &iso_td)) {
if (!ohci_put_iso_td(ohci, addr, &iso_td))
{
ohci_die(ohci);
}
return 1;
@ -730,18 +801,21 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
addr = ed->head & OHCI_DPTR_MASK;
/* See if this TD has already been submitted to the device. */
completion = (addr == ohci->async_td);
if (completion && !ohci->async_complete) {
if (completion && !ohci->async_complete)
{
//trace_usb_ohci_td_skip_async();
return 1;
}
if (!ohci_read_td(ohci, addr, &td)) {
if (!ohci_read_td(ohci, addr, &td))
{
//trace_usb_ohci_td_read_error(addr);
ohci_die(ohci);
return 1;
}
dir = OHCI_BM(ed->flags, ED_D);
switch (dir) {
switch (dir)
{
case OHCI_TD_DIR_OUT:
case OHCI_TD_DIR_IN:
/* Same value. */
@ -751,7 +825,8 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
break;
}
switch (dir) {
switch (dir)
{
case OHCI_TD_DIR_IN:
str = "in";
pid = USB_TOKEN_IN;
@ -768,23 +843,31 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
//trace_usb_ohci_td_bad_direction(dir);
return 1;
}
if (td.cbp && td.be) {
if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) {
if (td.cbp && td.be)
{
if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000))
{
len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff);
} else {
}
else
{
len = (td.be - td.cbp) + 1;
}
pktlen = len;
if (len && dir != OHCI_TD_DIR_IN) {
if (len && dir != OHCI_TD_DIR_IN)
{
/* The endpoint may not allow us to transfer it all now */
pktlen = (ed->flags & OHCI_ED_MPS_MASK) >> OHCI_ED_MPS_SHIFT;
if (pktlen > len) {
if (pktlen > len)
{
pktlen = len;
}
if (!completion) {
if (!completion)
{
if (ohci_copy_td(ohci, &td, ohci->usb_buf, pktlen,
DMA_DIRECTION_TO_DEVICE)) {
DMA_DIRECTION_TO_DEVICE))
{
ohci_die(ohci);
}
}
@ -796,11 +879,15 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
// flag_r, td.cbp, td.be);
//ohci_td_pkt("OUT", ohci->usb_buf, pktlen);
if (completion) {
if (completion)
{
ohci->async_td = 0;
ohci->async_complete = false;
} else {
if (ohci->async_td) {
}
else
{
if (ohci->async_td)
{
/* ??? The hardware should allow one active packet per
endpoint. We only allow one active packet per controller.
This should be sufficient as long as devices respond in a
@ -817,39 +904,55 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
usb_handle_packet(dev, &ohci->usb_packet);
//trace_usb_ohci_td_packet_status(ohci->usb_packet.status);
if (ohci->usb_packet.status == USB_RET_ASYNC) {
if (ohci->usb_packet.status == USB_RET_ASYNC)
{
usb_device_flush_ep_queue(dev, ep);
ohci->async_td = addr;
return 1;
}
}
if (ohci->usb_packet.status == USB_RET_SUCCESS) {
if (ohci->usb_packet.status == USB_RET_SUCCESS)
{
ret = ohci->usb_packet.actual_length;
} else {
}
else
{
ret = ohci->usb_packet.status;
}
if (ret >= 0) {
if (dir == OHCI_TD_DIR_IN) {
if (ret >= 0)
{
if (dir == OHCI_TD_DIR_IN)
{
if (ohci_copy_td(ohci, &td, ohci->usb_buf, ret,
DMA_DIRECTION_FROM_DEVICE)) {
DMA_DIRECTION_FROM_DEVICE))
{
ohci_die(ohci);
}
//ohci_td_pkt("IN", ohci->usb_buf, pktlen);
} else {
}
else
{
ret = pktlen;
}
}
/* Writeback */
if (ret == pktlen || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) {
if (ret == pktlen || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r))
{
/* Transmission succeeded. */
if (ret == len) {
if (ret == len)
{
td.cbp = 0;
} else {
if ((td.cbp & 0xfff) + ret > 0xfff) {
}
else
{
if ((td.cbp & 0xfff) + ret > 0xfff)
{
td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);
} else {
}
else
{
td.cbp += ret;
}
}
@ -858,7 +961,8 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR);
OHCI_SET_BM(td.flags, TD_EC, 0);
if ((dir != OHCI_TD_DIR_IN) && (ret != len)) {
if ((dir != OHCI_TD_DIR_IN) && (ret != len))
{
/* Partial packet transfer: TD not ready to retire yet */
goto exit_no_retire;
}
@ -867,12 +971,18 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
ed->head &= ~OHCI_ED_C;
if (td.flags & OHCI_TD_T0)
ed->head |= OHCI_ED_C;
} else {
if (ret >= 0) {
}
else
{
if (ret >= 0)
{
//trace_usb_ohci_td_underrun();
OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN);
} else {
switch (ret) {
}
else
{
switch (ret)
{
case USB_RET_IOERROR:
case USB_RET_NODEV:
//trace_usb_ohci_td_dev_error();
@ -911,7 +1021,8 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
if (i < ohci->done_count)
ohci->done_count = i;
exit_no_retire:
if (!ohci_put_td(ohci, addr, &td)) {
if (!ohci_put_td(ohci, addr, &td))
{
ohci_die(ohci);
return 1;
}
@ -931,8 +1042,10 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
if (head == 0)
return 0;
for (cur = head; cur; cur = next_ed) {
if (!ohci_read_ed(ohci, cur, &ed)) {
for (cur = head; cur; cur = next_ed)
{
if (!ohci_read_ed(ohci, cur, &ed))
{
//trace_usb_ohci_ed_read_error(cur);
ohci_die(ohci);
return 0;
@ -940,16 +1053,19 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
next_ed = ed.next & OHCI_DPTR_MASK;
if (++link_cnt > ED_LINK_LIMIT) {
if (++link_cnt > ED_LINK_LIMIT)
{
ohci_die(ohci);
return 0;
}
if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K))
{
uint32_t addr;
/* Cancel pending packets for ED that have been paused. */
addr = ed.head & OHCI_DPTR_MASK;
if (ohci->async_td && addr == ohci->async_td) {
if (ohci->async_td && addr == ohci->async_td)
{
usb_cancel_packet(&ohci->usb_packet);
ohci->async_td = 0;
usb_device_ep_stopped(ohci->usb_packet.ep->dev,
@ -958,7 +1074,8 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
continue;
}
while ((ed.head & OHCI_DPTR_MASK) != ed.tail) {
while ((ed.head & OHCI_DPTR_MASK) != ed.tail)
{
/*trace_usb_ohci_ed_pkt(cur, (ed.head & OHCI_ED_H) != 0,
(ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK,
ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK);
@ -970,17 +1087,21 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
active = 1;
if ((ed.flags & OHCI_ED_F) == 0) {
if ((ed.flags & OHCI_ED_F) == 0)
{
if (ohci_service_td(ohci, &ed))
break;
} else {
}
else
{
/* Handle isochronous endpoints */
if (ohci_service_iso_td(ohci, &ed, completion))
break;
}
}
if (!ohci_put_ed(ohci, cur, &ed)) {
if (!ohci_put_ed(ohci, cur, &ed))
{
ohci_die(ohci);
return 0;
}
@ -1000,18 +1121,23 @@ static void ohci_sof(OHCIState *ohci)
/* Process Control and Bulk lists. */
static void ohci_process_lists(OHCIState* ohci, int completion)
{
if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) {
if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head) {
if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF))
{
if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head)
{
OSDebugOut(TEXT("usb-ohci: head %x, cur %x\n"), ohci->ctrl_head, ohci->ctrl_cur);
}
if (!ohci_service_ed_list(ohci, ohci->ctrl_head, completion)) {
if (!ohci_service_ed_list(ohci, ohci->ctrl_head, completion))
{
ohci->ctrl_cur = 0;
ohci->status &= ~OHCI_STATUS_CLF;
}
}
if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) {
if (!ohci_service_ed_list(ohci, ohci->bulk_head, completion)) {
if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF))
{
if (!ohci_service_ed_list(ohci, ohci->bulk_head, completion))
{
ohci->bulk_cur = 0;
ohci->status &= ~OHCI_STATUS_BLF;
}
@ -1030,10 +1156,12 @@ void ohci_frame_boundary(void *opaque)
/* if reset bit was set, don't process possibly invalid descriptors */
/* TODO intr_status is interrupts that driver wants, so not quite right to us it here */
bool hack = false; // ohci->intr_status & ohci->intr & OHCI_INTR_RHSC;
if (hack) OSDebugOut(TEXT("skipping PLE\n"));
if (hack)
OSDebugOut(TEXT("skipping PLE\n"));
/* Process all the lists at the end of the frame */
if ((ohci->ctl & OHCI_CTL_PLE) && !hack) {
if ((ohci->ctl & OHCI_CTL_PLE) && !hack)
{
int n;
n = ohci->frame_number & 0x1f;
@ -1041,8 +1169,10 @@ void ohci_frame_boundary(void *opaque)
}
/* Cancel all pending packets if either of the lists has been disabled. */
if (ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
if (ohci->async_td) {
if (ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE))
{
if (ohci->async_td)
{
usb_cancel_packet(&ohci->usb_packet);
ohci->async_td = 0;
}
@ -1053,7 +1183,8 @@ void ohci_frame_boundary(void *opaque)
ohci_process_lists(ohci, 0);
/* Stop if UnrecoverableError happened or ohci_sof will crash */
if (ohci->intr_status & OHCI_INTR_UE) {
if (ohci->intr_status & OHCI_INTR_UE)
{
return;
}
@ -1064,7 +1195,8 @@ void ohci_frame_boundary(void *opaque)
ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
hcca.frame = cpu_to_le16(ohci->frame_number);
if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD))
{
if (!ohci->done)
abort();
if (ohci->intr & ohci->intr_status)
@ -1121,9 +1253,11 @@ static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val)
/* If CurrentConnectStatus is cleared we set
* ConnectStatusChange
*/
if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) {
if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS))
{
ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
if (ohci->rhstatus & OHCI_RHS_DRWE) {
if (ohci->rhstatus & OHCI_RHS_DRWE)
{
/* TODO: CSC is a wakeup event */
}
return 0;
@ -1143,7 +1277,8 @@ static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val)
{
val &= OHCI_FMI_FI;
if (val != ohci->fi) {
if (val != ohci->fi)
{
OSDebugOut(TEXT("usb-ohci: FrameInterval = 0x%x (%u)\n"), ohci->fi, ohci->fi);
}
@ -1152,9 +1287,12 @@ static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val)
static void ohci_port_power(OHCIState* ohci, int i, int p)
{
if (p) {
if (p)
{
ohci->rhport[i].ctrl |= OHCI_PORT_PPS;
} else {
}
else
{
ohci->rhport[i].ctrl &= ~(OHCI_PORT_PPS |
OHCI_PORT_CCS |
OHCI_PORT_PSS |
@ -1176,7 +1314,8 @@ static void ohci_set_ctl(OHCIState *ohci, uint32_t val)
if (old_state == new_state)
return;
switch (new_state) {
switch (new_state)
{
case OHCI_USB_OPERATIONAL:
ohci_bus_start(ohci);
break;
@ -1234,7 +1373,8 @@ static void ohci_set_hub_status(OHCIState *ohci, uint32_t val)
if (val & OHCI_RHS_OCIC)
ohci->rhstatus &= ~OHCI_RHS_OCIC;
if (val & OHCI_RHS_LPS) {
if (val & OHCI_RHS_LPS)
{
int i;
for (i = 0; i < ohci->num_ports; i++)
@ -1242,7 +1382,8 @@ static void ohci_set_hub_status(OHCIState *ohci, uint32_t val)
OSDebugOut(TEXT("usb-ohci: powered down all ports\n"));
}
if (val & OHCI_RHS_LPSC) {
if (val & OHCI_RHS_LPSC)
{
int i;
for (i = 0; i < ohci->num_ports; i++)
@ -1278,11 +1419,13 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PES);
if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PSS)) {
if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PSS))
{
OSDebugOut(TEXT("usb-ohci: port %d: SUSPEND\n"), portnum);
}
if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) {
if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS))
{
OSDebugOut(TEXT("usb-ohci: port %d: RESET\n"), portnum);
usb_device_reset(port->port.dev);
port->ctrl &= ~OHCI_PORT_PRS;
@ -1309,19 +1452,22 @@ uint32_t ohci_mem_read(OHCIState *ptr, uint32_t addr)
addr -= ohci->mem_base;
/* Only aligned reads are allowed on OHCI */
if (addr & 3) {
if (addr & 3)
{
OSDebugOut(TEXT("usb-ohci: Mis-aligned read\n"));
return 0xffffffff;
}
if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) {
if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4)
{
/* HcRhPortStatus */
return ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS;
}
#ifdef DEBUG_OHCI
OSDebugOut(TEXT("ohci_mem_read: addr %d\n"), addr >> 2);
#endif
switch (addr >> 2) {
switch (addr >> 2)
{
case 0: /* HcRevision */
return 0x10;
@ -1396,12 +1542,14 @@ void ohci_mem_write(OHCIState *ptr,uint32_t addr, uint32_t val)
addr -= ohci->mem_base;
/* Only aligned reads are allowed on OHCI */
if (addr & 3) {
if (addr & 3)
{
fprintf(stderr, "usb-ohci: Mis-aligned write\n");
return;
}
if ((addr >= 0x54) && (addr < (0x54 + ohci->num_ports * 4))) {
if ((addr >= 0x54) && (addr < (0x54 + ohci->num_ports * 4)))
{
/* HcRhPortStatus */
OSDebugOut(TEXT("ohci_port_set_status: %d = 0x%08x\n"), (addr - 0x54) >> 2, val);
ohci_port_set_status(ohci, (addr - 0x54) >> 2, val);
@ -1410,7 +1558,8 @@ void ohci_mem_write(OHCIState *ptr,uint32_t addr, uint32_t val)
#ifdef DEBUG_OHCI
OSDebugOut(TEXT("ohci_mem_write: addr %d = 0x%08x\n"), addr >> 2, val);
#endif
switch (addr >> 2) {
switch (addr >> 2)
{
case 1: /* HcControl */
ohci_set_ctl(ohci, val);
break;
@ -1497,7 +1646,8 @@ static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev)
{
if (ohci->async_td &&
usb_packet_is_inflight(&ohci->usb_packet) &&
ohci->usb_packet.ep->dev == dev) {
ohci->usb_packet.ep->dev == dev)
{
usb_cancel_packet(&ohci->usb_packet);
ohci->async_td = 0;
}
@ -1511,13 +1661,13 @@ static USBPortOps ohci_port_ops = {
//.complete = ohci_async_complete_packet,
};
static USBBusOps ohci_bus_ops = {
};
static USBBusOps ohci_bus_ops = {};
OHCIState* ohci_create(uint32_t base, int ports)
{
OHCIState* ohci = (OHCIState*)malloc(sizeof(OHCIState));
if(!ohci) return NULL;
if (!ohci)
return NULL;
int i;
const int ticks_per_sec = get_ticks_per_second();
@ -1526,15 +1676,19 @@ OHCIState *ohci_create(uint32_t base, int ports)
ohci->mem_base = base;
if (usb_frame_time == 0) {
if (usb_frame_time == 0)
{
#if OHCI_TIME_WARP
usb_frame_time = ticks_per_sec;
usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ / 1000);
#else
usb_frame_time = muldiv64(1, ticks_per_sec, 1000);
if (ticks_per_sec >= USB_HZ) {
if (ticks_per_sec >= USB_HZ)
{
usb_bit_time = muldiv64(1, ticks_per_sec, USB_HZ);
} else {
}
else
{
usb_bit_time = 1;
}
#endif
@ -1543,7 +1697,8 @@ OHCIState *ohci_create(uint32_t base, int ports)
}
ohci->num_ports = ports;
for (i = 0; i < ports; i++) {
for (i = 0; i < ports; i++)
{
memset(&(ohci->rhport[i].port), 0, sizeof(USBPort));
ohci->rhport[i].port.opaque = ohci;
ohci->rhport[i].port.index = i;

View File

@ -18,9 +18,11 @@
/* compute with 96 bit intermediate result: (a*b)/c */
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
{
union {
union
{
uint64_t ll;
struct {
struct
{
#ifdef WORDS_BIGENDIAN
uint32_t high, low;
#else

View File

@ -67,9 +67,11 @@
// Portable atomic fences implemented below:
namespace moodycamel {
namespace moodycamel
{
enum memory_order {
enum memory_order
{
memory_order_relaxed,
memory_order_acquire,
memory_order_release,
@ -109,17 +111,29 @@ enum memory_order {
#endif
#endif
namespace moodycamel {
namespace moodycamel
{
AE_FORCEINLINE void compiler_fence(memory_order order)
{
switch (order) {
case memory_order_relaxed: break;
case memory_order_acquire: _ReadBarrier(); break;
case memory_order_release: _WriteBarrier(); break;
case memory_order_acq_rel: _ReadWriteBarrier(); break;
case memory_order_seq_cst: _ReadWriteBarrier(); break;
default: assert(false);
switch (order)
{
case memory_order_relaxed:
break;
case memory_order_acquire:
_ReadBarrier();
break;
case memory_order_release:
_WriteBarrier();
break;
case memory_order_acq_rel:
_ReadWriteBarrier();
break;
case memory_order_seq_cst:
_ReadWriteBarrier();
break;
default:
assert(false);
}
}
@ -129,24 +143,34 @@ AE_FORCEINLINE void compiler_fence(memory_order order)
#if defined(AE_ARCH_X86) || defined(AE_ARCH_X64)
AE_FORCEINLINE void fence(memory_order order)
{
switch (order) {
case memory_order_relaxed: break;
case memory_order_acquire: _ReadBarrier(); break;
case memory_order_release: _WriteBarrier(); break;
case memory_order_acq_rel: _ReadWriteBarrier(); break;
switch (order)
{
case memory_order_relaxed:
break;
case memory_order_acquire:
_ReadBarrier();
break;
case memory_order_release:
_WriteBarrier();
break;
case memory_order_acq_rel:
_ReadWriteBarrier();
break;
case memory_order_seq_cst:
_ReadWriteBarrier();
AeFullSync();
_ReadWriteBarrier();
break;
default: assert(false);
default:
assert(false);
}
}
#else
AE_FORCEINLINE void fence(memory_order order)
{
// Non-specialized arch, use heavier memory barriers everywhere just in case :-(
switch (order) {
switch (order)
{
case memory_order_relaxed:
break;
case memory_order_acquire:
@ -169,7 +193,8 @@ AE_FORCEINLINE void fence(memory_order order)
AeFullSync();
_ReadWriteBarrier();
break;
default: assert(false);
default:
assert(false);
}
}
#endif
@ -178,29 +203,52 @@ AE_FORCEINLINE void fence(memory_order order)
// Use standard library of atomics
#include <atomic>
namespace moodycamel {
namespace moodycamel
{
AE_FORCEINLINE void compiler_fence(memory_order order)
{
switch (order) {
case memory_order_relaxed: break;
case memory_order_acquire: std::atomic_signal_fence(std::memory_order_acquire); break;
case memory_order_release: std::atomic_signal_fence(std::memory_order_release); break;
case memory_order_acq_rel: std::atomic_signal_fence(std::memory_order_acq_rel); break;
case memory_order_seq_cst: std::atomic_signal_fence(std::memory_order_seq_cst); break;
default: assert(false);
switch (order)
{
case memory_order_relaxed:
break;
case memory_order_acquire:
std::atomic_signal_fence(std::memory_order_acquire);
break;
case memory_order_release:
std::atomic_signal_fence(std::memory_order_release);
break;
case memory_order_acq_rel:
std::atomic_signal_fence(std::memory_order_acq_rel);
break;
case memory_order_seq_cst:
std::atomic_signal_fence(std::memory_order_seq_cst);
break;
default:
assert(false);
}
}
AE_FORCEINLINE void fence(memory_order order)
{
switch (order) {
case memory_order_relaxed: break;
case memory_order_acquire: std::atomic_thread_fence(std::memory_order_acquire); break;
case memory_order_release: std::atomic_thread_fence(std::memory_order_release); break;
case memory_order_acq_rel: std::atomic_thread_fence(std::memory_order_acq_rel); break;
case memory_order_seq_cst: std::atomic_thread_fence(std::memory_order_seq_cst); break;
default: assert(false);
switch (order)
{
case memory_order_relaxed:
break;
case memory_order_acquire:
std::atomic_thread_fence(std::memory_order_acquire);
break;
case memory_order_release:
std::atomic_thread_fence(std::memory_order_release);
break;
case memory_order_acq_rel:
std::atomic_thread_fence(std::memory_order_acq_rel);
break;
case memory_order_seq_cst:
std::atomic_thread_fence(std::memory_order_seq_cst);
break;
default:
assert(false);
}
}
@ -222,7 +270,8 @@ AE_FORCEINLINE void fence(memory_order order)
// Provides basic support for atomic variables -- no memory ordering guarantees are provided.
// The guarantee of atomicity is only made for types that already have atomic load and store guarantees
// at the hardware level -- on most platforms this generally means aligned pointers and integers (only).
namespace moodycamel {
namespace moodycamel
{
template <typename T>
class weak_atomic
{
@ -232,32 +281,59 @@ public:
#pragma warning(push)
#pragma warning(disable : 4100) // Get rid of (erroneous) 'unreferenced formal parameter' warning
#endif
template<typename U> weak_atomic(U&& x) : value(std::forward<U>(x)) { }
template <typename U>
weak_atomic(U&& x)
: value(std::forward<U>(x))
{
}
#ifdef __cplusplus_cli
// Work around bug with universal reference/nullptr combination that only appears when /clr is on
weak_atomic(nullptr_t) : value(nullptr) { }
weak_atomic(nullptr_t)
: value(nullptr)
{
}
#endif
weak_atomic(weak_atomic const& other) : value(other.value) { }
weak_atomic(weak_atomic&& other) : value(std::move(other.value)) { }
weak_atomic(weak_atomic const& other)
: value(other.value)
{
}
weak_atomic(weak_atomic&& other)
: value(std::move(other.value))
{
}
#ifdef AE_VCPP
#pragma warning(pop)
#endif
AE_FORCEINLINE operator T() const { return load(); }
AE_FORCEINLINE operator T() const
{
return load();
}
#ifndef AE_USE_STD_ATOMIC_FOR_WEAK_ATOMIC
template<typename U> AE_FORCEINLINE weak_atomic const& operator=(U&& x) { value = std::forward<U>(x); return *this; }
AE_FORCEINLINE weak_atomic const& operator=(weak_atomic const& other) { value = other.value; return *this; }
template <typename U>
AE_FORCEINLINE weak_atomic const& operator=(U&& x)
{
value = std::forward<U>(x);
return *this;
}
AE_FORCEINLINE weak_atomic const& operator=(weak_atomic const& other)
{
value = other.value;
return *this;
}
AE_FORCEINLINE T load() const { return value; }
AE_FORCEINLINE T fetch_add_acquire(T increment)
{
#if defined(AE_ARCH_X64) || defined(AE_ARCH_X86)
if (sizeof(T) == 4) return _InterlockedExchangeAdd((long volatile*)&value, (long)increment);
if (sizeof(T) == 4)
return _InterlockedExchangeAdd((long volatile*)&value, (long)increment);
#if defined(_M_AMD64)
else if (sizeof(T) == 8) return _InterlockedExchangeAdd64((long long volatile*)&value, (long long)increment);
else if (sizeof(T) == 8)
return _InterlockedExchangeAdd64((long long volatile*)&value, (long long)increment);
#endif
#else
#error Unsupported platform
@ -269,9 +345,11 @@ public:
AE_FORCEINLINE T fetch_add_release(T increment)
{
#if defined(AE_ARCH_X64) || defined(AE_ARCH_X86)
if (sizeof(T) == 4) return _InterlockedExchangeAdd((long volatile*)&value, (long)increment);
if (sizeof(T) == 4)
return _InterlockedExchangeAdd((long volatile*)&value, (long)increment);
#if defined(_M_AMD64)
else if (sizeof(T) == 8) return _InterlockedExchangeAdd64((long long volatile*)&value, (long long)increment);
else if (sizeof(T) == 8)
return _InterlockedExchangeAdd64((long long volatile*)&value, (long long)increment);
#endif
#else
#error Unsupported platform
@ -503,14 +581,14 @@ namespace moodycamel
do
{
rc = sem_wait(&m_sema);
}
while (rc == -1 && errno == EINTR);
} while (rc == -1 && errno == EINTR);
}
bool try_wait()
{
int rc;
do {
do
{
rc = sem_trywait(&m_sema);
} while (rc == -1 && errno == EINTR);
return !(rc == -1 && errno == EAGAIN);
@ -526,13 +604,15 @@ namespace moodycamel
ts.tv_nsec += (usecs % usecs_in_1_sec) * 1000;
// sem_timedwait bombs if you have more than 1e9 in tv_nsec
// so we have to clean things up before passing it in
if (ts.tv_nsec >= nsecs_in_1_sec) {
if (ts.tv_nsec >= nsecs_in_1_sec)
{
ts.tv_nsec -= nsecs_in_1_sec;
++ts.tv_sec;
}
int rc;
do {
do
{
rc = sem_timedwait(&m_sema, &ts);
} while (rc == -1 && errno == EINTR);
return !(rc == -1 && errno == ETIMEDOUT);
@ -611,7 +691,8 @@ namespace moodycamel
}
public:
LightweightSemaphore(ssize_t initialCount = 0) : m_count(initialCount)
LightweightSemaphore(ssize_t initialCount = 0)
: m_count(initialCount)
{
assert(initialCount >= 0);
}

View File

@ -53,7 +53,8 @@
#pragma warning(disable : 4127) // conditional expression is constant
#endif
namespace moodycamel {
namespace moodycamel
{
template <typename T, size_t MAX_BLOCK_SIZE = 512>
class ReaderWriterQueue
@ -98,7 +99,8 @@ public:
Block* firstBlock = nullptr;
largestBlockSize = ceilToPow2(maxSize + 1); // We need a spare slot to fit maxSize elements in the block
if (largestBlockSize > MAX_BLOCK_SIZE * 2) {
if (largestBlockSize > MAX_BLOCK_SIZE * 2)
{
// We need a spare block in case the producer is writing to a different block the consumer is reading from, and
// wants to enqueue the maximum number of elements. We also need a spare element in each block to avoid the ambiguity
// between front == tail meaning "empty" and "full".
@ -107,28 +109,34 @@ public:
size_t initialBlockCount = (maxSize + MAX_BLOCK_SIZE * 2 - 3) / (MAX_BLOCK_SIZE - 1);
largestBlockSize = MAX_BLOCK_SIZE;
Block* lastBlock = nullptr;
for (size_t i = 0; i != initialBlockCount; ++i) {
for (size_t i = 0; i != initialBlockCount; ++i)
{
auto block = make_block(largestBlockSize);
if (block == nullptr) {
if (block == nullptr)
{
#ifdef MOODYCAMEL_EXCEPTIONS_ENABLED
throw std::bad_alloc();
#else
abort();
#endif
}
if (firstBlock == nullptr) {
if (firstBlock == nullptr)
{
firstBlock = block;
}
else {
else
{
lastBlock->next = block;
}
lastBlock = block;
block->next = firstBlock;
}
}
else {
else
{
firstBlock = make_block(largestBlockSize);
if (firstBlock == nullptr) {
if (firstBlock == nullptr)
{
#ifdef MOODYCAMEL_EXCEPTIONS_ENABLED
throw std::bad_alloc();
#else
@ -147,9 +155,9 @@ public:
// Note: The queue should not be accessed concurrently while it's
// being moved. It's up to the user to synchronize this.
ReaderWriterQueue(ReaderWriterQueue&& other)
: frontBlock(other.frontBlock.load()),
tailBlock(other.tailBlock.load()),
largestBlockSize(other.largestBlockSize)
: frontBlock(other.frontBlock.load())
, tailBlock(other.tailBlock.load())
, largestBlockSize(other.largestBlockSize)
#ifndef NDEBUG
, enqueuing(false)
, dequeuing(false)
@ -157,7 +165,8 @@ public:
{
other.largestBlockSize = 32;
Block* b = other.make_block(other.largestBlockSize);
if (b == nullptr) {
if (b == nullptr)
{
#ifdef MOODYCAMEL_EXCEPTIONS_ENABLED
throw std::bad_alloc();
#else
@ -193,12 +202,14 @@ public:
// Destroy any remaining objects in queue and free memory
Block* frontBlock_ = frontBlock;
Block* block = frontBlock_;
do {
do
{
Block* nextBlock = block->next;
size_t blockFront = block->front;
size_t blockTail = block->tail;
for (size_t i = blockFront; i != blockTail; i = (i + 1) & block->sizeMask) {
for (size_t i = blockFront; i != blockTail; i = (i + 1) & block->sizeMask)
{
auto element = reinterpret_cast<T*>(block->data + i * sizeof(T));
element->~T();
(void)element;
@ -293,7 +304,8 @@ public:
size_t blockTail = frontBlock_->localTail;
size_t blockFront = frontBlock_->front.load();
if (blockFront != blockTail || blockFront != (frontBlock_->localTail = frontBlock_->tail.load())) {
if (blockFront != blockTail || blockFront != (frontBlock_->localTail = frontBlock_->tail.load()))
{
fence(memory_order_acquire);
non_empty_front_block:
@ -307,7 +319,8 @@ public:
fence(memory_order_release);
frontBlock_->front = blockFront;
}
else if (frontBlock_ != tailBlock.load()) {
else if (frontBlock_ != tailBlock.load())
{
fence(memory_order_acquire);
frontBlock_ = frontBlock.load();
@ -315,7 +328,8 @@ public:
blockFront = frontBlock_->front.load();
fence(memory_order_acquire);
if (blockFront != blockTail) {
if (blockFront != blockTail)
{
// Oh look, the front block isn't empty after all
goto non_empty_front_block;
}
@ -351,7 +365,8 @@ public:
fence(memory_order_release);
frontBlock_->front = nextBlockFront;
}
else {
else
{
// No elements in current block and no other block to advance to
return false;
}
@ -376,19 +391,22 @@ public:
size_t blockTail = frontBlock_->localTail;
size_t blockFront = frontBlock_->front.load();
if (blockFront != blockTail || blockFront != (frontBlock_->localTail = frontBlock_->tail.load())) {
if (blockFront != blockTail || blockFront != (frontBlock_->localTail = frontBlock_->tail.load()))
{
fence(memory_order_acquire);
non_empty_front_block:
return reinterpret_cast<T*>(frontBlock_->data + blockFront * sizeof(T));
}
else if (frontBlock_ != tailBlock.load()) {
else if (frontBlock_ != tailBlock.load())
{
fence(memory_order_acquire);
frontBlock_ = frontBlock.load();
blockTail = frontBlock_->localTail = frontBlock_->tail.load();
blockFront = frontBlock_->front.load();
fence(memory_order_acquire);
if (blockFront != blockTail) {
if (blockFront != blockTail)
{
goto non_empty_front_block;
}
@ -418,7 +436,8 @@ public:
size_t blockTail = frontBlock_->localTail;
size_t blockFront = frontBlock_->front.load();
if (blockFront != blockTail || blockFront != (frontBlock_->localTail = frontBlock_->tail.load())) {
if (blockFront != blockTail || blockFront != (frontBlock_->localTail = frontBlock_->tail.load()))
{
fence(memory_order_acquire);
non_empty_front_block:
@ -430,14 +449,16 @@ public:
fence(memory_order_release);
frontBlock_->front = blockFront;
}
else if (frontBlock_ != tailBlock.load()) {
else if (frontBlock_ != tailBlock.load())
{
fence(memory_order_acquire);
frontBlock_ = frontBlock.load();
blockTail = frontBlock_->localTail = frontBlock_->tail.load();
blockFront = frontBlock_->front.load();
fence(memory_order_acquire);
if (blockFront != blockTail) {
if (blockFront != blockTail)
{
goto non_empty_front_block;
}
@ -464,7 +485,8 @@ public:
fence(memory_order_release);
frontBlock_->front = nextBlockFront;
}
else {
else
{
// No elements in current block and no other block to advance to
return false;
}
@ -479,7 +501,8 @@ public:
size_t result = 0;
Block* frontBlock_ = frontBlock.load();
Block* block = frontBlock_;
do {
do
{
fence(memory_order_acquire);
size_t blockFront = block->front.load();
size_t blockTail = block->tail.load();
@ -491,7 +514,11 @@ public:
private:
enum AllocationMode { CanAlloc, CannotAlloc };
enum AllocationMode
{
CanAlloc,
CannotAlloc
};
#if MOODYCAMEL_HAS_EMPLACE
template <AllocationMode canAlloc, typename... Args>
@ -517,7 +544,8 @@ private:
size_t blockTail = tailBlock_->tail.load();
size_t nextBlockTail = (blockTail + 1) & tailBlock_->sizeMask;
if (nextBlockTail != blockFront || nextBlockTail != (tailBlock_->localFront = tailBlock_->front.load())) {
if (nextBlockTail != blockFront || nextBlockTail != (tailBlock_->localFront = tailBlock_->front.load()))
{
fence(memory_order_acquire);
// This block has room for at least one more element
char* location = tailBlock_->data + blockTail * sizeof(T);
@ -530,9 +558,11 @@ private:
fence(memory_order_release);
tailBlock_->tail = nextBlockTail;
}
else {
else
{
fence(memory_order_acquire);
if (tailBlock_->next.load() != frontBlock) {
if (tailBlock_->next.load() != frontBlock)
{
// Note that the reason we can't advance to the frontBlock and start adding new entries there
// is because if we did, then dequeue would stay in that block, eventually reading the new values,
// instead of advancing to the next full block (whose values were enqueued first and so should be
@ -563,11 +593,13 @@ private:
fence(memory_order_release);
tailBlock = tailBlockNext;
}
else if (canAlloc == CanAlloc) {
else if (canAlloc == CanAlloc)
{
// tailBlock is full and there's no free block ahead; create a new block
auto newBlockSize = largestBlockSize >= MAX_BLOCK_SIZE ? largestBlockSize : largestBlockSize * 2;
auto newBlock = make_block(newBlockSize);
if (newBlock == nullptr) {
if (newBlock == nullptr)
{
// Could not allocate a block!
return false;
}
@ -593,11 +625,13 @@ private:
fence(memory_order_release);
tailBlock = newBlock;
}
else if (canAlloc == CannotAlloc) {
else if (canAlloc == CannotAlloc)
{
// Would have had to allocate a new block to enqueue, but not allowed
return false;
}
else {
else
{
assert(false && "Should be unreachable code");
return false;
}
@ -622,7 +656,8 @@ private:
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
for (size_t i = 1; i < sizeof(size_t); i <<= 1) {
for (size_t i = 1; i < sizeof(size_t); i <<= 1)
{
x |= x >> (i << 3);
}
++x;
@ -635,6 +670,7 @@ private:
const std::size_t alignment = std::alignment_of<U>::value;
return ptr + (alignment - (reinterpret_cast<std::uintptr_t>(ptr) % alignment)) % alignment;
}
private:
#ifndef NDEBUG
struct ReentrantGuard
@ -676,7 +712,14 @@ private:
// size must be a power of two (and greater than 0)
Block(size_t const& _size, char* _rawThis, char* _data)
: front(0), localTail(0), tail(0), localFront(0), next(nullptr), data(_data), sizeMask(_size - 1), rawThis(_rawThis)
: front(0)
, localTail(0)
, tail(0)
, localFront(0)
, next(nullptr)
, data(_data)
, sizeMask(_size - 1)
, rawThis(_rawThis)
{
}
@ -695,7 +738,8 @@ private:
auto size = sizeof(Block) + std::alignment_of<Block>::value - 1;
size += sizeof(T) * capacity + std::alignment_of<T>::value - 1;
auto newBlockRaw = static_cast<char*>(std::malloc(size));
if (newBlockRaw == nullptr) {
if (newBlockRaw == nullptr)
{
return nullptr;
}
@ -728,7 +772,8 @@ private:
public:
explicit BlockingReaderWriterQueue(size_t maxSize = 15)
: inner(maxSize)
{ }
{
}
// Enqueues a copy of element if there is room in the queue.
@ -736,7 +781,8 @@ public:
// Does not allocate memory.
AE_FORCEINLINE bool try_enqueue(T const& element)
{
if (inner.try_enqueue(element)) {
if (inner.try_enqueue(element))
{
sema.signal();
return true;
}
@ -748,7 +794,8 @@ public:
// Does not allocate memory.
AE_FORCEINLINE bool try_enqueue(T&& element)
{
if (inner.try_enqueue(std::forward<T>(element))) {
if (inner.try_enqueue(std::forward<T>(element)))
{
sema.signal();
return true;
}
@ -761,7 +808,8 @@ public:
// Only fails (returns false) if memory allocation fails.
AE_FORCEINLINE bool enqueue(T const& element)
{
if (inner.enqueue(element)) {
if (inner.enqueue(element))
{
sema.signal();
return true;
}
@ -773,7 +821,8 @@ public:
// Only fails (returns false) if memory allocation fails.
AE_FORCEINLINE bool enqueue(T&& element)
{
if (inner.enqueue(std::forward<T>(element))) {
if (inner.enqueue(std::forward<T>(element)))
{
sema.signal();
return true;
}
@ -787,7 +836,8 @@ public:
template <typename U>
bool try_dequeue(U& result)
{
if (sema.tryWait()) {
if (sema.tryWait())
{
bool success = inner.try_dequeue(result);
assert(success);
AE_UNUSED(success);
@ -819,7 +869,8 @@ public:
template <typename U>
bool wait_dequeue_timed(U& result, std::int64_t timeout_usecs)
{
if (!sema.wait(timeout_usecs)) {
if (!sema.wait(timeout_usecs))
{
return false;
}
bool success = inner.try_dequeue(result);
@ -860,7 +911,8 @@ public:
// `pop` was called.
AE_FORCEINLINE bool pop()
{
if (sema.tryWait()) {
if (sema.tryWait())
{
bool result = inner.pop();
assert(result);
AE_UNUSED(result);

View File

@ -33,12 +33,15 @@ _HidD_GetProductString HidD_GetProductString = NULL;
static HMODULE hModHid = 0;
int InitHid() {
if (hModHid) {
int InitHid()
{
if (hModHid)
{
return 1;
}
hModHid = LoadLibraryA("hid.dll");
if (hModHid) {
if (hModHid)
{
if ((HidD_GetHidGuid = (_HidD_GetHidGuid)GetProcAddress(hModHid, "HidD_GetHidGuid")) &&
(HidD_GetAttributes = (_HidD_GetAttributes)GetProcAddress(hModHid, "HidD_GetAttributes")) &&
(HidD_GetPreparsedData = (_HidD_GetPreparsedData)GetProcAddress(hModHid, "HidD_GetPreparsedData")) &&
@ -51,7 +54,8 @@ int InitHid() {
(HidP_GetUsageValue = (_HidP_GetUsageValue)GetProcAddress(hModHid, "HidP_GetUsageValue")) &&
(HidD_GetProductString = (_HidD_GetProductString)GetProcAddress(hModHid, "HidD_GetProductString")) &&
(HidD_GetFeature = (_HidD_GetFeature)GetProcAddress(hModHid, "HidD_GetFeature")) &&
(HidD_SetFeature = (_HidD_SetFeature)GetProcAddress(hModHid, "HidD_SetFeature"))) {
(HidD_SetFeature = (_HidD_SetFeature)GetProcAddress(hModHid, "HidD_SetFeature")))
{
//pHidD_GetHidGuid(&GUID_DEVINTERFACE_HID);
return 1;
}
@ -60,8 +64,10 @@ int InitHid() {
return 0;
}
void UninitHid() {
if (hModHid) {
void UninitHid()
{
if (hModHid)
{
FreeLibrary(hModHid);
hModHid = 0;
}

View File

@ -309,14 +309,17 @@ typedef struct _HIDP_BUTTON_CAPS
BOOLEAN IsAbsolute;
ULONG Reserved[10];
union {
struct {
union
{
struct
{
USAGE UsageMin, UsageMax;
USHORT StringMin, StringMax;
USHORT DesignatorMin, DesignatorMax;
USHORT DataIndexMin, DataIndexMax;
} Range;
struct {
struct
{
USAGE Usage, Reserved1;
USHORT StringIndex, Reserved2;
USHORT DesignatorIndex, Reserved3;
@ -357,15 +360,18 @@ typedef struct _HIDP_VALUE_CAPS
LONG LogicalMin, LogicalMax;
LONG PhysicalMin, PhysicalMax;
union {
struct {
union
{
struct
{
USAGE UsageMin, UsageMax;
USHORT StringMin, StringMax;
USHORT DesignatorMin, DesignatorMax;
USHORT DataIndexMin, DataIndexMax;
} Range;
struct {
struct
{
USAGE Usage, Reserved1;
USHORT StringIndex, Reserved2;
USHORT DesignatorIndex, Reserved3;
@ -374,7 +380,8 @@ typedef struct _HIDP_VALUE_CAPS
};
} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
typedef struct _HIDD_ATTRIBUTES {
typedef struct _HIDD_ATTRIBUTES
{
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
//
@ -421,7 +428,8 @@ typedef struct _HIDP_DATA
{
USHORT DataIndex;
USHORT Reserved;
union {
union
{
ULONG RawValue; // for values
BOOLEAN On; // for buttons MUST BE TRUE for buttons.
};

View File

@ -183,7 +183,13 @@ void CIniFileA::Load( std::istream& input , bool bMerge )
CIniSectionA* pSection = NULL;
std::string sRead;
enum { KEY , SECTION , COMMENT , OTHER };
enum
{
KEY,
SECTION,
COMMENT,
OTHER
};
while (std::getline(input, sRead))
{
@ -430,7 +436,9 @@ SecIndexA::iterator CIniFileA::_find_sec( const std::string& sSection )
// CIniSectionA functions start here
CIniSectionA::CIniSectionA( CIniFileA* pIniFile , const std::string& sSectionName ) : m_pIniFile(pIniFile) , m_sSectionName(sSectionName)
CIniSectionA::CIniSectionA(CIniFileA* pIniFile, const std::string& sSectionName)
: m_pIniFile(pIniFile)
, m_sSectionName(sSectionName)
{
#ifdef _CINIFILE_DEBUG
std::cout << "CIniSectionA::CIniSectionA()" << std::endl;
@ -622,7 +630,9 @@ KeyIndexA::iterator CIniSectionA::_find_key( const std::string& sKey )
// CIniKeyA Functions Start Here
CIniKeyA::CIniKeyA( CIniSectionA* pSection , const std::string& sKeyName ) : m_pSection(pSection) , m_sKeyName(sKeyName)
CIniKeyA::CIniKeyA(CIniSectionA* pSection, const std::string& sKeyName)
: m_pSection(pSection)
, m_sKeyName(sKeyName)
{
#ifdef _CINIFILE_DEBUG
std::cout << "CIniKeyA::CIniKeyA()" << std::endl;
@ -819,7 +829,13 @@ void CIniFileW::Load( std::wistream& input , bool bMerge )
CIniSectionW* pSection = NULL;
std::wstring sRead;
enum { KEY , SECTION , COMMENT , OTHER };
enum
{
KEY,
SECTION,
COMMENT,
OTHER
};
while (std::getline(input, sRead))
{
@ -1070,7 +1086,9 @@ SecIndexW::iterator CIniFileW::_find_sec( const std::wstring& sSection )
// CIniSectionW functions start here
CIniSectionW::CIniSectionW( CIniFileW* pIniFile , const std::wstring& sSectionName ) : m_pIniFile(pIniFile) , m_sSectionName(sSectionName)
CIniSectionW::CIniSectionW(CIniFileW* pIniFile, const std::wstring& sSectionName)
: m_pIniFile(pIniFile)
, m_sSectionName(sSectionName)
{
#ifdef _CINIFILE_DEBUG
std::wcout << L"CIniSectionW::CIniSectionW()" << std::endl;
@ -1262,7 +1280,9 @@ KeyIndexW::iterator CIniSectionW::_find_key( const std::wstring& sKey )
// CIniKeyW Functions Start Here
CIniKeyW::CIniKeyW( CIniSectionW* pSection , const std::wstring& sKeyName ) : m_pSection(pSection) , m_sKeyName(sKeyName)
CIniKeyW::CIniKeyW(CIniSectionW* pSection, const std::wstring& sKeyName)
: m_pSection(pSection)
, m_sKeyName(sKeyName)
{
#ifdef _CINIFILE_DEBUG
std::wcout << L"CIniKeyW::CIniKeyW()" << std::endl;

View File

@ -71,6 +71,7 @@ class CIniFileA
{
public:
static const char* const LF;
public:
CIniFileA();
~CIniFileA();
@ -91,15 +92,20 @@ public:
class CIniMergeA
{
public:
explicit CIniMergeA(CIniFileA& ini):_ini(ini) {}
explicit CIniMergeA(CIniFileA& ini)
: _ini(ini)
{
}
std::istream& operator()(std::istream& input) const
{
_ini.Load(input, true);
return input;
}
private:
CIniFileA& _ini;
};
public:
#ifdef _WIN32
// Added for versions earlier than VS2008
@ -138,6 +144,7 @@ public:
CIniKeyA(const CIniKeyA&); // No Copy
CIniKeyA& operator=(const CIniKeyA&); // No Copy
~CIniKeyA();
public:
// Sets the value of the key
void SetValue(const std::string& sValue);
@ -148,6 +155,7 @@ public:
bool SetKeyName(std::string sKeyName);
// Returns the name of the Key
std::string GetKeyName() const;
private:
// Pointer to the parent CIniSectionA
CIniSectionA* m_pSection;
@ -182,6 +190,7 @@ public:
CIniSectionA(const CIniSectionA&); // No Copy
CIniSectionA& operator=(const CIniSectionA&); // No Copy
~CIniSectionA();
public:
// Adds a key to the CIniSectionA object, returns a CIniKeyA pointer to the new or existing object
CIniKeyA* AddKey(std::string sKeyName);
@ -204,9 +213,11 @@ public:
bool SetSectionName(std::string sSectionName);
// Returns the section name
std::string GetSectionName() const;
private:
KeyIndexA::const_iterator _find_key(const std::string& sKeyName) const;
KeyIndexA::iterator _find_key(const std::string& sKeyName);
private:
// CIniFileA pointer back to the object that instanciated the section
CIniFileA* m_pIniFile;
@ -257,9 +268,11 @@ public:
bool RenameSection(const std::string& sSectionName, const std::string& sNewSectionName);
// Renames an existing key returns true on success, false if the key didn't exist or there was another section with the same sNewSectionName
bool RenameKey(const std::string& sSectionName, const std::string& sKeyName, const std::string& sNewKeyName);
private:
SecIndexA::const_iterator _find_sec(const std::string& sSection) const;
SecIndexA::iterator _find_sec(const std::string& sSection);
private:
CIniFileA(const CIniFileA&); // No Copy
CIniFileA& operator=(const CIniFileA&); // No Copy
@ -295,6 +308,7 @@ class CIniFileW
{
public:
static const wchar_t* const LF;
public:
CIniFileW();
~CIniFileW();
@ -315,15 +329,20 @@ public:
class CIniMergeW
{
public:
explicit CIniMergeW(CIniFileW& ini):_ini(ini) {}
explicit CIniMergeW(CIniFileW& ini)
: _ini(ini)
{
}
std::wistream& operator()(std::wistream& input) const
{
_ini.Load(input, true);
return input;
}
private:
CIniFileW& _ini;
};
public:
#ifdef _WIN32
// Added for versions earlier than VS2008
@ -361,6 +380,7 @@ public:
CIniKeyW(const CIniKeyW&); // No Copy
CIniKeyW& operator=(const CIniKeyW&); // No Copy
~CIniKeyW();
public:
// Sets the value of the key
void SetValue(const std::wstring& sValue);
@ -371,6 +391,7 @@ public:
bool SetKeyName(std::wstring sKeyName);
// Returns the name of the Key
std::wstring GetKeyName() const;
private:
// Pointer to the parent CIniSectionW
CIniSectionW* m_pSection;
@ -405,6 +426,7 @@ public:
CIniSectionW(const CIniSectionW&); // No Copy
CIniSectionW& operator=(const CIniSectionW&); // No Copy
~CIniSectionW();
public:
// Adds a key to the CIniSectionW object, returns a CIniKeyW pointer to the new or existing object
CIniKeyW* AddKey(std::wstring sKeyName);
@ -427,9 +449,11 @@ public:
bool SetSectionName(std::wstring sSectionName);
// Returns the section name
std::wstring GetSectionName() const;
private:
KeyIndexW::const_iterator _find_key(const std::wstring& sKeyName) const;
KeyIndexW::iterator _find_key(const std::wstring& sKeyName);
private:
// CIniFileW pointer back to the object that instanciated the section
CIniFileW* m_pIniFile;
@ -480,9 +504,11 @@ public:
bool RenameSection(const std::wstring& sSectionName, const std::wstring& sNewSectionName);
// Renames an existing key returns true on success, false if the key didn't exist or there was another section with the same sNewSectionName
bool RenameKey(const std::wstring& sSectionName, const std::wstring& sKeyName, const std::wstring& sNewKeyName);
private:
SecIndexW::const_iterator _find_sec(const std::wstring& sSection) const;
SecIndexW::iterator _find_sec(const std::wstring& sSection);
private:
CIniFileW(const CIniFileW&); // No Copy
CIniFileW& operator=(const CIniFileW&); // No Copy
@ -542,4 +568,3 @@ std::wstring str_to_wstr(const std::string& arg);
std::string wstr_to_str(const std::wstring& arg);
#endif

View File

@ -21,7 +21,10 @@
extern HINSTANCE hInst;
namespace shared{ namespace rawinput{
namespace shared
{
namespace rawinput
{
static std::vector<ParseRawInputCB*> callbacks;
@ -128,7 +131,8 @@ static int RegisterRaw(HWND hWnd)
Rid[3].dwFlags = hWnd ? RIDEV_INPUTSINK : RIDEV_REMOVE;
Rid[3].hwndTarget = hWnd;
if (RegisterRawInputDevices(Rid, countof(Rid), sizeof(Rid[0])) == FALSE) {
if (RegisterRawInputDevices(Rid, countof(Rid), sizeof(Rid[0])) == FALSE)
{
//registration failed. Call GetLastError for the cause of the error.
fprintf(stderr, "Could not (de)register raw input devices.\n");
return 0;
@ -138,7 +142,8 @@ static int RegisterRaw(HWND hWnd)
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
switch (uMsg)
{
case WM_ACTIVATE:
OSDebugOut(TEXT("****** WM_ACTIVATE ****** %p %d\n"), hWnd, LOWORD(wParam) != WA_INACTIVE);
skipInput = LOWORD(wParam) == WA_INACTIVE;
@ -160,13 +165,16 @@ static LRESULT CALLBACK RawInputProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
PRAWINPUT pRawInput;
UINT bufferSize = 0;
switch(uMsg) {
switch (uMsg)
{
case WM_CREATE:
if (eatenWnd == nullptr)
RegisterRaw(hWnd);
break;
case WM_INPUT: {
if (skipInput) break;
case WM_INPUT:
{
if (skipInput)
break;
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &bufferSize, sizeof(RAWINPUTHEADER));
pRawInput = (PRAWINPUT)malloc(bufferSize);
@ -174,7 +182,8 @@ static LRESULT CALLBACK RawInputProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
if (!pRawInput)
break;
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, pRawInput, &bufferSize, sizeof(RAWINPUTHEADER)) > 0) {
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, pRawInput, &bufferSize, sizeof(RAWINPUTHEADER)) > 0)
{
if (pRawInput->header.dwType == RIM_TYPEKEYBOARD)
ToggleCursor(hWnd, pRawInput->data.keyboard);
@ -284,4 +293,5 @@ void Uninitialize()
eatenWnd = nullptr;
}
}} //namespace
} // namespace rawinput
} // namespace shared

View File

@ -18,7 +18,10 @@
#include <setupapi.h>
#include "hidapi.h"
namespace shared{ namespace rawinput{
namespace shared
{
namespace rawinput
{
class ParseRawInputCB
{
@ -31,4 +34,5 @@ namespace shared{ namespace rawinput{
void RegisterCallback(ParseRawInputCB* cb);
void UnregisterCallback(ParseRawInputCB* cb);
}}
} // namespace rawinput
} // namespace shared

View File

@ -21,7 +21,10 @@
#if 0
#define DPRINTF OSDebugOut
#else
#define DPRINTF(...) do{}while(0)
#define DPRINTF(...) \
do \
{ \
} while (0)
#endif
RingBuffer::RingBuffer()
@ -33,7 +36,8 @@ RingBuffer::RingBuffer()
{
}
RingBuffer::RingBuffer(size_t capacity) : RingBuffer()
RingBuffer::RingBuffer(size_t capacity)
: RingBuffer()
{
reserve(capacity);
}

View File

@ -28,6 +28,7 @@ using sec = std::chrono::seconds;
class RingBuffer
{
RingBuffer(RingBuffer&) = delete;
public:
RingBuffer();
RingBuffer(size_t capacity);
@ -45,10 +46,16 @@ public:
void read(size_t bytes);
template <typename T>
void write(size_t samples) { write(samples * sizeof(T)); }
void write(size_t samples)
{
write(samples * sizeof(T));
}
template <typename T>
void read(size_t samples) { read (samples * sizeof(T)); }
void read(size_t samples)
{
read(samples * sizeof(T));
}
void reserve(size_t size);
// if you care about old data, check how much can be written
@ -80,15 +87,22 @@ public:
char* back() { return m_data + m_end; }
template <typename T>
T* front() { return (T*)(m_data + m_begin); }
T* front()
{
return (T*)(m_data + m_begin);
}
template <typename T>
T* back() { return (T*)(m_data + m_end); }
T* back()
{
return (T*)(m_data + m_end);
}
long long MilliSecsSinceLastWrite()
{
return std::chrono::duration_cast<ms>(hrc::now() - mLastWrite).count();
}
private:
size_t m_capacity;
char* m_data;
@ -96,7 +110,6 @@ private:
bool m_overrun;
size_t m_end;
hrc::time_point mLastWrite = hrc::time_point(ns(0));
};
#endif

View File

@ -20,7 +20,8 @@
#include "rawinput.h"
#endif
namespace shared {
namespace shared
{
void Initialize(void* ptr)
{
@ -38,4 +39,4 @@ namespace shared {
#endif
}
};
}; // namespace shared

View File

@ -14,7 +14,8 @@
*/
#pragma once
namespace shared {
namespace shared
{
void Initialize(void* ptr);
void Uninitialize(/*void *ptr*/);
};
}; // namespace shared

View File

@ -57,28 +57,35 @@ static unsigned int pixelformat;
buffer_t mpeg_buffer;
std::mutex mpeg_mutex;
static int xioctl(int fh, unsigned long int request, void *arg) {
static int xioctl(int fh, unsigned long int request, void* arg)
{
int r;
do {
do
{
r = ioctl(fh, request, arg);
} while (-1 == r && EINTR == errno);
return r;
}
static void store_mpeg_frame(unsigned char *data, unsigned int len) {
static void store_mpeg_frame(unsigned char* data, unsigned int len)
{
mpeg_mutex.lock();
memcpy(mpeg_buffer.start, data, len);
mpeg_buffer.length = len;
mpeg_mutex.unlock();
}
static void process_image(const unsigned char *ptr, int size) {
if (pixelformat == V4L2_PIX_FMT_YUYV) {
static void process_image(const unsigned char* ptr, int size)
{
if (pixelformat == V4L2_PIX_FMT_YUYV)
{
unsigned char* mpegData = (unsigned char*)calloc(1, 320 * 240 * 2);
int mpegLen = jo_write_mpeg(mpegData, ptr, 320, 240, JO_YUYV, JO_FLIP_X, JO_NONE);
store_mpeg_frame(mpegData, mpegLen);
free(mpegData);
} else if (pixelformat == V4L2_PIX_FMT_JPEG) {
}
else if (pixelformat == V4L2_PIX_FMT_JPEG)
{
int width, height, actual_comps;
unsigned char* rgbData = jpgd::decompress_jpeg_image_from_memory(ptr, size, &width, &height, &actual_comps, 3);
unsigned char* mpegData = (unsigned char*)calloc(1, 320 * 240 * 2);
@ -86,19 +93,24 @@ static void process_image(const unsigned char *ptr, int size) {
free(rgbData);
store_mpeg_frame(mpegData, mpegLen);
free(mpegData);
} else {
}
else
{
fprintf(stderr, "unk format %c%c%c%c\n", pixelformat, pixelformat >> 8, pixelformat >> 16, pixelformat >> 24);
}
}
static int read_frame() {
static int read_frame()
{
struct v4l2_buffer buf;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) {
switch (errno) {
if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf))
{
switch (errno)
{
case EAGAIN:
return 0;
@ -113,7 +125,8 @@ static int read_frame() {
process_image((const unsigned char*)buffers[buf.index].start, buf.bytesused);
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
{
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QBUF", errno, strerror(errno));
return -1;
}
@ -121,20 +134,24 @@ static int read_frame() {
return 1;
}
std::vector<std::string> getDevList() {
std::vector<std::string> getDevList()
{
std::vector<std::string> devList;
char dev_name[64];
int fd;
struct v4l2_capability cap;
for (int index = 0; index < 64; index++) {
for (int index = 0; index < 64; index++)
{
snprintf(dev_name, sizeof(dev_name), "/dev/video%d", index);
if ((fd = open(dev_name, O_RDONLY)) < 0) {
if ((fd = open(dev_name, O_RDONLY)) < 0)
{
continue;
}
if(ioctl(fd, VIDIOC_QUERYCAP, &cap) >= 0) {
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) >= 0)
{
devList.push_back((char*)cap.card);
}
@ -143,22 +160,27 @@ std::vector<std::string> getDevList() {
return devList;
}
static int v4l_open(std::string selectedDevice) {
static int v4l_open(std::string selectedDevice)
{
char dev_name[64];
struct v4l2_capability cap;
fd = -1;
for (int index = 0; index < 64; index++) {
for (int index = 0; index < 64; index++)
{
snprintf(dev_name, sizeof(dev_name), "/dev/video%d", index);
if ((fd = open(dev_name, O_RDWR | O_NONBLOCK, 0)) < 0) {
if ((fd = open(dev_name, O_RDWR | O_NONBLOCK, 0)) < 0)
{
continue;
}
CLEAR(cap);
if(ioctl(fd, VIDIOC_QUERYCAP, &cap) >= 0) {
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) >= 0)
{
fprintf(stderr, "Camera: %s / %s\n", dev_name, (char*)cap.card);
if (!selectedDevice.empty() && strcmp(selectedDevice.c_str(), (char*)cap.card) == 0) {
if (!selectedDevice.empty() && strcmp(selectedDevice.c_str(), (char*)cap.card) == 0)
{
goto cont;
}
}
@ -167,10 +189,12 @@ static int v4l_open(std::string selectedDevice) {
fd = -1;
}
if (fd < 0) {
if (fd < 0)
{
snprintf(dev_name, sizeof(dev_name), "/dev/video0");
fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
if (-1 == fd) {
if (-1 == fd)
{
fprintf(stderr, "Cannot open '%s': %d, %s\n", dev_name, errno, strerror(errno));
return -1;
}
@ -179,22 +203,28 @@ static int v4l_open(std::string selectedDevice) {
cont:
CLEAR(cap);
if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) {
if (EINVAL == errno) {
if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap))
{
if (EINVAL == errno)
{
fprintf(stderr, "%s is no V4L2 device\n", dev_name);
return -1;
} else {
}
else
{
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QUERYCAP", errno, strerror(errno));
return -1;
}
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
{
fprintf(stderr, "%s is no video capture device\n", dev_name);
return -1;
}
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
if (!(cap.capabilities & V4L2_CAP_STREAMING))
{
fprintf(stderr, "%s does not support streaming i/o\n", dev_name);
return -1;
}
@ -203,13 +233,16 @@ cont:
CLEAR(cropcap);
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap)) {
if (0 == xioctl(fd, VIDIOC_CROPCAP, &cropcap))
{
struct v4l2_crop crop;
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect;
if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop)) {
switch (errno) {
if (-1 == xioctl(fd, VIDIOC_S_CROP, &crop))
{
switch (errno)
{
case EINVAL:
break;
default:
@ -225,14 +258,14 @@ cont:
fmt.fmt.pix.height = 240;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) {
if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
{
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_S_FMT", errno, strerror(errno));
return -1;
}
pixelformat = fmt.fmt.pix.pixelformat;
fprintf(stderr, "VIDIOC_S_FMT res=%dx%d, fmt=%c%c%c%c\n", fmt.fmt.pix.width, fmt.fmt.pix.height,
pixelformat, pixelformat>>8, pixelformat>>16, pixelformat>>24
);
pixelformat, pixelformat >> 8, pixelformat >> 16, pixelformat >> 24);
struct v4l2_requestbuffers req;
CLEAR(req);
@ -240,29 +273,36 @@ cont:
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) {
if (EINVAL == errno) {
if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req))
{
if (EINVAL == errno)
{
fprintf(stderr, "%s does not support memory mapping\n", dev_name);
return -1;
} else {
}
else
{
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_REQBUFS", errno, strerror(errno));
return -1;
}
}
if (req.count < 2) {
if (req.count < 2)
{
fprintf(stderr, "Insufficient buffer memory on %s\n", dev_name);
return -1;
}
buffers = (buffer_t*)calloc(req.count, sizeof(*buffers));
if (!buffers) {
if (!buffers)
{
fprintf(stderr, "Out of memory\n");
return -1;
}
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
for (n_buffers = 0; n_buffers < req.count; ++n_buffers)
{
struct v4l2_buffer buf;
CLEAR(buf);
@ -270,7 +310,8 @@ cont:
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf)) {
if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
{
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QUERYBUF", errno, strerror(errno));
return -1;
}
@ -278,20 +319,23 @@ cont:
buffers[n_buffers].length = buf.length;
buffers[n_buffers].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
if (MAP_FAILED == buffers[n_buffers].start) {
if (MAP_FAILED == buffers[n_buffers].start)
{
fprintf(stderr, "%s error %d, %s\n", "mmap", errno, strerror(errno));
return -1;
}
}
for (unsigned int i = 0; i < n_buffers; ++i) {
for (unsigned int i = 0; i < n_buffers; ++i)
{
struct v4l2_buffer buf;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) {
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
{
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_QBUF", errno, strerror(errno));
return -1;
}
@ -299,7 +343,8 @@ cont:
enum v4l2_buf_type type;
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) {
if (-1 == xioctl(fd, VIDIOC_STREAMON, &type))
{
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_STREAMON", errno, strerror(errno));
return -1;
}
@ -307,9 +352,12 @@ cont:
}
static void* v4l_thread(void *arg) {
while(eyetoy_running) {
for (;;) {
static void* v4l_thread(void* arg)
{
while (eyetoy_running)
{
for (;;)
{
fd_set fds;
FD_ZERO(&fds);
@ -318,14 +366,16 @@ static void* v4l_thread(void *arg) {
struct timeval timeout = {2, 0}; // 2sec
int ret = select(fd + 1, &fds, NULL, NULL, &timeout);
if (ret < 0) {
if (ret < 0)
{
if (errno == EINTR)
continue;
fprintf(stderr, "%s error %d, %s\n", "select", errno, strerror(errno));
break;
}
if (ret == 0) {
if (ret == 0)
{
fprintf(stderr, "select timeout\n");
break;
}
@ -337,23 +387,28 @@ static void* v4l_thread(void *arg) {
return NULL;
}
static int v4l_close() {
static int v4l_close()
{
enum v4l2_buf_type type;
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type)) {
if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type))
{
fprintf(stderr, "%s error %d, %s\n", "VIDIOC_STREAMOFF", errno, strerror(errno));
return -1;
}
for (unsigned int i = 0; i < n_buffers; ++i) {
if (-1 == munmap(buffers[i].start, buffers[i].length)) {
for (unsigned int i = 0; i < n_buffers; ++i)
{
if (-1 == munmap(buffers[i].start, buffers[i].length))
{
fprintf(stderr, "%s error %d, %s\n", "munmap", errno, strerror(errno));
return -1;
}
}
free(buffers);
if (-1 == close(fd)) {
if (-1 == close(fd))
{
fprintf(stderr, "%s error %d, %s\n", "close", errno, strerror(errno));
return -1;
}
@ -361,14 +416,17 @@ static int v4l_close() {
return 0;
}
void create_dummy_frame() {
void create_dummy_frame()
{
const int width = 320;
const int height = 240;
const int bytesPerPixel = 3;
unsigned char* rgbData = (unsigned char*)calloc(1, width * height * bytesPerPixel);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
unsigned char* ptr = rgbData + (y * width + x) * bytesPerPixel;
ptr[0] = 255 - y;
ptr[1] = y;
@ -383,10 +441,12 @@ void create_dummy_frame() {
free(mpegData);
}
int V4L2::Open() {
int V4L2::Open()
{
mpeg_buffer.start = calloc(1, 320 * 240 * 2);
create_dummy_frame();
if (eyetoy_running) {
if (eyetoy_running)
{
eyetoy_running = 0;
pthread_join(*eyetoy_thread, NULL);
v4l_close();
@ -400,8 +460,10 @@ int V4L2::Open() {
return 0;
};
int V4L2::Close() {
if (eyetoy_running) {
int V4L2::Close()
{
if (eyetoy_running)
{
eyetoy_running = 0;
pthread_join(*eyetoy_thread, NULL);
v4l_close();
@ -409,20 +471,24 @@ int V4L2::Close() {
return 0;
};
int V4L2::GetImage(uint8_t *buf, int len) {
int V4L2::GetImage(uint8_t* buf, int len)
{
mpeg_mutex.lock();
int len2 = mpeg_buffer.length;
if (len < mpeg_buffer.length) len2 = len;
if (len < mpeg_buffer.length)
len2 = len;
memcpy(buf, mpeg_buffer.start, len2);
mpeg_mutex.unlock();
return len2;
};
static void deviceChanged(GtkComboBox *widget, gpointer data) {
static void deviceChanged(GtkComboBox* widget, gpointer data)
{
*(int*)data = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
}
int GtkConfigure(int port, const char* dev_type, void *data) {
int GtkConfigure(int port, const char* dev_type, void* data)
{
GtkWidget *ro_frame, *ro_label, *rs_hbox, *rs_label;
std::string selectedDevice;
@ -447,9 +513,11 @@ int GtkConfigure(int port, const char* dev_type, void *data) {
std::vector<std::string> devList = getDevList();
int sel_idx = 0;
for (auto idx = 0; idx < devList.size(); idx++) {
for (auto idx = 0; idx < devList.size(); idx++)
{
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rs_cb), devList.at(idx).c_str());
if (!selectedDevice.empty() && selectedDevice == devList.at(idx)) {
if (!selectedDevice.empty() && selectedDevice == devList.at(idx))
{
gtk_combo_box_set_active(GTK_COMBO_BOX(rs_cb), idx);
sel_idx = idx;
}
@ -462,13 +530,18 @@ int GtkConfigure(int port, const char* dev_type, void *data) {
gint result = gtk_dialog_run(GTK_DIALOG(dlg));
int ret = RESULT_OK;
if (result == GTK_RESPONSE_OK) {
if (sel_new != sel_idx) {
if (!SaveSetting(dev_type, port, APINAME, N_DEVICE, devList.at(sel_new))) {
if (result == GTK_RESPONSE_OK)
{
if (sel_new != sel_idx)
{
if (!SaveSetting(dev_type, port, APINAME, N_DEVICE, devList.at(sel_new)))
{
ret = RESULT_FAILED;
}
}
} else {
}
else
{
ret = RESULT_CANCELED;
}
@ -476,7 +549,8 @@ int GtkConfigure(int port, const char* dev_type, void *data) {
return ret;
}
int V4L2::Configure(int port, const char *dev_type, void *data) {
int V4L2::Configure(int port, const char* dev_type, void* data)
{
return GtkConfigure(port, dev_type, data);
};

View File

@ -20,7 +20,8 @@ namespace usb_eyetoy
namespace linux_api
{
typedef struct {
typedef struct
{
void* start;
size_t length;
} buffer_t;
@ -30,14 +31,16 @@ static const char *APINAME = "V4L2";
class V4L2 : public VideoDevice
{
public:
V4L2(int port) : mPort(port) {};
V4L2(int port)
: mPort(port){};
~V4L2(){};
int Open();
int Close();
int GetImage(uint8_t* buf, int len);
int Reset() { return 0; };
static const TCHAR *Name() {
static const TCHAR* Name()
{
return TEXT("V4L2");
}
static int Configure(int port, const char* dev_type, void* data);

View File

@ -26,47 +26,57 @@ namespace usb_eyetoy
namespace windows_api
{
HRESULT DirectShow::CallbackHandler::SampleCB(double time, IMediaSample *sample) {
HRESULT DirectShow::CallbackHandler::SampleCB(double time, IMediaSample* sample)
{
HRESULT hr;
unsigned char* buffer;
hr = sample->GetPointer((BYTE**)&buffer);
if (hr != S_OK) return S_OK;
if (hr != S_OK)
return S_OK;
if (callback) callback(buffer, sample->GetActualDataLength(), BITS_PER_PIXEL);
if (callback)
callback(buffer, sample->GetActualDataLength(), BITS_PER_PIXEL);
return S_OK;
}
HRESULT DirectShow::CallbackHandler::QueryInterface(REFIID iid, LPVOID *ppv) {
if( iid == IID_ISampleGrabberCB || iid == IID_IUnknown ) {
HRESULT DirectShow::CallbackHandler::QueryInterface(REFIID iid, LPVOID* ppv)
{
if (iid == IID_ISampleGrabberCB || iid == IID_IUnknown)
{
*ppv = (void*)static_cast<ISampleGrabberCB*>(this);
return S_OK;
}
return E_NOINTERFACE;
}
std::vector<std::wstring> getDevList() {
std::vector<std::wstring> getDevList()
{
std::vector<std::wstring> devList;
ICreateDevEnum* pCreateDevEnum = 0;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pCreateDevEnum));
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "Error Creating Device Enumerator");
return devList;
}
IEnumMoniker* pEnum = 0;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, NULL);
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "You have no video capture hardware");
return devList;
};
IMoniker* pMoniker = NULL;
while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
{
IPropertyBag* pPropBag;
HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
if (FAILED(hr)) {
if (FAILED(hr))
{
pMoniker->Release();
continue;
}
@ -74,10 +84,12 @@ std::vector<std::wstring> getDevList() {
VARIANT var;
VariantInit(&var);
hr = pPropBag->Read(L"Description", &var, 0);
if (FAILED(hr)) {
if (FAILED(hr))
{
hr = pPropBag->Read(L"FriendlyName", &var, 0);
}
if (SUCCEEDED(hr)) {
if (SUCCEEDED(hr))
{
devList.push_back(var.bstrVal);
VariantClear(&var);
}
@ -92,30 +104,35 @@ std::vector<std::wstring> getDevList() {
return devList;
}
int DirectShow::InitializeDevice(std::wstring selectedDevice) {
int DirectShow::InitializeDevice(std::wstring selectedDevice)
{
// Create the Capture Graph Builder.
HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraphBuilder));
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "CoCreateInstance CLSID_CaptureGraphBuilder2 err : %x\n", hr);
return -1;
}
// Create the Filter Graph Manager.
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph));
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "CoCreateInstance CLSID_FilterGraph err : %x\n", hr);
return -1;
}
hr = pGraphBuilder->SetFiltergraph(pGraph);
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "SetFiltergraph err : %x\n", hr);
return -1;
}
hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl);
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "QueryInterface IID_IMediaControl err : %x\n", hr);
return -1;
}
@ -123,14 +140,16 @@ int DirectShow::InitializeDevice(std::wstring selectedDevice) {
// enumerate all video capture devices
ICreateDevEnum* pCreateDevEnum = 0;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pCreateDevEnum));
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "Error Creating Device Enumerator");
return -1;
}
IEnumMoniker* pEnum = 0;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, NULL);
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "You have no video capture hardware");
return -1;
};
@ -138,10 +157,12 @@ int DirectShow::InitializeDevice(std::wstring selectedDevice) {
pEnum->Reset();
IMoniker* pMoniker;
while (pEnum->Next(1, &pMoniker, NULL) == S_OK && sourcefilter == NULL) {
while (pEnum->Next(1, &pMoniker, NULL) == S_OK && sourcefilter == NULL)
{
IPropertyBag* pPropBag = 0;
hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "BindToStorage err : %x\n", hr);
goto freeMoniker;
}
@ -150,34 +171,41 @@ int DirectShow::InitializeDevice(std::wstring selectedDevice) {
VariantInit(&var);
hr = pPropBag->Read(L"Description", &var, 0);
if (FAILED(hr)) {
if (FAILED(hr))
{
hr = pPropBag->Read(L"FriendlyName", &var, 0);
}
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "Read name err : %x\n", hr);
goto freeVar;
}
fprintf(stderr, "Camera: '%ls'\n", var.bstrVal);
if (!selectedDevice.empty() && selectedDevice != var.bstrVal) {
if (!selectedDevice.empty() && selectedDevice != var.bstrVal)
{
goto freeVar;
}
//add a filter for the device
hr = pGraph->AddSourceFilterForMoniker(pMoniker, NULL, L"sourcefilter", &sourcefilter);
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "AddSourceFilterForMoniker err : %x\n", hr);
goto freeVar;
}
hr = pGraphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, sourcefilter, IID_IAMStreamConfig, (void**)&pSourceConfig);
if (SUCCEEDED(hr)) {
if (SUCCEEDED(hr))
{
int iCount = 0, iSize = 0;
hr = pSourceConfig->GetNumberOfCapabilities(&iCount, &iSize);
// Check the size to make sure we pass in the correct structure.
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) {
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
{
// Use the video capabilities structure.
for (int iFormat = 0; iFormat < iCount; iFormat++) {
for (int iFormat = 0; iFormat < iCount; iFormat++)
{
VIDEO_STREAM_CONFIG_CAPS scc;
AM_MEDIA_TYPE* pmtConfig;
hr = pSourceConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
@ -186,11 +214,13 @@ int DirectShow::InitializeDevice(std::wstring selectedDevice) {
scc.MaxOutputSize.cx, scc.MaxOutputSize.cy,
pmtConfig->subtype);
if (SUCCEEDED(hr)) {
if (SUCCEEDED(hr))
{
if ((pmtConfig->majortype == MEDIATYPE_Video) &&
(pmtConfig->formattype == FORMAT_VideoInfo) &&
(pmtConfig->cbFormat >= sizeof(VIDEOINFOHEADER)) &&
(pmtConfig->pbFormat != NULL)) {
(pmtConfig->pbFormat != NULL))
{
VIDEOINFOHEADER* pVih = (VIDEOINFOHEADER*)pmtConfig->pbFormat;
pVih->bmiHeader.biWidth = 320;
@ -206,20 +236,23 @@ int DirectShow::InitializeDevice(std::wstring selectedDevice) {
// Create the Sample Grabber filter.
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&samplegrabberfilter));
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "CoCreateInstance CLSID_SampleGrabber err : %x\n", hr);
goto freeVar;
}
hr = pGraph->AddFilter(samplegrabberfilter, L"samplegrabberfilter");
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "AddFilter samplegrabberfilter err : %x\n", hr);
goto freeVar;
}
//set mediatype on the samplegrabber
hr = samplegrabberfilter->QueryInterface(IID_PPV_ARGS(&samplegrabber));
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "QueryInterface err : %x\n", hr);
goto freeVar;
}
@ -229,34 +262,39 @@ int DirectShow::InitializeDevice(std::wstring selectedDevice) {
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = samplegrabber->SetMediaType(&mt);
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "SetMediaType err : %x\n", hr);
goto freeVar;
}
//add the callback to the samplegrabber
hr = samplegrabber->SetCallback(callbackhandler, 0);
if (hr != S_OK) {
if (hr != S_OK)
{
fprintf(stderr, "SetCallback err : %x\n", hr);
goto freeVar;
}
//set the null renderer
hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&nullrenderer));
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "CoCreateInstance CLSID_NullRenderer err : %x\n", hr);
goto freeVar;
}
hr = pGraph->AddFilter(nullrenderer, L"nullrenderer");
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "AddFilter nullrenderer err : %x\n", hr);
goto freeVar;
}
//set the render path
hr = pGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, sourcefilter, samplegrabberfilter, nullrenderer);
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "RenderStream err : %x\n", hr);
goto freeVar;
}
@ -264,7 +302,8 @@ int DirectShow::InitializeDevice(std::wstring selectedDevice) {
// if the stream is started, start capturing immediatly
LONGLONG start = 0, stop = MAXLONGLONG;
hr = pGraphBuilder->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, sourcefilter, &start, &stop, 1, 2);
if (FAILED(hr)) {
if (FAILED(hr))
{
fprintf(stderr, "ControlStream err : %x\n", hr);
goto freeVar;
}
@ -277,63 +316,80 @@ int DirectShow::InitializeDevice(std::wstring selectedDevice) {
pMoniker->Release();
}
pEnum->Release();
if (sourcefilter == NULL) {
if (sourcefilter == NULL)
{
return -1;
}
return 0;
}
void DirectShow::Start() {
void DirectShow::Start()
{
HRESULT hr = nullrenderer->Run(0);
if (FAILED(hr)) throw hr;
if (FAILED(hr))
throw hr;
hr = samplegrabberfilter->Run(0);
if (FAILED(hr)) throw hr;
if (FAILED(hr))
throw hr;
hr = sourcefilter->Run(0);
if (FAILED(hr)) throw hr;
if (FAILED(hr))
throw hr;
}
void DirectShow::Stop() {
void DirectShow::Stop()
{
HRESULT hr = sourcefilter->Stop();
if (FAILED(hr)) throw hr;
if (FAILED(hr))
throw hr;
hr = samplegrabberfilter->Stop();
if (FAILED(hr)) throw hr;
if (FAILED(hr))
throw hr;
hr = nullrenderer->Stop();
if (FAILED(hr)) throw hr;
if (FAILED(hr))
throw hr;
}
buffer_t mpeg_buffer{};
std::mutex mpeg_mutex;
void store_mpeg_frame(unsigned char *data, unsigned int len) {
void store_mpeg_frame(unsigned char* data, unsigned int len)
{
mpeg_mutex.lock();
memcpy(mpeg_buffer.start, data, len);
mpeg_buffer.length = len;
mpeg_mutex.unlock();
}
void dshow_callback(unsigned char *data, int len, int bitsperpixel) {
if (bitsperpixel == 24) {
void dshow_callback(unsigned char* data, int len, int bitsperpixel)
{
if (bitsperpixel == 24)
{
unsigned char* mpegData = (unsigned char*)calloc(1, 320 * 240 * 2);
int mpegLen = jo_write_mpeg(mpegData, data, 320, 240, JO_RGB24, JO_FLIP_X, JO_FLIP_Y);
store_mpeg_frame(mpegData, mpegLen);
free(mpegData);
} else {
}
else
{
fprintf(stderr, "dshow_callback: unk format: len=%d bpp=%d\n", len, bitsperpixel);
}
}
void create_dummy_frame() {
void create_dummy_frame()
{
const int width = 320;
const int height = 240;
const int bytesPerPixel = 3;
unsigned char* rgbData = (unsigned char*)calloc(1, width * height * bytesPerPixel);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
unsigned char* ptr = rgbData + (y * width + x) * bytesPerPixel;
ptr[0] = 255 - y;
ptr[1] = y;
@ -348,7 +404,8 @@ void create_dummy_frame() {
free(mpegData);
}
DirectShow::DirectShow(int port) {
DirectShow::DirectShow(int port)
{
mPort = port;
pGraphBuilder = NULL;
pGraph = NULL;
@ -362,7 +419,8 @@ DirectShow::DirectShow(int port) {
CoInitialize(NULL);
}
int DirectShow::Open() {
int DirectShow::Open()
{
mpeg_buffer.start = calloc(1, 320 * 240 * 2);
create_dummy_frame();
@ -370,7 +428,8 @@ int DirectShow::Open() {
LoadSetting(EyeToyWebCamDevice::TypeName(), Port(), APINAME, N_DEVICE, selectedDevice);
int ret = InitializeDevice(selectedDevice);
if (ret < 0) {
if (ret < 0)
{
fprintf(stderr, "Camera: cannot find '%ls'\n", selectedDevice.c_str());
return -1;
}
@ -383,8 +442,10 @@ int DirectShow::Open() {
return 0;
};
int DirectShow::Close() {
if (sourcefilter != NULL) {
int DirectShow::Close()
{
if (sourcefilter != NULL)
{
this->Stop();
pControl->Stop();
@ -399,30 +460,36 @@ int DirectShow::Close() {
pGraph->Release();
pControl->Release();
if (mpeg_buffer.start != NULL) {
if (mpeg_buffer.start != NULL)
{
free(mpeg_buffer.start);
mpeg_buffer.start = NULL;
}
return 0;
};
int DirectShow::GetImage(uint8_t *buf, int len) {
int DirectShow::GetImage(uint8_t* buf, int len)
{
mpeg_mutex.lock();
int len2 = mpeg_buffer.length;
if (len < mpeg_buffer.length) len2 = len;
if (len < mpeg_buffer.length)
len2 = len;
memcpy(buf, mpeg_buffer.start, len2);
mpeg_mutex.unlock();
return len2;
};
BOOL CALLBACK DirectShowDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
BOOL CALLBACK DirectShowDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int port;
switch (uMsg) {
switch (uMsg)
{
case WM_CREATE:
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
break;
case WM_INITDIALOG: {
case WM_INITDIALOG:
{
port = (int)lParam;
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
@ -431,23 +498,29 @@ BOOL CALLBACK DirectShowDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam
SendDlgItemMessage(hW, IDC_COMBO1, CB_RESETCONTENT, 0, 0);
std::vector<std::wstring> devList = getDevList();
for (auto i = 0; i != devList.size(); i++) {
for (auto i = 0; i != devList.size(); i++)
{
SendDlgItemMessageW(hW, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)devList[i].c_str());
if (selectedDevice == devList.at(i)) {
if (selectedDevice == devList.at(i))
{
SendDlgItemMessage(hW, IDC_COMBO1, CB_SETCURSEL, i, i);
}
}
return TRUE;
}
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED) {
switch (LOWORD(wParam)) {
case IDOK: {
if (HIWORD(wParam) == BN_CLICKED)
{
switch (LOWORD(wParam))
{
case IDOK:
{
INT_PTR res = RESULT_OK;
static wchar_t selectedDevice[500] = {0};
GetWindowTextW(GetDlgItem(hW, IDC_COMBO1), selectedDevice, countof(selectedDevice));
port = (int)GetWindowLongPtr(hW, GWLP_USERDATA);
if (!SaveSetting<std::wstring>(EyeToyWebCamDevice::TypeName(), port, APINAME, N_DEVICE, selectedDevice)) {
if (!SaveSetting<std::wstring>(EyeToyWebCamDevice::TypeName(), port, APINAME, N_DEVICE, selectedDevice))
{
res = RESULT_FAILED;
}
EndDialog(hW, res);
@ -462,7 +535,8 @@ BOOL CALLBACK DirectShowDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam
return FALSE;
}
int DirectShow::Configure(int port, const char *dev_type, void *data) {
int DirectShow::Configure(int port, const char* dev_type, void* data)
{
Win32Handles handles = *(Win32Handles*)data;
return DialogBoxParam(handles.hInst,
MAKEINTRESOURCE(IDD_DLG_EYETOY),

View File

@ -29,13 +29,15 @@ extern "C" {
#pragma region qedit.h
struct __declspec(uuid("0579154a-2b53-4994-b0d0-e773148eff85"))
ISampleGrabberCB : IUnknown {
ISampleGrabberCB : IUnknown
{
virtual HRESULT __stdcall SampleCB(double SampleTime, struct IMediaSample* pSample) = 0;
virtual HRESULT __stdcall BufferCB(double SampleTime, unsigned char* pBuffer, long BufferLen) = 0;
};
struct __declspec(uuid("6b652fff-11fe-4fce-92ad-0266b5d7c78f"))
ISampleGrabber : IUnknown {
ISampleGrabber : IUnknown
{
virtual HRESULT __stdcall SetOneShot(long OneShot) = 0;
virtual HRESULT __stdcall SetMediaType(struct _AMMediaType* pType) = 0;
virtual HRESULT __stdcall GetConnectedMediaType(struct _AMMediaType* pType) = 0;
@ -70,14 +72,16 @@ namespace windows_api
typedef void (*DShowVideoCaptureCallback)(unsigned char* data, int len, int bitsperpixel);
typedef struct {
typedef struct
{
void* start = NULL;
size_t length = 0;
} buffer_t;
static const char* APINAME = "DirectShow";
class DirectShow : public VideoDevice {
class DirectShow : public VideoDevice
{
public:
DirectShow(int port);
~DirectShow() {}
@ -86,7 +90,8 @@ public:
int GetImage(uint8_t* buf, int len);
int Reset() { return 0; };
static const TCHAR *Name() {
static const TCHAR* Name()
{
return TEXT("DirectShow");
}
static int Configure(int port, const char* dev_type, void* data);

View File

@ -37,35 +37,160 @@
static const unsigned char s_jo_HTDC_Y[9][2] = {{4, 3}, {0, 2}, {1, 2}, {5, 3}, {6, 3}, {14, 4}, {30, 5}, {62, 6}, {126, 7}};
static const unsigned char s_jo_HTDC_C[9][2] = {{0, 2}, {1, 2}, {2, 2}, {6, 3}, {14, 4}, {30, 5}, {62, 6}, {126, 7}, {254, 8}};
static const unsigned char s_jo_HTAC[32][40][2] = {
{{6,3},{8,5},{10,6},{12,8},{76,9},{66,9},{20,11},{58,13},{48,13},{38,13},{32,13},{52,14},{50,14},{48,14},{46,14},{62,15},{62,15},{58,15},{56,15},{54,15},{52,15},{50,15},{48,15},{46,15},{44,15},{42,15},{40,15},{38,15},{36,15},{34,15},{32,15},{48,16},{46,16},{44,16},{42,16},{40,16},{38,16},{36,16},{34,16},{32,16},},
{
{6, 3},
{8, 5},
{10, 6},
{12, 8},
{76, 9},
{66, 9},
{20, 11},
{58, 13},
{48, 13},
{38, 13},
{32, 13},
{52, 14},
{50, 14},
{48, 14},
{46, 14},
{62, 15},
{62, 15},
{58, 15},
{56, 15},
{54, 15},
{52, 15},
{50, 15},
{48, 15},
{46, 15},
{44, 15},
{42, 15},
{40, 15},
{38, 15},
{36, 15},
{34, 15},
{32, 15},
{48, 16},
{46, 16},
{44, 16},
{42, 16},
{40, 16},
{38, 16},
{36, 16},
{34, 16},
{32, 16},
},
{{6, 4}, {12, 7}, {74, 9}, {24, 11}, {54, 13}, {44, 14}, {42, 14}, {62, 16}, {60, 16}, {58, 16}, {56, 16}, {54, 16}, {52, 16}, {50, 16}, {38, 17}, {36, 17}, {34, 17}, {32, 17}},
{{10, 5}, {8, 8}, {22, 11}, {40, 13}, {40, 14}},
{{14, 6}, {72, 9}, {56, 13}, {38, 14}},
{{12,6},{30,11},{36,13}}, {{14,7},{18,11},{36,14}}, {{10,7},{60,13},{40,17}},
{{8,7},{42,13}}, {{14,8},{34,13}}, {{10,8},{34,14}}, {{78,9},{32,14}}, {{70,9},{52,17}}, {{68,9},{50,17}}, {{64,9},{48,17}}, {{28,11},{46,17}}, {{26,11},{44,17}}, {{16,11},{42,17}},
{{62,13}}, {{52,13}}, {{50,13}}, {{46,13}}, {{44,13}}, {{62,14}}, {{60,14}}, {{58,14}}, {{56,14}}, {{54,14}}, {{62,17}}, {{60,17}}, {{58,17}}, {{56,17}}, {{54,17}},
{{12, 6}, {30, 11}, {36, 13}},
{{14, 7}, {18, 11}, {36, 14}},
{{10, 7}, {60, 13}, {40, 17}},
{{8, 7}, {42, 13}},
{{14, 8}, {34, 13}},
{{10, 8}, {34, 14}},
{{78, 9}, {32, 14}},
{{70, 9}, {52, 17}},
{{68, 9}, {50, 17}},
{{64, 9}, {48, 17}},
{{28, 11}, {46, 17}},
{{26, 11}, {44, 17}},
{{16, 11}, {42, 17}},
{{62, 13}},
{{52, 13}},
{{50, 13}},
{{46, 13}},
{{44, 13}},
{{62, 14}},
{{60, 14}},
{{58, 14}},
{{56, 14}},
{{54, 14}},
{{62, 17}},
{{60, 17}},
{{58, 17}},
{{56, 17}},
{{54, 17}},
};
static const float s_jo_quantTbl[64] = {
0.015625f,0.005632f,0.005035f,0.004832f,0.004808f,0.005892f,0.007964f,0.013325f,
0.005632f,0.004061f,0.003135f,0.003193f,0.003338f,0.003955f,0.004898f,0.008828f,
0.005035f,0.003135f,0.002816f,0.003013f,0.003299f,0.003581f,0.005199f,0.009125f,
0.004832f,0.003484f,0.003129f,0.003348f,0.003666f,0.003979f,0.005309f,0.009632f,
0.005682f,0.003466f,0.003543f,0.003666f,0.003906f,0.004546f,0.005774f,0.009439f,
0.006119f,0.004248f,0.004199f,0.004228f,0.004546f,0.005062f,0.006124f,0.009942f,
0.008883f,0.006167f,0.006096f,0.005777f,0.006078f,0.006391f,0.007621f,0.012133f,
0.016780f,0.011263f,0.009907f,0.010139f,0.009849f,0.010297f,0.012133f,0.019785f,
0.015625f,
0.005632f,
0.005035f,
0.004832f,
0.004808f,
0.005892f,
0.007964f,
0.013325f,
0.005632f,
0.004061f,
0.003135f,
0.003193f,
0.003338f,
0.003955f,
0.004898f,
0.008828f,
0.005035f,
0.003135f,
0.002816f,
0.003013f,
0.003299f,
0.003581f,
0.005199f,
0.009125f,
0.004832f,
0.003484f,
0.003129f,
0.003348f,
0.003666f,
0.003979f,
0.005309f,
0.009632f,
0.005682f,
0.003466f,
0.003543f,
0.003666f,
0.003906f,
0.004546f,
0.005774f,
0.009439f,
0.006119f,
0.004248f,
0.004199f,
0.004228f,
0.004546f,
0.005062f,
0.006124f,
0.009942f,
0.008883f,
0.006167f,
0.006096f,
0.005777f,
0.006078f,
0.006391f,
0.007621f,
0.012133f,
0.016780f,
0.011263f,
0.009907f,
0.010139f,
0.009849f,
0.010297f,
0.012133f,
0.019785f,
};
static const unsigned char s_jo_ZigZag[] = {0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63};
typedef struct {
typedef struct
{
unsigned char* buf_ptr;
int buf, cnt;
} jo_bits_t;
static void jo_writeBits(jo_bits_t *b, int value, int count) {
static void jo_writeBits(jo_bits_t* b, int value, int count)
{
b->cnt += count;
b->buf |= value << (24 - b->cnt);
while(b->cnt >= 8) {
while (b->cnt >= 8)
{
unsigned char c = (b->buf >> 16) & 255;
//putc(c, b->fp);
*(b->buf_ptr) = c & 0xff;
@ -75,7 +200,8 @@ static void jo_writeBits(jo_bits_t *b, int value, int count) {
}
}
static void jo_DCT(float *d0, float *d1, float *d2, float *d3, float *d4, float *d5, float *d6, float *d7) {
static void jo_DCT(float* d0, float* d1, float* d2, float* d3, float* d4, float* d5, float* d6, float* d7)
{
float tmp0 = *d0 + *d7;
float tmp7 = *d0 - *d7;
float tmp1 = *d1 + *d6;
@ -118,15 +244,19 @@ static void jo_DCT(float *d0, float *d1, float *d2, float *d3, float *d4, float
*d7 = z11 - z4;
}
static int jo_processDU(jo_bits_t *bits, float A[64], const unsigned char htdc[9][2], int DC) {
for(int dataOff=0; dataOff<64; dataOff+=8) {
static int jo_processDU(jo_bits_t* bits, float A[64], const unsigned char htdc[9][2], int DC)
{
for (int dataOff = 0; dataOff < 64; dataOff += 8)
{
jo_DCT(&A[dataOff], &A[dataOff + 1], &A[dataOff + 2], &A[dataOff + 3], &A[dataOff + 4], &A[dataOff + 5], &A[dataOff + 6], &A[dataOff + 7]);
}
for(int dataOff=0; dataOff<8; ++dataOff) {
for (int dataOff = 0; dataOff < 8; ++dataOff)
{
jo_DCT(&A[dataOff], &A[dataOff + 8], &A[dataOff + 16], &A[dataOff + 24], &A[dataOff + 32], &A[dataOff + 40], &A[dataOff + 48], &A[dataOff + 56]);
}
int Q[64];
for(int i=0; i<64; ++i) {
for (int i = 0; i < 64; ++i)
{
float v = A[i] * s_jo_quantTbl[i];
Q[s_jo_ZigZag[i]] = (int)(v < 0 ? ceilf(v - 0.5f) : floorf(v + 0.5f));
}
@ -135,36 +265,48 @@ static int jo_processDU(jo_bits_t *bits, float A[64], const unsigned char htdc[9
int aDC = DC < 0 ? -DC : DC;
int size = 0;
int tempval = aDC;
while(tempval) {
while (tempval)
{
size++;
tempval >>= 1;
}
jo_writeBits(bits, htdc[size][0], htdc[size][1]);
if(DC < 0) aDC ^= (1 << size) - 1;
if (DC < 0)
aDC ^= (1 << size) - 1;
jo_writeBits(bits, aDC, size);
int endpos = 63;
for(; (endpos>0)&&(Q[endpos]==0); --endpos) { /* do nothing */ }
for(int i = 1; i <= endpos;) {
for (; (endpos > 0) && (Q[endpos] == 0); --endpos)
{ /* do nothing */
}
for (int i = 1; i <= endpos;)
{
int run = 0;
while (Q[i]==0 && i<endpos) {
while (Q[i] == 0 && i < endpos)
{
++run;
++i;
}
int AC = Q[i++];
int aAC = AC < 0 ? -AC : AC;
int code = 0, size = 0;
if (run<32 && aAC<=40) {
if (run < 32 && aAC <= 40)
{
code = s_jo_HTAC[run][aAC - 1][0];
size = s_jo_HTAC[run][aAC - 1][1];
if (AC < 0) code += 1;
if (AC < 0)
code += 1;
}
if(!size) {
if (!size)
{
jo_writeBits(bits, 1, 6);
jo_writeBits(bits, run, 6);
if (AC < -127) {
if (AC < -127)
{
jo_writeBits(bits, 128, 12);
} else if(AC > 127) {
}
else if (AC > 127)
{
jo_writeBits(bits, 0, 12);
}
code = AC & 0xFFF;
@ -177,17 +319,23 @@ static int jo_processDU(jo_bits_t *bits, float A[64], const unsigned char htdc[9
return Q[0];
}
unsigned long jo_write_mpeg(unsigned char *mpeg_buf, const unsigned char *raw, int width, int height, int format, int flipx, int flipy) {
unsigned long jo_write_mpeg(unsigned char* mpeg_buf, const unsigned char* raw, int width, int height, int format, int flipx, int flipy)
{
int lastDCY = 128, lastDCCR = 128, lastDCCB = 128;
unsigned char* head = mpeg_buf;
jo_bits_t bits = {mpeg_buf};
for (int vblock = 0; vblock < (height+15)/16; vblock++) {
for (int hblock = 0; hblock < (width+15)/16; hblock++) {
if (vblock == 0 && hblock == 0) {
for (int vblock = 0; vblock < (height + 15) / 16; vblock++)
{
for (int hblock = 0; hblock < (width + 15) / 16; hblock++)
{
if (vblock == 0 && hblock == 0)
{
jo_writeBits(&bits, 0b01, 2); // macroblock_type = intra+quant
jo_writeBits(&bits, 8, 5); // quantiser_scale_code = 8
} else {
}
else
{
jo_writeBits(&bits, 0b1, 1); // macroblock_address_increment
jo_writeBits(&bits, 0b1, 1); // macroblock_type = intra
}
@ -195,19 +343,26 @@ unsigned long jo_write_mpeg(unsigned char *mpeg_buf, const unsigned char *raw, i
float Y[256], CBx[256], CRx[256];
float CB[64], CR[64];
if (format == JO_RGBX) {
for (int i=0; i<256; ++i) {
if (format == JO_RGBX)
{
for (int i = 0; i < 256; ++i)
{
int y = vblock * 16 + (i / 16);
int x = hblock * 16 + (i & 15);
x = x >= width ? width - 1 : x;
y = y >= height ? height - 1 : y;
if (flipx) x = width - 1 - x;
if (flipy) y = height - 1 - y;
if (flipx)
x = width - 1 - x;
if (flipy)
y = height - 1 - y;
const unsigned char* c = raw + y * width * 4 + x * 4;
float r, g, b;
if (flipx && flipy) {
if (flipx && flipy)
{
r = c[2], g = c[1], b = c[0];
} else {
}
else
{
r = c[0], g = c[1], b = c[2];
}
Y[i] = (0.299f * r + 0.587f * g + 0.114f * b) * (219.f / 255) + 16;
@ -215,25 +370,33 @@ unsigned long jo_write_mpeg(unsigned char *mpeg_buf, const unsigned char *raw, i
CRx[i] = (0.701f * r - 0.587f * g - 0.114f * b) * (224.f / 255) + 128;
}
// Downsample Cb,Cr (420 format)
for (int i=0; i<64; ++i) {
for (int i = 0; i < 64; ++i)
{
int j = (i & 7) * 2 + (i & 56) * 4;
CB[i] = (CBx[j] + CBx[j + 1] + CBx[j + 16] + CBx[j + 17]) * 0.25f;
CR[i] = (CRx[j] + CRx[j + 1] + CRx[j + 16] + CRx[j + 17]) * 0.25f;
}
} else
if (format == JO_RGB24) {
for (int i=0; i<256; ++i) {
}
else if (format == JO_RGB24)
{
for (int i = 0; i < 256; ++i)
{
int y = vblock * 16 + (i / 16);
int x = hblock * 16 + (i & 15);
x = x >= width ? width - 1 : x;
y = y >= height ? height - 1 : y;
if (flipx) x = width - 1 - x;
if (flipy) y = height - 1 - y;
if (flipx)
x = width - 1 - x;
if (flipy)
y = height - 1 - y;
const unsigned char* c = raw + y * width * 3 + x * 3;
float r, g, b;
if (flipx && flipy) {
if (flipx && flipy)
{
r = c[2], g = c[1], b = c[0];
} else {
}
else
{
r = c[0], g = c[1], b = c[2];
}
Y[i] = (0.299f * r + 0.587f * g + 0.114f * b) * (219.f / 255) + 16;
@ -241,27 +404,35 @@ unsigned long jo_write_mpeg(unsigned char *mpeg_buf, const unsigned char *raw, i
CRx[i] = (0.701f * r - 0.587f * g - 0.114f * b) * (224.f / 255) + 128;
}
// Downsample Cb,Cr (420 format)
for (int i=0; i<64; ++i) {
for (int i = 0; i < 64; ++i)
{
int j = (i & 7) * 2 + (i & 56) * 4;
CB[i] = (CBx[j] + CBx[j + 1] + CBx[j + 16] + CBx[j + 17]) * 0.25f;
CR[i] = (CRx[j] + CRx[j + 1] + CRx[j + 16] + CRx[j + 17]) * 0.25f;
}
} else
if (format == JO_YUYV) {
for (int i=0; i<256; i+=2) {
}
else if (format == JO_YUYV)
{
for (int i = 0; i < 256; i += 2)
{
int y = vblock * 16 + (i / 16);
int x = hblock * 16 + (i & 15);
x = x >= width ? width - 1 : x;
y = y >= height ? height - 1 : y;
if (flipx) x = width - 1 - x;
if (flipy) y = height - 1 - y;
if (flipx)
x = width - 1 - x;
if (flipy)
y = height - 1 - y;
const unsigned char* c = raw + y * width * 2 + x * 2 - 2;
if (flipx) {
if (flipx)
{
Y[i + 1] = c[0];
CB[i / 4] = c[1];
Y[i] = c[2];
CR[i / 4] = c[3];
} else {
}
else
{
Y[i] = c[2];
CB[i / 4] = c[3];
Y[i + 1] = c[4];
@ -270,10 +441,13 @@ unsigned long jo_write_mpeg(unsigned char *mpeg_buf, const unsigned char *raw, i
}
}
for (int k1=0; k1<2; ++k1) {
for (int k2=0; k2<2; ++k2) {
for (int k1 = 0; k1 < 2; ++k1)
{
for (int k2 = 0; k2 < 2; ++k2)
{
float block[64];
for (int i=0; i<64; i+=8) {
for (int i = 0; i < 64; i += 8)
{
int j = (i & 7) + (i & 56) * 2 + k1 * 8 * 16 + k2 * 8;
memcpy(block + i, Y + j, 8 * sizeof(Y[0]));
}

View File

@ -17,13 +17,15 @@
extern "C" {
#endif
typedef enum {
typedef enum
{
JO_RGBX,
JO_RGB24,
JO_YUYV,
} jo_mpeg_format_t;
typedef enum {
typedef enum
{
JO_NONE,
JO_FLIP_X,
JO_FLIP_Y,

View File

@ -55,7 +55,8 @@
#define JPGD_MAX(a, b) (((a) > (b)) ? (a) : (b))
#define JPGD_MIN(a, b) (((a) < (b)) ? (a) : (b))
namespace jpgd {
namespace jpgd
{
static inline void* jpgd_malloc(size_t nSize) { return malloc(nSize); }
static inline void jpgd_free(void* p) { free(p); }
@ -65,14 +66,56 @@ namespace jpgd {
enum JPEG_MARKER
{
M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8,
M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC,
M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7,
M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF,
M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0
M_SOF0 = 0xC0,
M_SOF1 = 0xC1,
M_SOF2 = 0xC2,
M_SOF3 = 0xC3,
M_SOF5 = 0xC5,
M_SOF6 = 0xC6,
M_SOF7 = 0xC7,
M_JPG = 0xC8,
M_SOF9 = 0xC9,
M_SOF10 = 0xCA,
M_SOF11 = 0xCB,
M_SOF13 = 0xCD,
M_SOF14 = 0xCE,
M_SOF15 = 0xCF,
M_DHT = 0xC4,
M_DAC = 0xCC,
M_RST0 = 0xD0,
M_RST1 = 0xD1,
M_RST2 = 0xD2,
M_RST3 = 0xD3,
M_RST4 = 0xD4,
M_RST5 = 0xD5,
M_RST6 = 0xD6,
M_RST7 = 0xD7,
M_SOI = 0xD8,
M_EOI = 0xD9,
M_SOS = 0xDA,
M_DQT = 0xDB,
M_DNL = 0xDC,
M_DRI = 0xDD,
M_DHP = 0xDE,
M_EXP = 0xDF,
M_APP0 = 0xE0,
M_APP15 = 0xEF,
M_JPG0 = 0xF0,
M_JPG13 = 0xFD,
M_COM = 0xFE,
M_TEM = 0x01,
M_ERROR = 0x100,
RST0 = 0xD0
};
enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 };
enum JPEG_SUBSAMPLING
{
JPGD_GRAYSCALE = 0,
JPGD_YH1V1,
JPGD_YH2V1,
JPGD_YH1V2,
JPGD_YH2V2
};
#if JPGD_USE_SSE2
#include "jpgd_idct.h"
@ -263,21 +306,524 @@ namespace jpgd {
static const uint8 s_idct_row_table[] =
{
1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0,
4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0,
6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0,
6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0,
8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2,
8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2,
8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4,
8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8,
1,
0,
0,
0,
0,
0,
0,
0,
2,
0,
0,
0,
0,
0,
0,
0,
2,
1,
0,
0,
0,
0,
0,
0,
2,
1,
1,
0,
0,
0,
0,
0,
2,
2,
1,
0,
0,
0,
0,
0,
3,
2,
1,
0,
0,
0,
0,
0,
4,
2,
1,
0,
0,
0,
0,
0,
4,
3,
1,
0,
0,
0,
0,
0,
4,
3,
2,
0,
0,
0,
0,
0,
4,
3,
2,
1,
0,
0,
0,
0,
4,
3,
2,
1,
1,
0,
0,
0,
4,
3,
2,
2,
1,
0,
0,
0,
4,
3,
3,
2,
1,
0,
0,
0,
4,
4,
3,
2,
1,
0,
0,
0,
5,
4,
3,
2,
1,
0,
0,
0,
6,
4,
3,
2,
1,
0,
0,
0,
6,
5,
3,
2,
1,
0,
0,
0,
6,
5,
4,
2,
1,
0,
0,
0,
6,
5,
4,
3,
1,
0,
0,
0,
6,
5,
4,
3,
2,
0,
0,
0,
6,
5,
4,
3,
2,
1,
0,
0,
6,
5,
4,
3,
2,
1,
1,
0,
6,
5,
4,
3,
2,
2,
1,
0,
6,
5,
4,
3,
3,
2,
1,
0,
6,
5,
4,
4,
3,
2,
1,
0,
6,
5,
5,
4,
3,
2,
1,
0,
6,
6,
5,
4,
3,
2,
1,
0,
7,
6,
5,
4,
3,
2,
1,
0,
8,
6,
5,
4,
3,
2,
1,
0,
8,
7,
5,
4,
3,
2,
1,
0,
8,
7,
6,
4,
3,
2,
1,
0,
8,
7,
6,
5,
3,
2,
1,
0,
8,
7,
6,
5,
4,
2,
1,
0,
8,
7,
6,
5,
4,
3,
1,
0,
8,
7,
6,
5,
4,
3,
2,
0,
8,
7,
6,
5,
4,
3,
2,
1,
8,
7,
6,
5,
4,
3,
2,
2,
8,
7,
6,
5,
4,
3,
3,
2,
8,
7,
6,
5,
4,
4,
3,
2,
8,
7,
6,
5,
5,
4,
3,
2,
8,
7,
6,
6,
5,
4,
3,
2,
8,
7,
7,
6,
5,
4,
3,
2,
8,
8,
7,
6,
5,
4,
3,
2,
8,
8,
8,
6,
5,
4,
3,
2,
8,
8,
8,
7,
5,
4,
3,
2,
8,
8,
8,
7,
6,
4,
3,
2,
8,
8,
8,
7,
6,
5,
3,
2,
8,
8,
8,
7,
6,
5,
4,
2,
8,
8,
8,
7,
6,
5,
4,
3,
8,
8,
8,
7,
6,
5,
4,
4,
8,
8,
8,
7,
6,
5,
5,
4,
8,
8,
8,
7,
6,
6,
5,
4,
8,
8,
8,
7,
7,
6,
5,
4,
8,
8,
8,
8,
7,
6,
5,
4,
8,
8,
8,
8,
8,
6,
5,
4,
8,
8,
8,
8,
8,
7,
5,
4,
8,
8,
8,
8,
8,
7,
6,
4,
8,
8,
8,
8,
8,
7,
6,
5,
8,
8,
8,
8,
8,
7,
6,
6,
8,
8,
8,
8,
8,
7,
7,
6,
8,
8,
8,
8,
8,
8,
7,
6,
8,
8,
8,
8,
8,
8,
8,
6,
8,
8,
8,
8,
8,
8,
8,
7,
8,
8,
8,
8,
8,
8,
8,
8,
};
static const uint8 s_idct_col_table[] =
{
1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
};
7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
// Scalar "fast pathing" IDCT.
static void idct(const jpgd_block_coeff_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag, bool use_simd)
@ -324,15 +870,33 @@ namespace jpgd {
{
switch (*pRow_tab)
{
case 0: Row<0>::idct(pTemp, pSrc); break;
case 1: Row<1>::idct(pTemp, pSrc); break;
case 2: Row<2>::idct(pTemp, pSrc); break;
case 3: Row<3>::idct(pTemp, pSrc); break;
case 4: Row<4>::idct(pTemp, pSrc); break;
case 5: Row<5>::idct(pTemp, pSrc); break;
case 6: Row<6>::idct(pTemp, pSrc); break;
case 7: Row<7>::idct(pTemp, pSrc); break;
case 8: Row<8>::idct(pTemp, pSrc); break;
case 0:
Row<0>::idct(pTemp, pSrc);
break;
case 1:
Row<1>::idct(pTemp, pSrc);
break;
case 2:
Row<2>::idct(pTemp, pSrc);
break;
case 3:
Row<3>::idct(pTemp, pSrc);
break;
case 4:
Row<4>::idct(pTemp, pSrc);
break;
case 5:
Row<5>::idct(pTemp, pSrc);
break;
case 6:
Row<6>::idct(pTemp, pSrc);
break;
case 7:
Row<7>::idct(pTemp, pSrc);
break;
case 8:
Row<8>::idct(pTemp, pSrc);
break;
}
pSrc += 8;
@ -346,14 +910,30 @@ namespace jpgd {
{
switch (nonzero_rows)
{
case 1: Col<1>::idct(pDst_ptr, pTemp); break;
case 2: Col<2>::idct(pDst_ptr, pTemp); break;
case 3: Col<3>::idct(pDst_ptr, pTemp); break;
case 4: Col<4>::idct(pDst_ptr, pTemp); break;
case 5: Col<5>::idct(pDst_ptr, pTemp); break;
case 6: Col<6>::idct(pDst_ptr, pTemp); break;
case 7: Col<7>::idct(pDst_ptr, pTemp); break;
case 8: Col<8>::idct(pDst_ptr, pTemp); break;
case 1:
Col<1>::idct(pDst_ptr, pTemp);
break;
case 2:
Col<2>::idct(pDst_ptr, pTemp);
break;
case 3:
Col<3>::idct(pDst_ptr, pTemp);
break;
case 4:
Col<4>::idct(pDst_ptr, pTemp);
break;
case 5:
Col<5>::idct(pDst_ptr, pTemp);
break;
case 6:
Col<6>::idct(pDst_ptr, pTemp);
break;
case 7:
Col<7>::idct(pDst_ptr, pTemp);
break;
case 8:
Col<8>::idct(pDst_ptr, pTemp);
break;
}
pTemp++;
@ -671,7 +1251,8 @@ namespace jpgd {
b->m_size = capacity;
rv = b->m_data;
}
if (zero) memset(rv, 0, nSize);
if (zero)
memset(rv, 0, nSize);
return rv;
}
@ -1473,7 +2054,11 @@ namespace jpgd {
get_bits_no_markers(16);
}
static inline int dequantize_ac(int c, int q) { c *= q; return c; }
static inline int dequantize_ac(int c, int q)
{
c *= q;
return c;
}
// Decodes and dequantizes the next row of coefficients.
void jpeg_decoder::decode_next_row()
@ -1919,9 +2504,11 @@ namespace jpgd {
static const uint8_t s_muls[2][2][4] =
{
{ { 1, 3, 3, 9 }, { 3, 9, 1, 3 }, },
{ { 3, 1, 9, 3 }, { 9, 3, 3, 1 } }
};
{
{1, 3, 3, 9},
{3, 9, 1, 3},
},
{{3, 1, 9, 3}, {9, 3, 3, 1}}};
if (((row & 15) >= 1) && ((row & 15) <= 14))
{

View File

@ -40,15 +40,42 @@ namespace jpgd
// Success/failure error codes.
enum jpgd_status
{
JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1,
JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE,
JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS,
JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH,
JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER,
JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS,
JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE,
JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER,
JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM, JPGD_TOO_MANY_SCANS
JPGD_SUCCESS = 0,
JPGD_FAILED = -1,
JPGD_DONE = 1,
JPGD_BAD_DHT_COUNTS = -256,
JPGD_BAD_DHT_INDEX,
JPGD_BAD_DHT_MARKER,
JPGD_BAD_DQT_MARKER,
JPGD_BAD_DQT_TABLE,
JPGD_BAD_PRECISION,
JPGD_BAD_HEIGHT,
JPGD_BAD_WIDTH,
JPGD_TOO_MANY_COMPONENTS,
JPGD_BAD_SOF_LENGTH,
JPGD_BAD_VARIABLE_MARKER,
JPGD_BAD_DRI_LENGTH,
JPGD_BAD_SOS_LENGTH,
JPGD_BAD_SOS_COMP_ID,
JPGD_W_EXTRA_BYTES_BEFORE_MARKER,
JPGD_NO_ARITHMITIC_SUPPORT,
JPGD_UNEXPECTED_MARKER,
JPGD_NOT_JPEG,
JPGD_UNSUPPORTED_MARKER,
JPGD_BAD_DQT_LENGTH,
JPGD_TOO_MANY_BLOCKS,
JPGD_UNDEFINED_QUANT_TABLE,
JPGD_UNDEFINED_HUFF_TABLE,
JPGD_NOT_SINGLE_SCAN,
JPGD_UNSUPPORTED_COLORSPACE,
JPGD_UNSUPPORTED_SAMP_FACTORS,
JPGD_DECODE_ERROR,
JPGD_BAD_RESTART_MARKER,
JPGD_BAD_SOS_SPECTRAL,
JPGD_BAD_SOS_SUCCESSIVE,
JPGD_STREAM_READ,
JPGD_NOTENOUGHMEM,
JPGD_TOO_MANY_SCANS
};
// Input stream interface.
@ -98,13 +125,28 @@ namespace jpgd
uint m_ofs, m_size;
public:
jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { }
jpeg_decoder_mem_stream(const uint8* pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { }
jpeg_decoder_mem_stream()
: m_pSrc_data(NULL)
, m_ofs(0)
, m_size(0)
{
}
jpeg_decoder_mem_stream(const uint8* pSrc_data, uint size)
: m_pSrc_data(pSrc_data)
, m_ofs(0)
, m_size(size)
{
}
virtual ~jpeg_decoder_mem_stream() {}
bool open(const uint8* pSrc_data, uint size);
void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; }
void close()
{
m_pSrc_data = NULL;
m_ofs = 0;
m_size = 0;
}
virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag);
};
@ -114,8 +156,15 @@ namespace jpgd
enum
{
JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4,
JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 16384, JPGD_MAX_HEIGHT = 32768, JPGD_MAX_WIDTH = 32768
JPGD_IN_BUF_SIZE = 8192,
JPGD_MAX_BLOCKS_PER_MCU = 10,
JPGD_MAX_HUFF_TABLES = 8,
JPGD_MAX_QUANT_TABLES = 4,
JPGD_MAX_COMPONENTS = 4,
JPGD_MAX_COMPS_IN_SCAN = 4,
JPGD_MAX_BLOCKS_PER_ROW = 16384,
JPGD_MAX_HEIGHT = 32768,
JPGD_MAX_WIDTH = 32768
};
typedef int16 jpgd_quant_t;
@ -275,7 +324,12 @@ namespace jpgd
bool m_sample_buf_prev_valid;
bool m_has_sse2;
inline int check_sample_buf_ofs(int ofs) const { assert(ofs >= 0); assert(ofs < m_max_blocks_per_row * 64); return ofs; }
inline int check_sample_buf_ofs(int ofs) const
{
assert(ofs >= 0);
assert(ofs < m_max_blocks_per_row * 64);
return ofs;
}
void free_all_blocks();
JPGD_NORETURN void stop_decoding(jpgd_status status);
void* alloc(size_t n, bool zero = false);

View File

@ -53,4 +53,3 @@
#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */
#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
#define OV7610_REG_COM_I 0x29 /* misc settings */

View File

@ -19,7 +19,8 @@
#include "ov519.h"
#include "../qemu-usb/desc.h"
namespace usb_eyetoy {
namespace usb_eyetoy
{
static const USBDescStrings desc_strings = {
"",
@ -27,7 +28,8 @@ static const USBDescStrings desc_strings = {
"EyeToy USB camera Namtai",
};
typedef struct EYETOYState {
typedef struct EYETOYState
{
USBDevice dev;
USBDesc desc;
USBDescDevice desc_dev;
@ -328,11 +330,13 @@ static void eyetoy_handle_control(USBDevice *dev, USBPacket *p, int request, int
int ret = 0;
ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
if (ret >= 0) {
if (ret >= 0)
{
return;
}
switch(request) {
switch (request)
{
case VendorDeviceRequest | 0x1: //Read register
data[0] = s->regs[index & 0xFF];
OSDebugOut(TEXT("=== READ reg 0x%02x = 0x%02x (%d)\n"), index, data[0], data[0]);
@ -340,7 +344,8 @@ static void eyetoy_handle_control(USBDevice *dev, USBPacket *p, int request, int
break;
case VendorDeviceOutRequest | 0x1: //Write register
if (!(index >= R51x_I2C_SADDR_3 && index <= R518_I2C_CTL)) {
if (!(index >= R51x_I2C_SADDR_3 && index <= R518_I2C_CTL))
{
OSDebugOut(TEXT("*** WRITE reg 0x%02x = 0x%02x (%d)\n"), index, data[0], data[0]);
}
@ -417,28 +422,30 @@ static void eyetoy_handle_data(USBDevice *dev, USBPacket *p)
uint8_t data[max_ep_size];
uint8_t devep = p->ep->nr;
switch(p->pid) {
switch (p->pid)
{
case USB_TOKEN_IN:
if (devep == 1) {
if (devep == 1)
{
memset(data, 0xff, sizeof(data));
if (s->frame_step == 0) {
if (s->frame_step == 0)
{
s->mpeg_frame_size = s->videodev->GetImage(s->mpeg_frame_data, 320 * 240 * 2);
if (s->mpeg_frame_size == 0) {
if (s->mpeg_frame_size == 0)
{
goto send_packet;
}
s->mpeg_frame_offset = 0;
uint8_t header1[] = {
0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
};
0xFF, 0xFF, 0xFF, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
memcpy(data, header1, sizeof(header1));
uint8_t header2[] = {
0x69, 0x70, 0x75, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xF0, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00
};
0x00};
memcpy(data + sizeof(header1), header2, sizeof(header2));
int data_pk = max_ep_size - sizeof(header1) - sizeof(header2);
@ -446,7 +453,9 @@ static void eyetoy_handle_data(USBDevice *dev, USBPacket *p)
s->mpeg_frame_offset = data_pk;
s->frame_step++;
} else if (s->frame_step < 10) {
}
else if (s->frame_step < 10)
{
int data_pk = s->mpeg_frame_size - s->mpeg_frame_offset;
if (data_pk > max_ep_size)
data_pk = max_ep_size;
@ -454,10 +463,11 @@ static void eyetoy_handle_data(USBDevice *dev, USBPacket *p)
s->mpeg_frame_offset += data_pk;
s->frame_step++;
} else if (s->frame_step == 10) {
}
else if (s->frame_step == 10)
{
uint8_t footer[] = {
0xFF, 0xFF, 0xFF, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
};
0xFF, 0xFF, 0xFF, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
memcpy(data, footer, sizeof(footer));
s->frame_step = 0;
}
@ -465,7 +475,8 @@ static void eyetoy_handle_data(USBDevice *dev, USBPacket *p)
send_packet:
usb_packet_copy(p, data, max_ep_size);
}
else if (devep == 2) {
else if (devep == 2)
{
// get audio
//fprintf(stderr, "get audio %d\n", len);
memset(data, 0, p->iov.size);
@ -589,4 +600,4 @@ int EyeToyWebCamDevice::Freeze(int mode, USBDevice *dev, void *data)
return -1;
}
} //namespace
} // namespace usb_eyetoy

View File

@ -23,7 +23,8 @@
#include <mutex>
namespace usb_eyetoy {
namespace usb_eyetoy
{
class EyeToyWebCamDevice
{
@ -53,6 +54,6 @@ public:
static int Freeze(int mode, USBDevice* dev, void* data);
};
} //namespace
} // namespace usb_eyetoy
#endif

View File

@ -18,7 +18,8 @@
#include "../qemu-usb/vl.h"
#include "../configuration.h"
namespace usb_eyetoy {
namespace usb_eyetoy
{
class VideoDevice
{
@ -36,5 +37,5 @@ protected:
int mPort;
};
} //namespace
} // namespace usb_eyetoy
#endif

View File

@ -24,12 +24,16 @@
#include "../helpers.h"
#include "../deviceproxy.h"
namespace usb_eyetoy {
namespace usb_eyetoy
{
class VideoDeviceError : public std::runtime_error
{
public:
VideoDeviceError(const char* msg) : std::runtime_error(msg) {}
VideoDeviceError(const char* msg)
: std::runtime_error(msg)
{
}
virtual ~VideoDeviceError() throw() {}
};
@ -50,7 +54,10 @@ class VideoDeviceProxy : public VideoDeviceProxyBase
public:
VideoDeviceProxy() {}
VideoDeviceProxy(const std::string& name): VideoDeviceProxyBase(name) {}
VideoDeviceProxy(const std::string& name)
: VideoDeviceProxyBase(name)
{
}
VideoDevice* CreateObject(int port) const
{
try
@ -79,5 +86,5 @@ class RegisterVideoDevice : public RegisterProxy<VideoDeviceProxyBase>
static void Register();
};
} //namespace
} // namespace usb_eyetoy
#endif

View File

@ -23,12 +23,16 @@
GtkWidget* new_combobox(const char* label, GtkWidget* vbox); // src/linux/config-gtk.cpp
namespace usb_hid { namespace evdev {
namespace usb_hid
{
namespace evdev
{
#define EVDEV_DIR "/dev/input/by-path/"
typedef std::vector<std::pair<std::string, std::string>> devs_t;
struct ConfigData {
struct ConfigData
{
int port;
devs_t devs;
devs_t::const_iterator iter;
@ -44,7 +48,8 @@ static void PopulateHIDs(ConfigData &cfg, HIDType hid_type)
cfg.devs.push_back(std::make_pair("None", ""));
DIR* dirp = opendir(EVDEV_DIR);
if(dirp == NULL) {
if (dirp == NULL)
{
fprintf(stderr, "Error opening " EVDEV_DIR ": %s\n", strerror(errno));
return;
}
@ -58,10 +63,12 @@ static void PopulateHIDs(ConfigData &cfg, HIDType hid_type)
if (devlen >= len)
{
const char* const start = dp->d_name + devlen - len;
if(strncmp(start, devstr[hid_type], len) == 0) {
if (strncmp(start, devstr[hid_type], len) == 0)
{
OSDebugOut("%s%s\n", EVDEV_DIR, dp->d_name);
str.clear(); str.str("");
str.clear();
str.str("");
str << EVDEV_DIR << dp->d_name;
char name[1024];
@ -168,7 +175,8 @@ int GtkHidConfigure(int port, const char* dev_type, HIDType hid_type, GtkWindow
int ret = RESULT_OK;
if (result == GTK_RESPONSE_OK)
{
if (cfg.iter != cfg.devs.end()) {
if (cfg.iter != cfg.devs.end())
{
if (!SaveSetting(dev_type, port, APINAME, N_DEVICE, cfg.iter->second))
ret = RESULT_FAILED;
}
@ -186,4 +194,5 @@ int EvDev::Configure(int port, const char* dev_type, HIDType hid_type, void *dat
}
#undef EVDEV_DIR
}} //namespace
} // namespace evdev
} // namespace usb_hid

View File

@ -27,7 +27,10 @@ extern Display *g_GSdsp;
extern Window g_GSwin;
#endif
namespace usb_hid { namespace evdev {
namespace usb_hid
{
namespace evdev
{
#define test_bit(nr, addr) \
(((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
@ -43,21 +46,25 @@ bool FindHid(const std::string &evphys, std::string& hid_dev)
struct dirent* dp;
DIR* dirp = opendir("/dev/input/");
if(dirp == NULL) {
if (dirp == NULL)
{
perror("Error opening /dev/input/");
return false;
}
while ((dp = readdir(dirp)) != NULL)
{
if(strncmp(dp->d_name, "hidraw", 6) == 0) {
if (strncmp(dp->d_name, "hidraw", 6) == 0)
{
OSDebugOut("%s\n", dp->d_name);
str.clear(); str.str("");
str.clear();
str.str("");
str << "/dev/input/" << dp->d_name;
fd = open(str.str().c_str(), O_RDWR | O_NONBLOCK);
if (fd < 0) {
if (fd < 0)
{
perror("Unable to open device");
continue;
}
@ -71,7 +78,8 @@ bool FindHid(const std::string &evphys, std::string& hid_dev)
else
OSDebugOut("Raw Phys: %s\n", buf);*/
close(fd);
if (evphys == buf) {
if (evphys == buf)
{
closedir(dirp);
hid_dev = str.str();
return true;
@ -249,14 +257,18 @@ void EvDev::ReaderThread(void *ptr)
if (event.code == KEY_LEFTSHIFT || event.code == KEY_RIGHTSHIFT)
shift = (event.value > 0);
if (event.code == KEY_F12 && (event.value == 1) && shift) {
if (!grabbed) {
if (event.code == KEY_F12 && (event.value == 1) && shift)
{
if (!grabbed)
{
grabbed = true;
XGrabPointer(g_GSdsp, g_GSwin, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, g_GSwin, None, CurrentTime);
XGrabKeyboard(g_GSdsp, g_GSwin, True, GrabModeAsync, GrabModeAsync, CurrentTime);
// Hides globally :(
XFixesHideCursor(g_GSdsp, g_GSwin);
} else {
}
else
{
grabbed = false;
XUngrabPointer(g_GSdsp, CurrentTime);
XUngrabKeyboard(g_GSdsp, CurrentTime);
@ -265,13 +277,15 @@ void EvDev::ReaderThread(void *ptr)
}
#endif
if (hs->kbd.eh_entry) {
if (hs->kbd.eh_entry)
{
QKeyCode qcode = Q_KEY_CODE_UNMAPPED;
if (event.code < (uint16_t)qemu_input_map_linux_to_qcode_len)
qcode = qemu_input_map_linux_to_qcode[event.code];
if (event.value < 2) {
if (event.value < 2)
{
ev.type = INPUT_EVENT_KIND_KEY;
ev.u.key.down = (event.value == 1); // 2 if repeat
ev.u.key.key.type = KEY_VALUE_KIND_QCODE;
@ -281,7 +295,8 @@ void EvDev::ReaderThread(void *ptr)
}
}
if (hs->ptr.eh_entry) {
if (hs->ptr.eh_entry)
{
ev.type = INPUT_EVENT_KIND_BTN;
switch (event.code)
{
@ -309,7 +324,8 @@ void EvDev::ReaderThread(void *ptr)
case EV_SYN: //TODO useful?
{
OSDebugOut("EV_SYN: %d, val: %d\n", event.code, event.value);
switch(event.code) {
switch (event.code)
{
case SYN_REPORT:
if (hs->ptr.eh_sync) //TODO sync here?
hs->ptr.eh_sync(hs);
@ -339,4 +355,5 @@ void EvDev::ReaderThread(void *ptr)
dev->mReaderThreadIsRunning = false;
}
}} //namespace
} // namespace evdev
} // namespace usb_hid

View File

@ -22,14 +22,18 @@
#include <atomic>
#include "../usb-hid.h"
namespace usb_hid { namespace evdev {
namespace usb_hid
{
namespace evdev
{
static const char* APINAME = "evdev";
class EvDev : public UsbHID
{
public:
EvDev(int port, const char* dev_type): UsbHID(port, dev_type)
EvDev(int port, const char* dev_type)
: UsbHID(port, dev_type)
, mHandle(-1)
, mReaderThreadIsRunning(false)
{
@ -48,6 +52,7 @@ public:
}
static int Configure(int port, const char* dev_type, HIDType hid_type, void* data);
protected:
static void ReaderThread(void* ptr);
@ -83,4 +88,5 @@ bool GetEvdevName(const std::string& path, char (&name)[_Size])
return false;
}
}} //namespace
} // namespace evdev
} // namespace usb_hid

View File

@ -24,12 +24,16 @@
#include "../helpers.h"
#include "../deviceproxy.h"
namespace usb_hid {
namespace usb_hid
{
class UsbHIDError : public std::runtime_error
{
public:
UsbHIDError(const char* msg) : std::runtime_error(msg) {}
UsbHIDError(const char* msg)
: std::runtime_error(msg)
{
}
virtual ~UsbHIDError() throw() {}
};
@ -52,7 +56,10 @@ class UsbHIDProxy : public UsbHIDProxyBase
public:
UsbHIDProxy() {}
UsbHIDProxy(const std::string& name): UsbHIDProxyBase(name) {}
UsbHIDProxy(const std::string& name)
: UsbHIDProxyBase(name)
{
}
UsbHID* CreateObject(int port, const char* dev_type) const
{
try
@ -85,5 +92,5 @@ class RegisterUsbHID : public RegisterProxy<UsbHIDProxyBase>
static void Register();
};
}
} // namespace usb_hid
#endif

View File

@ -16,14 +16,20 @@
#include "usb-hid.h"
#include "hidproxy.h"
namespace usb_hid { namespace noop {
namespace usb_hid
{
namespace noop
{
static const char* APINAME = "noop";
class NOOP : public UsbHID
{
public:
NOOP(int port, const char* dev_type): UsbHID(port, dev_type) {}
NOOP(int port, const char* dev_type)
: UsbHID(port, dev_type)
{
}
~NOOP() {}
int Open() { return 0; }
int Close() { return 0; }
@ -42,4 +48,5 @@ public:
}
};
}}
} // namespace noop
} // namespace usb_hid

View File

@ -18,10 +18,26 @@
#include "qemu-usb/input-keymap.h"
#include "qemu-usb/input-keymap-win32-to-qcode.h"
namespace usb_hid { namespace raw {
namespace usb_hid
{
namespace raw
{
#define CHECK(exp) do{ if(!(exp)) goto Error; }while(0)
#define SAFE_FREE(p) do{ if(p) { free(p); (p) = NULL; } }while(0)
#define CHECK(exp) \
do \
{ \
if (!(exp)) \
goto Error; \
} while (0)
#define SAFE_FREE(p) \
do \
{ \
if (p) \
{ \
free(p); \
(p) = NULL; \
} \
} while (0)
// VKEY from https://docs.microsoft.com/en-us/windows/desktop/inputdev/virtual-key-codes
// and convert to HID usage id from "10 Keyboard/Keypad Page (0x07)"
@ -91,8 +107,7 @@ static void ParseRawInput(PRAWINPUT pRawInput, HIDState *hs)
if (HidP_GetUsageValue(
HidP_Input, pValueCaps[i].UsagePage, 0,
pValueCaps[i].Range.UsageMin, &value, pPreparsedData,
(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid
) != HIDP_STATUS_SUCCESS )
(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid) != HIDP_STATUS_SUCCESS)
{
continue; // if here then maybe something is up with HIDP_CAPS.NumberInputValueCaps
}
@ -128,7 +143,8 @@ static void ParseRawInputKB(RAWKEYBOARD &k, HIDState *hs)
OSDebugOut(TEXT("%ud kb: %hu %hu %hu %u\n"), nr, k.MakeCode, k.VKey, k.Flags, k.ExtraInformation);
nr++;
if (nr > 10) nr = 0;
if (nr > 10)
nr = 0;
if (KEYBOARD_OVERRUN_MAKE_CODE == k.MakeCode)
return;
@ -137,7 +153,8 @@ static void ParseRawInputKB(RAWKEYBOARD &k, HIDState *hs)
qcode = qemu_input_map_win32_to_qcode[k.VKey];
//TODO
if (k.Flags & RI_KEY_E0) {
if (k.Flags & RI_KEY_E0)
{
if (Q_KEY_CODE_SHIFT == qcode)
qcode = Q_KEY_CODE_SHIFT_R;
else if (Q_KEY_CODE_CTRL == qcode)
@ -157,7 +174,8 @@ static void ParseRawInputKB(RAWKEYBOARD &k, HIDState *hs)
static void SendPointerEvent(InputEvent& ev, HIDState* hs)
{
if (hs->ptr.eh_entry) {
if (hs->ptr.eh_entry)
{
hs->ptr.eh_entry(hs, &ev);
}
}
@ -284,4 +302,5 @@ int RawInput::Configure(int port, const char* dev_type, HIDType type, void *data
return res;
}
}} //namespace
} // namespace raw
} // namespace usb_hid

View File

@ -17,14 +17,18 @@
#include "../hidproxy.h"
#include "../usb-hid.h"
namespace usb_hid { namespace raw {
namespace usb_hid
{
namespace raw
{
static const char* APINAME = "rawinput";
class RawInput : public UsbHID, shared::rawinput::ParseRawInputCB
{
public:
RawInput(int port, const char* dev_type) : UsbHID(port, dev_type)
RawInput(int port, const char* dev_type)
: UsbHID(port, dev_type)
{
}
~RawInput()
@ -46,4 +50,5 @@ public:
static int Configure(int port, const char* dev_type, HIDType, void* data);
};
}} // namespace
} // namespace raw
} // namespace usb_hid

View File

@ -30,9 +30,11 @@
#define CONTAINER_OF(p, type, field) ((type*)((char*)p - ((ptrdiff_t) & ((type*)0)->field)))
namespace usb_hid {
namespace usb_hid
{
typedef struct UsbHIDState {
typedef struct UsbHIDState
{
USBDevice dev;
USBDesc desc;
USBDescDevice desc_dev;
@ -41,7 +43,8 @@ typedef struct UsbHIDState {
USBEndpoint* intr;
uint8_t port;
struct freeze {
struct freeze
{
HIDState hid;
int ep;
} f;
@ -74,7 +77,8 @@ const TCHAR* HIDMouseDevice::LongAPIName(const std::string& name)
return nullptr;
}
enum {
enum
{
STR_MANUFACTURER = 1,
STR_PRODUCT_MOUSE,
STR_PRODUCT_TABLET,
@ -433,24 +437,32 @@ static void usb_hid_handle_control(USBDevice *dev, USBPacket *p,
OSDebugOut(TEXT("usb-hid: req %04X val: %04X idx: %04X len: %d\n"), request, value, index, length);
ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
if (ret >= 0) {
if (ret >= 0)
{
return;
}
switch (request) {
switch (request)
{
/* hid specific requests */
case InterfaceRequest | USB_REQ_GET_DESCRIPTOR:
switch (value >> 8) {
switch (value >> 8)
{
case 0x22:
if (hs->kind == HID_MOUSE) {
if (hs->kind == HID_MOUSE)
{
memcpy(data, qemu_mouse_hid_report_descriptor,
sizeof(qemu_mouse_hid_report_descriptor));
p->actual_length = sizeof(qemu_mouse_hid_report_descriptor);
} else if (hs->kind == HID_TABLET) {
}
else if (hs->kind == HID_TABLET)
{
memcpy(data, qemu_tablet_hid_report_descriptor,
sizeof(qemu_tablet_hid_report_descriptor));
p->actual_length = sizeof(qemu_tablet_hid_report_descriptor);
} else if (hs->kind == HID_KEYBOARD) {
}
else if (hs->kind == HID_KEYBOARD)
{
memcpy(data, qemu_keyboard_hid_report_descriptor,
sizeof(qemu_keyboard_hid_report_descriptor));
p->actual_length = sizeof(qemu_keyboard_hid_report_descriptor);
@ -461,28 +473,36 @@ static void usb_hid_handle_control(USBDevice *dev, USBPacket *p,
}
break;
case GET_REPORT:
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET)
{
p->actual_length = hid_pointer_poll(hs, data, length);
} else if (hs->kind == HID_KEYBOARD) {
}
else if (hs->kind == HID_KEYBOARD)
{
p->actual_length = hid_keyboard_poll(hs, data, length);
}
break;
case SET_REPORT:
if (hs->kind == HID_KEYBOARD) {
if (hs->kind == HID_KEYBOARD)
{
p->actual_length = hid_keyboard_write(hs, data, length);
} else {
}
else
{
goto fail;
}
break;
case GET_PROTOCOL:
if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) {
if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE)
{
goto fail;
}
data[0] = hs->protocol;
p->actual_length = 1;
break;
case SET_PROTOCOL:
if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE) {
if (hs->kind != HID_KEYBOARD && hs->kind != HID_MOUSE)
{
goto fail;
}
hs->protocol = value;
@ -495,7 +515,8 @@ static void usb_hid_handle_control(USBDevice *dev, USBPacket *p,
hs->idle = (uint8_t)(value >> 8);
OSDebugOut(TEXT("IDLE %d\n"), hs->idle);
hid_set_next_idle(hs);
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET)
{
hid_pointer_activate(hs);
}
break;
@ -513,24 +534,33 @@ static void usb_hid_handle_data(USBDevice *dev, USBPacket *p)
std::vector<uint8_t> buf(p->iov.size);
size_t len = 0;
switch (p->pid) {
switch (p->pid)
{
case USB_TOKEN_IN:
if (p->ep->nr == 1) {
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
if (p->ep->nr == 1)
{
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET)
{
hid_pointer_activate(hs);
}
if (!hid_has_events(hs)) {
if (!hid_has_events(hs))
{
p->status = USB_RET_NAK;
return;
}
hid_set_next_idle(hs);
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET)
{
len = hid_pointer_poll(hs, buf.data(), p->iov.size);
} else if (hs->kind == HID_KEYBOARD) {
}
else if (hs->kind == HID_KEYBOARD)
{
len = hid_keyboard_poll(hs, buf.data(), p->iov.size);
}
usb_packet_copy(p, buf.data(), len);
} else {
}
else
{
goto fail;
}
break;
@ -566,7 +596,8 @@ void usb_hid_close(USBDevice *dev)
s->usbhid->Close();
}
USBDevice *HIDKbdDevice::CreateDevice(int port){
USBDevice* HIDKbdDevice::CreateDevice(int port)
{
UsbHIDState* s;
std::string varApi;
@ -637,11 +668,13 @@ int HIDKbdDevice::Freeze(int mode, USBDevice *dev, void *data)
switch (mode)
{
case FREEZE_LOAD:
if (!s) return -1;
if (!s)
return -1;
s->f = *freezed;
return sizeof(UsbHIDState::freeze);
case FREEZE_SAVE:
if (!s) return -1;
if (!s)
return -1;
*freezed = s->f;
return sizeof(UsbHIDState::freeze);
case FREEZE_SIZE:
@ -652,7 +685,8 @@ int HIDKbdDevice::Freeze(int mode, USBDevice *dev, void *data)
return -1;
}
USBDevice *HIDMouseDevice::CreateDevice(int port) {
USBDevice* HIDMouseDevice::CreateDevice(int port)
{
UsbHIDState* s;
std::string varApi;
@ -720,4 +754,4 @@ int HIDMouseDevice::Freeze(int mode, USBDevice *dev, void *data)
return HIDKbdDevice::Freeze(mode, dev, data);
}
} //namespace
} // namespace usb_hid

View File

@ -19,7 +19,8 @@
#include <list>
#include <string>
namespace usb_hid {
namespace usb_hid
{
enum HIDType
{
@ -30,7 +31,11 @@ enum HIDType
class UsbHID
{
public:
UsbHID(int port, const char* dev_type) : mPort(port), mDevType(dev_type) {}
UsbHID(int port, const char* dev_type)
: mPort(port)
, mDevType(dev_type)
{
}
virtual ~UsbHID() {}
virtual int Open() = 0;
virtual int Close() = 0;
@ -88,4 +93,4 @@ public:
static int Freeze(int mode, USBDevice* dev, void* data);
};
}
} // namespace usb_hid

View File

@ -16,14 +16,20 @@
#pragma once
#include "audiodeviceproxy.h"
namespace usb_mic { namespace audiodev_noop {
namespace usb_mic
{
namespace audiodev_noop
{
static const char* APINAME = "noop";
class NoopAudioDevice : public AudioDevice
{
public:
NoopAudioDevice(int port, const char* dev_type, int mic, AudioDir dir): AudioDevice(port, dev_type, mic, dir) {}
NoopAudioDevice(int port, const char* dev_type, int mic, AudioDir dir)
: AudioDevice(port, dev_type, mic, dir)
{
}
~NoopAudioDevice() {}
void Start() {}
void Stop() {}
@ -78,4 +84,5 @@ public:
}
};
}}
} // namespace audiodev_noop
} // namespace usb_mic

View File

@ -21,7 +21,10 @@
GtkWidget* new_combobox(const char* label, GtkWidget* vbox); // src/linux/config-gtk.cpp
namespace usb_mic { namespace audiodev_pulse {
namespace usb_mic
{
namespace audiodev_pulse
{
static void pa_context_state_cb(pa_context* c, void* userdata)
{
@ -30,7 +33,8 @@ static void pa_context_state_cb(pa_context *c, void *userdata)
state = pa_context_get_state(c);
OSDebugOut("pa_context_get_state() %d\n", state);
switch (state) {
switch (state)
{
// There are just here for reference
case PA_CONTEXT_UNCONNECTED:
*pa_ready = 3;
@ -54,7 +58,8 @@ static void pa_sourcelist_cb(pa_context *c, const pa_source_info *l, int eol, vo
{
AudioDeviceInfoList* devicelist = static_cast<AudioDeviceInfoList*>(userdata);
if (eol > 0) {
if (eol > 0)
{
return;
}
@ -69,7 +74,8 @@ static void pa_sinklist_cb(pa_context *c, const pa_sink_info *l, int eol, void *
{
AudioDeviceInfoList* devicelist = static_cast<AudioDeviceInfoList*>(userdata);
if (eol > 0) {
if (eol > 0)
{
return;
}
@ -99,7 +105,8 @@ static int pa_get_devicelist(AudioDeviceInfoList& list, AudioDir dir)
pa_context_set_state_callback(pa_ctx, pa_context_state_cb, &pa_ready);
OSDebugOut("pa_get_devicelist\n");
for (;;) {
for (;;)
{
if (pa_ready == 0)
{
@ -334,8 +341,7 @@ uint32_t PulseAudioDevice::GetBuffer(short *buff, uint32_t frames)
int ret = pa_context_connect(mPContext,
mServer,
PA_CONTEXT_NOFLAGS,
NULL
);
NULL);
//TODO reconnect stream as well?
@ -382,8 +388,7 @@ uint32_t PulseAudioDevice::SetBuffer(short *buff, uint32_t frames)
int ret = pa_context_connect(mPContext,
mServer,
PA_CONTEXT_NOFLAGS,
NULL
);
NULL);
//TODO reconnect stream as well?
@ -466,22 +471,26 @@ bool PulseAudioDevice::Compare(AudioDevice* compare)
void PulseAudioDevice::Uninit()
{
int ret;
if (mStream) {
if (mStream)
{
pa_threaded_mainloop_lock(mPMainLoop);
ret = pa_stream_disconnect(mStream);
pa_stream_unref(mStream);
mStream = nullptr;
pa_threaded_mainloop_unlock(mPMainLoop);
}
if (mPMainLoop) {
if (mPMainLoop)
{
pa_threaded_mainloop_stop(mPMainLoop);
}
if (mPContext) {
if (mPContext)
{
pa_context_disconnect(mPContext);
pa_context_unref(mPContext);
mPContext = nullptr;
}
if (mPMainLoop) {
if (mPMainLoop)
{
pa_threaded_mainloop_free(mPMainLoop);
mPMainLoop = nullptr;
}
@ -499,8 +508,7 @@ bool PulseAudioDevice::Init()
pa_context_set_state_callback(mPContext,
context_state_cb,
this
);
this);
// Lock the mainloop so that it does not run and crash before the context is ready
pa_threaded_mainloop_lock(mPMainLoop);
@ -509,8 +517,7 @@ bool PulseAudioDevice::Init()
ret = pa_context_connect(mPContext,
mServer,
PA_CONTEXT_NOFLAGS,
NULL
);
NULL);
OSDebugOut("pa_context_connect %s\n", pa_strerror(ret));
if (ret != PA_OK)
@ -519,16 +526,17 @@ bool PulseAudioDevice::Init()
// wait for pa_context_state_cb
for (;;)
{
if(mPAready == 1) break;
if(mPAready == 2 || mQuit) goto unlock_and_fail;
if (mPAready == 1)
break;
if (mPAready == 2 || mQuit)
goto unlock_and_fail;
pa_threaded_mainloop_wait(mPMainLoop);
}
mStream = pa_stream_new(mPContext,
"USBqemu-pulse",
&mSSpec,
NULL
);
NULL);
if (!mStream)
goto unlock_and_fail;
@ -550,29 +558,25 @@ bool PulseAudioDevice::Init()
{
pa_stream_set_read_callback(mStream,
stream_read_cb,
this
);
this);
ret = pa_stream_connect_record(mStream,
mDeviceName.c_str(),
&buffer_attr,
PA_STREAM_ADJUST_LATENCY
);
PA_STREAM_ADJUST_LATENCY);
OSDebugOut("pa_stream_connect_record %s\n", pa_strerror(ret));
}
else
{
pa_stream_set_write_callback(mStream,
stream_write_cb,
this
);
this);
buffer_attr.maxlength = pa_bytes_per_second(&mSSpec);
buffer_attr.prebuf = 0; // Don't stop on underrun but then
// stream also only starts manually with uncorking.
buffer_attr.tlength = pa_usec_to_bytes(mBuffering * 1000, &mSSpec);
pa_stream_flags_t flags = (pa_stream_flags_t)
(PA_STREAM_INTERPOLATE_TIMING |
pa_stream_flags_t flags = (pa_stream_flags_t)(PA_STREAM_INTERPOLATE_TIMING |
PA_STREAM_NOT_MONOTONIC |
PA_STREAM_AUTO_TIMING_UPDATE |
//PA_STREAM_VARIABLE_RATE |
@ -583,8 +587,7 @@ bool PulseAudioDevice::Init()
&buffer_attr,
flags,
nullptr,
nullptr
);
nullptr);
OSDebugOut("pa_stream_connect_playback %s\n", pa_strerror(ret));
}
@ -592,11 +595,14 @@ bool PulseAudioDevice::Init()
goto unlock_and_fail;
// Wait for the stream to be ready
for(;;) {
for (;;)
{
pa_stream_state_t stream_state = pa_stream_get_state(mStream);
assert(PA_STREAM_IS_GOOD(stream_state));
if (stream_state == PA_STREAM_READY) break;
if (stream_state == PA_STREAM_FAILED) goto unlock_and_fail;
if (stream_state == PA_STREAM_READY)
break;
if (stream_state == PA_STREAM_FAILED)
goto unlock_and_fail;
pa_threaded_mainloop_wait(mPMainLoop);
}
@ -711,7 +717,8 @@ void PulseAudioDevice::context_state_cb(pa_context *c, void *userdata)
state = pa_context_get_state(c);
OSDebugOut("pa_context_get_state %d\n", state);
switch (state) {
switch (state)
{
case PA_CONTEXT_CONNECTING:
case PA_CONTEXT_AUTHORIZING:
case PA_CONTEXT_SETTING_NAME:
@ -757,7 +764,8 @@ void PulseAudioDevice::stream_read_cb (pa_stream *p, size_t nbytes, void *userda
return;
auto dur = std::chrono::duration_cast<ms>(hrc::now() - padev->mLastGetBuffer).count();
if (padev->mPaused /*|| dur > 5000*/ || (!padata && nbytes /* hole */)) {
if (padev->mPaused /*|| dur > 5000*/ || (!padata && nbytes /* hole */))
{
ret = pa_stream_drop(p);
if (ret != PA_OK)
OSDebugOut("pa_stream_drop %d: %s\n", ret, pa_strerror(ret));
@ -799,7 +807,8 @@ void PulseAudioDevice::stream_read_cb (pa_stream *p, size_t nbytes, void *userda
input_frames_used += data.input_frames_used;
size_t samples = data.input_frames_used * padev->GetChannels();
if (!samples) break; //TODO happens?
if (!samples)
break; //TODO happens?
padev->mInBuffer.read<float>(samples);
}
@ -924,4 +933,5 @@ exit:
return;
}
}}
} // namespace audiodev_pulse
} // namespace usb_mic

View File

@ -25,7 +25,10 @@
#include <mutex>
#include <chrono>
namespace usb_mic { namespace audiodev_pulse {
namespace usb_mic
{
namespace audiodev_pulse
{
// macros for string concat
#undef APINAME_
@ -42,7 +45,8 @@ using sec = std::chrono::seconds;
class PulseAudioDevice : public AudioDevice
{
public:
PulseAudioDevice(int port, const char* dev_type, int device, AudioDir dir): AudioDevice(port, dev_type, device, dir)
PulseAudioDevice(int port, const char* dev_type, int device, AudioDir dir)
: AudioDevice(port, dev_type, device, dir)
, mBuffering(50)
, mPaused(true)
, mQuit(false)
@ -62,8 +66,7 @@ public:
N_AUDIO_SOURCE0,
N_AUDIO_SOURCE1,
N_AUDIO_SINK0,
N_AUDIO_SINK1
};
N_AUDIO_SINK1};
if (!LoadSetting(mDevType, mPort, APINAME, (device ? var_names[i + 1] : var_names[i]), mDeviceName) || mDeviceName.empty())
throw AudioDeviceError(APINAME_ ": failed to load device settings");
@ -89,7 +92,8 @@ public:
Uninit();
AudioDeinit();
mResampler = src_delete(mResampler);
if (file) fclose(file);
if (file)
fclose(file);
}
uint32_t GetBuffer(short* buff, uint32_t frames);
@ -161,4 +165,5 @@ protected:
hrc::time_point mLastOut;
FILE* file = nullptr;
};
}}
} // namespace audiodev_pulse
} // namespace usb_mic

View File

@ -24,10 +24,18 @@
#include "../Win32/Config.h"
#include "../Win32/resource.h"
#define SafeRelease(x) if(x){x->Release(); x = NULL;}
#define SafeRelease(x) \
if (x) \
{ \
x->Release(); \
x = NULL; \
}
#define ConvertMSTo100NanoSec(ms) (ms * 1000 * 10) //1000 microseconds, then 10 "100nanosecond" segments
namespace usb_mic { namespace audiodev_wasapi {
namespace usb_mic
{
namespace audiodev_wasapi
{
static FILE* file = nullptr;
@ -436,7 +444,8 @@ unsigned WINAPI MMAudioDevice::CaptureThread(LPVOID ptr)
pBegin += srcData.output_frames_gen * src->GetChannels();
size_t samples = srcData.input_frames_used * src->GetChannels();
if (!samples) break; //TODO happens?
if (!samples)
break; //TODO happens?
src->mInBuffer.read<float>(samples);
}
@ -565,7 +574,6 @@ unsigned WINAPI MMAudioDevice::RenderThread(LPVOID ptr)
read -= srcData.input_frames_used * src->GetChannels();
src->mInBuffer.read<short>(srcData.input_frames_used * src->GetChannels());
}
}
// TODO WASAPI seems to stop playing when buffer underrun, so skip this
@ -590,8 +598,10 @@ unsigned WINAPI MMAudioDevice::RenderThread(LPVOID ptr)
goto error;
}
if (FAILED(hr)) {
if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
if (FAILED(hr))
{
if (hr == AUDCLNT_E_DEVICE_INVALIDATED)
{
src->mDeviceLost = true;
OSDebugOut(TEXT("Audio device has been lost, attempting to reinitialize\n"));
}
@ -600,7 +610,6 @@ unsigned WINAPI MMAudioDevice::RenderThread(LPVOID ptr)
}
Sleep(src->mDeviceLost ? 1000 : 10);
}
quit:
@ -718,8 +727,10 @@ uint32_t MMAudioDevice::GetMMBuffer()
UINT32 captureSize = 0;
HRESULT hRes = mmCapture->GetNextPacketSize(&captureSize);
if (FAILED(hRes)) {
if (hRes == AUDCLNT_E_DEVICE_INVALIDATED) {
if (FAILED(hRes))
{
if (hRes == AUDCLNT_E_DEVICE_INVALIDATED)
{
mDeviceLost = true;
FreeData();
OSDebugOut(TEXT("Audio device has been lost, attempting to reinitialize\n"));
@ -907,11 +918,13 @@ static void RefreshOutputAudioList(HWND hW, LRESULT idx, WASAPISettings *setting
}
}
static BOOL CALLBACK WASAPIDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
static BOOL CALLBACK WASAPIDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int tmp = 0;
WASAPISettings* s;
switch (uMsg) {
switch (uMsg)
{
case WM_CREATE:
SetWindowLongPtr(hW, GWLP_USERDATA, (LONG)lParam);
break;
@ -981,7 +994,8 @@ static BOOL CALLBACK WASAPIDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lPa
break;
case BN_CLICKED:
{
switch (LOWORD(wParam)) {
switch (LOWORD(wParam))
{
case IDOK:
{
int p[3];
@ -1026,4 +1040,5 @@ static BOOL CALLBACK WASAPIDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lPa
return FALSE;
}
}} // namespace
} // namespace audiodev_wasapi
} // namespace usb_mic

View File

@ -22,14 +22,18 @@
#include <mmdeviceapi.h>
#include <audioclient.h>
namespace usb_mic { namespace audiodev_wasapi {
namespace usb_mic
{
namespace audiodev_wasapi
{
static const char* APINAME = "wasapi";
class MMAudioDevice : public AudioDevice
{
public:
MMAudioDevice(int port, const char* dev_type, int device, AudioDir dir): AudioDevice(port, dev_type, device, dir)
MMAudioDevice(int port, const char* dev_type, int device, AudioDir dir)
: AudioDevice(port, dev_type, device, dir)
, mmCapture(NULL)
, mmRender(NULL)
, mmClient(NULL)
@ -153,4 +157,5 @@ private:
LONGLONG mLastTimeNS = 0;
};
}} // namespace
} // namespace audiodev_wasapi
} // namespace usb_mic

View File

@ -37,7 +37,8 @@
#define N_BUFFER_LEN_SRC TEXT("buffer_len_src")
#define N_BUFFER_LEN_SINK TEXT("buffer_len_sink")
enum MicMode {
enum MicMode
{
MIC_MODE_NONE,
MIC_MODE_SINGLE,
MIC_MODE_SEPARATE,
@ -46,7 +47,8 @@ enum MicMode {
MIC_MODE_SHARED
};
enum AudioDir {
enum AudioDir
{
AUDIODIR_SOURCE = 0,
AUDIODIR_SINK
};
@ -75,18 +77,20 @@ struct AudioDeviceInfoW
class AudioDevice
{
public:
AudioDevice(int port, const char* dev_type, int device, AudioDir dir): mPort(port)
AudioDevice(int port, const char* dev_type, int device, AudioDir dir)
: mPort(port)
, mDevType(dev_type)
, mDevice(device)
, mAudioDir(dir)
{
}
protected:
int mPort;
const char* mDevType;
int mDevice;
AudioDir mAudioDir;
public:
virtual ~AudioDevice() {}
//get buffer, converted to 16bit int format

View File

@ -27,12 +27,16 @@
#include "../osdebugout.h"
#include "audiodev.h"
namespace usb_mic {
namespace usb_mic
{
class AudioDeviceError : public std::runtime_error
{
public:
AudioDeviceError(const char* msg) : std::runtime_error(msg) {}
AudioDeviceError(const char* msg)
: std::runtime_error(msg)
{
}
virtual ~AudioDeviceError() throw() {}
};
@ -57,7 +61,10 @@ class AudioDeviceProxy : public AudioDeviceProxyBase
public:
AudioDeviceProxy() {}
AudioDeviceProxy(const std::string& name): AudioDeviceProxyBase(name) {} //Why can't it automagically, ugh
AudioDeviceProxy(const std::string& name)
: AudioDeviceProxyBase(name)
{
} //Why can't it automagically, ugh
~AudioDeviceProxy() { OSDebugOut(TEXT("%p\n"), this); }
AudioDevice* CreateObject(int port, const char* dev_type, int mic, AudioDir dir) const
@ -100,5 +107,5 @@ class RegisterAudioDevice : public RegisterProxy<AudioDeviceProxyBase>
public:
static void Register();
};
}
} // namespace usb_mic
#endif

View File

@ -40,34 +40,40 @@
#define USBAUDIO_SAMPLE_RATE 48000
#define USBAUDIO_PACKET_INTERVAL 1
namespace usb_mic {
namespace usb_mic
{
static FILE* file = NULL;
typedef struct HeadsetState {
typedef struct HeadsetState
{
USBDevice dev;
AudioDevice* audsrc;
AudioDevice* audsink;
AudioDeviceProxyBase* audsrcproxy;
struct freeze {
struct freeze
{
int intf;
MicMode mode;
/* state */
struct {
struct
{
bool mute;
uint8_t vol[2];
uint32_t srate;
} out;
struct {
struct
{
bool mute;
uint8_t vol;
uint32_t srate;
} in;
struct {
struct
{
bool mute;
uint8_t vol[2];
} mixer; //TODO
@ -170,8 +176,7 @@ static const uint8_t headset_config_descriptor[] = {
WBVAL(AUDIO_TERMINAL_USB_STREAMING), /* wTerminalType */
0x00, /* bAssocTerminal */
0x02, /* bNrChannels */
WBVAL((AUDIO_CHANNEL_L
| AUDIO_CHANNEL_R)), /* wChannelConfig */
WBVAL((AUDIO_CHANNEL_L | AUDIO_CHANNEL_R)), /* wChannelConfig */
0x00, /* iChannelNames */
0x00, /* iTerminal */
@ -183,8 +188,7 @@ static const uint8_t headset_config_descriptor[] = {
0x0c, /* baSourceID( 0) */
0x06, /* baSourceID( 1) */
0x02, /* bNrChannels */
WBVAL((AUDIO_CHANNEL_L
| AUDIO_CHANNEL_R)), /* wChannelConfig */
WBVAL((AUDIO_CHANNEL_L | AUDIO_CHANNEL_R)), /* wChannelConfig */
0, /* iChannelNames */
0x00, /* bmControls */
0, /* iMixer */
@ -305,8 +309,7 @@ static const uint8_t headset_config_descriptor[] = {
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength : 9 */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_OUT(1), /* bEndpointAddress */
USB_ENDPOINT_TYPE_ISOCHRONOUS
| USB_ENDPOINT_SYNC_ADAPTIVE, /* bmAttributes */
USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ADAPTIVE, /* bmAttributes */
WBVAL(0x00c0), /* wMaxPacketSize */
0x01, /* bInterval */
0x00, /* bRefresh */
@ -358,8 +361,7 @@ static const uint8_t headset_config_descriptor[] = {
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength : 9 */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_OUT(1), /* bEndpointAddress */
USB_ENDPOINT_TYPE_ISOCHRONOUS
| USB_ENDPOINT_SYNC_ADAPTIVE, /* bmAttributes */
USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ADAPTIVE, /* bmAttributes */
WBVAL(0x0060), /* wMaxPacketSize */
0x01, /* bInterval */
0x00, /* bRefresh */
@ -422,8 +424,7 @@ static const uint8_t headset_config_descriptor[] = {
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength : 9 */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_IN(4), /* bEndpointAddress */
USB_ENDPOINT_TYPE_ISOCHRONOUS
| USB_ENDPOINT_SYNC_ADAPTIVE, /* bmAttributes */
USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ADAPTIVE, /* bmAttributes */
WBVAL(0x0060), /* wMaxPacketSize */
0x01, /* bInterval */
0x00, /* bRefresh */
@ -445,8 +446,7 @@ static const USBDescStrings desc_strings = {
"",
"Logitech", // Atleast SOCOM II checks this (liblgaud?)
"Logitech USB Headset",
"00000000"
};
"00000000"};
static void headset_handle_reset(USBDevice* dev)
{
@ -475,7 +475,8 @@ static int usb_audio_get_control(HeadsetState *s, uint8_t attrib,
int ret = USB_RET_STALL;
OSDebugOut(TEXT("cs: %02x attr: %02x cn: %d, unit: %04x\n"), cs, attrib, cn, idif);
switch (aid) {
switch (aid)
{
case ATTRIB_ID(AUDIO_MUTE_CONTROL, AUDIO_REQUEST_GET_CUR, 0x0600):
case ATTRIB_ID(AUDIO_MUTE_CONTROL, AUDIO_REQUEST_GET_CUR, 0x0200):
data[0] = s->f.in.mute;
@ -590,7 +591,8 @@ static int usb_audio_set_control(HeadsetState *s, uint8_t attrib,
int ret = USB_RET_STALL;
bool set_vol = false;
switch (aid) {
switch (aid)
{
case ATTRIB_ID(AUDIO_MUTE_CONTROL, AUDIO_REQUEST_SET_CUR, 0x0600):
case ATTRIB_ID(AUDIO_MUTE_CONTROL, AUDIO_REQUEST_SET_CUR, 0x0200):
s->f.in.mute = data[0] & 1;
@ -605,11 +607,13 @@ static int usb_audio_set_control(HeadsetState *s, uint8_t attrib,
//qemu usb audiocard formula
vol -= 0x8000;
vol = (vol * 255 + 0x4400) / 0x8800;
if (vol > 255) {
if (vol > 255)
{
vol = 255;
}
if (s->f.in.vol != vol) {
if (s->f.in.vol != vol)
{
s->f.in.vol = (uint8_t)vol;
set_vol = true;
}
@ -624,16 +628,19 @@ static int usb_audio_set_control(HeadsetState *s, uint8_t attrib,
case ATTRIB_ID(AUDIO_VOLUME_CONTROL, AUDIO_REQUEST_SET_CUR, 0x0100):
vol = data[0] + (data[1] << 8);
OSDebugOut(TEXT("=> headphones set cn %d volume %04x\n"), cn, vol);
if (cn < 2) {
if (cn < 2)
{
//qemu usb audiocard formula
vol -= 0x8000;
vol = (vol * 255 + 0x4400) / 0x8800;
if (vol > 255) {
if (vol > 255)
{
vol = 255;
}
if (s->f.out.vol[cn] != vol) {
if (s->f.out.vol[cn] != vol)
{
s->f.out.vol[cn] = (uint8_t)vol;
set_vol = true;
}
@ -642,7 +649,8 @@ static int usb_audio_set_control(HeadsetState *s, uint8_t attrib,
break;
}
if (set_vol) {
if (set_vol)
{
//if (s->f.debug) {
OSDebugOut(TEXT("headset: mute %d, vol %3d; mute %d vol %d %d\n"),
s->f.in.mute, s->f.in.vol,
@ -667,7 +675,8 @@ static int usb_audio_ep_control(HeadsetState *s, uint8_t attrib,
fprintf(stderr, "%02X ", data[i]);
fprintf(stderr, "\n");*/
switch (aid) {
switch (aid)
{
case ATTRIB_ID(AUDIO_SAMPLING_FREQ_CONTROL, AUDIO_REQUEST_SET_CUR, 0x84):
s->f.in.srate = data[0] | (data[1] << 8) | (data[2] << 16);
OSDebugOut(TEXT("=> mic set cn %d sampling to %d\n"), cn, s->f.in.srate);
@ -711,11 +720,13 @@ static void headset_handle_control(USBDevice *dev, USBPacket *p, int request, in
OSDebugOut(TEXT("headset: req %04X val: %04X idx: %04X len: %d\n"), request, value, index, length);
ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
if (ret >= 0) {
if (ret >= 0)
{
return;
}
switch(request) {
switch (request)
{
/*
* Audio device specific request
*/
@ -725,7 +736,8 @@ static void headset_handle_control(USBDevice *dev, USBPacket *p, int request, in
case ClassInterfaceRequest | AUDIO_REQUEST_GET_RES:
ret = usb_audio_get_control(s, request & 0xff, value, index,
length, data);
if (ret < 0) {
if (ret < 0)
{
//if (s->debug) {
fprintf(stderr, "headset: fail: get control\n");
//}
@ -740,7 +752,8 @@ static void headset_handle_control(USBDevice *dev, USBPacket *p, int request, in
case ClassInterfaceOutRequest | AUDIO_REQUEST_SET_RES:
ret = usb_audio_set_control(s, request & 0xff, value, index,
length, data);
if (ret < 0) {
if (ret < 0)
{
//if (s->debug) {
fprintf(stderr, "headset: fail: set control\n data:");
//}
@ -758,7 +771,8 @@ static void headset_handle_control(USBDevice *dev, USBPacket *p, int request, in
case ClassEndpointOutRequest | AUDIO_REQUEST_SET_RES:
ret = usb_audio_ep_control(s, request & 0xff, value, index,
length, data);
if (ret < 0) goto fail;
if (ret < 0)
goto fail;
break;
default:
fail:
@ -780,11 +794,13 @@ static void headset_handle_data(USBDevice *dev, USBPacket *p)
int ret = USB_RET_STALL;
uint8_t devep = p->ep->nr;
switch(p->pid) {
switch (p->pid)
{
case USB_TOKEN_IN:
//fprintf(stderr, "token in ep: %d len: %zd\n", devep, p->iov.size);
OSDebugOut(TEXT("token in ep: %d len: %zd\n"), devep, p->iov.size);
if (devep == 4 && s->dev.altsetting[2] && s->audsrc) {
if (devep == 4 && s->dev.altsetting[2] && s->audsrc)
{
uint32_t outChns = 1; //s->dev.altsetting[2] == 1 ? 2 : 1;
uint32_t inChns = s->audsrc->GetChannels();
@ -847,7 +863,8 @@ static void headset_handle_data(USBDevice *dev, USBPacket *p)
if (!s->audsink)
return;
if (devep == 1 && s->dev.altsetting[1]) {
if (devep == 1 && s->dev.altsetting[1])
{
uint32_t inChns = s->dev.altsetting[1] == 1 ? 2 : 1;
uint32_t outChns = s->audsink->GetChannels();
size_t len = p->iov.size;
@ -914,7 +931,8 @@ static void headset_handle_destroy(USBDevice *dev)
fclose(file);
file = NULL;
if (!s) return;
if (!s)
return;
if (s->audsrc)
{
s->audsrc->Stop();
@ -1047,7 +1065,8 @@ int HeadsetDevice::Freeze(int mode, USBDevice *dev, void *data)
switch (mode)
{
case FREEZE_LOAD:
if (!s) return -1;
if (!s)
return -1;
s->f = *(HeadsetState::freeze*)data;
if (s->audsrc)
s->audsrc->SetResampling(s->f.in.srate);
@ -1055,7 +1074,8 @@ int HeadsetDevice::Freeze(int mode, USBDevice *dev, void *data)
s->audsink->SetResampling(s->f.out.srate);
return sizeof(HeadsetState::freeze);
case FREEZE_SAVE:
if (!s) return -1;
if (!s)
return -1;
*(HeadsetState::freeze*)data = s->f;
return sizeof(HeadsetState::freeze);
case FREEZE_SIZE:
@ -1066,4 +1086,4 @@ int HeadsetDevice::Freeze(int mode, USBDevice *dev, void *data)
return -1;
}
}
} // namespace usb_mic

View File

@ -16,7 +16,8 @@
#include "../deviceproxy.h"
#include "audiodeviceproxy.h"
namespace usb_mic {
namespace usb_mic
{
class HeadsetDevice
{
@ -38,4 +39,4 @@ public:
static int Freeze(int mode, USBDevice* dev, void* data);
};
}
} // namespace usb_mic

View File

@ -17,7 +17,8 @@
#include "audio.h"
#include "../qemu-usb/desc.h"
namespace usb_mic {
namespace usb_mic
{
static const uint8_t logitech_mic_dev_descriptor[] = {
/* bLength */ 0x12, //(18)
@ -77,8 +78,7 @@ static const uint8_t logitech_mic_config_descriptor[] = {
WBVAL(AUDIO_TERMINAL_MICROPHONE), /* wTerminalType */
0x02, /* bAssocTerminal */
0x02, /* bNrChannels */
WBVAL(AUDIO_CHANNEL_L
| AUDIO_CHANNEL_R), /* wChannelConfig */
WBVAL(AUDIO_CHANNEL_L | AUDIO_CHANNEL_R), /* wChannelConfig */
0x00, /* iChannelNames */
0x00, /* iTerminal */
@ -153,8 +153,7 @@ static const uint8_t logitech_mic_config_descriptor[] = {
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_IN(1), /* bEndpointAddress */
USB_ENDPOINT_TYPE_ISOCHRONOUS
| USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */
USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */
WBVAL(0x0064), /* wMaxPacketSize */
0x01, /* bInterval */
0x00, /* bRefresh */
@ -206,8 +205,7 @@ static const uint8_t logitech_mic_config_descriptor[] = {
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_IN(1), /* bEndpointAddress */
USB_ENDPOINT_TYPE_ISOCHRONOUS
| USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */
USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */
WBVAL(0x00c8), /* wMaxPacketSize */
0x01, /* bInterval */
0x00, /* bRefresh */
@ -232,7 +230,8 @@ static const USBDescStrings lt_desc_strings = {
};
//Minified state
typedef struct SINGSTARMICMINIState {
typedef struct SINGSTARMICMINIState
{
USBDevice dev;
USBDesc desc;
@ -270,4 +269,4 @@ fail:
return nullptr;
}
}
} // namespace usb_mic

View File

@ -42,7 +42,8 @@ static FILE *file = NULL;
#define USBAUDIO_SAMPLE_RATE 48000
#define USBAUDIO_PACKET_INTERVAL 1
namespace usb_mic {
namespace usb_mic
{
/*
* A USB audio device supports an arbitrary number of alternate
@ -52,12 +53,14 @@ namespace usb_mic {
* block diagrams. Alternative setting 0 is always the null block diagram,
* which is used by a disabled device.
*/
enum usb_audio_altset : int8_t {
enum usb_audio_altset : int8_t
{
ALTSET_OFF = 0x00, /* No endpoint */
ALTSET_ON = 0x01, /* Single endpoint */
};
typedef struct SINGSTARMICState {
typedef struct SINGSTARMICState
{
USBDevice dev;
USBDesc desc;
@ -66,7 +69,8 @@ typedef struct SINGSTARMICState {
AudioDevice* audsrc[2];
AudioDeviceProxyBase* audsrcproxy;
struct freeze {
struct freeze
{
int port;
int intf;
MicMode mode;
@ -149,8 +153,7 @@ static const uint8_t singstar_mic_config_descriptor[] = {
WBVAL(AUDIO_TERMINAL_MICROPHONE), /* wTerminalType */
0x02, /* bAssocTerminal */
0x02, /* bNrChannels */
WBVAL(AUDIO_CHANNEL_L
|AUDIO_CHANNEL_R), /* wChannelConfig */
WBVAL(AUDIO_CHANNEL_L | AUDIO_CHANNEL_R), /* wChannelConfig */
0x00, /* iChannelNames */
0x00, /* iTerminal */
@ -225,8 +228,7 @@ static const uint8_t singstar_mic_config_descriptor[] = {
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_IN(1), /* bEndpointAddress */
USB_ENDPOINT_TYPE_ISOCHRONOUS
| USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */
USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */
WBVAL(0x0064), /* wMaxPacketSize */
0x01, /* bInterval */
0x00, /* bRefresh */
@ -278,8 +280,7 @@ static const uint8_t singstar_mic_config_descriptor[] = {
AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_IN(1), /* bEndpointAddress */
USB_ENDPOINT_TYPE_ISOCHRONOUS
| USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */
USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */
WBVAL(0x00c8), /* wMaxPacketSize */
0x01, /* bInterval */
0x00, /* bRefresh */
@ -321,13 +322,15 @@ static int usb_audio_get_control(SINGSTARMICState *s, uint8_t attrib,
uint32_t aid = ATTRIB_ID(cs, attrib, idif);
int ret = USB_RET_STALL;
switch (aid) {
switch (aid)
{
case ATTRIB_ID(AUDIO_MUTE_CONTROL, AUDIO_REQUEST_GET_CUR, 0x0300):
data[0] = s->f.mute;
ret = 1;
break;
case ATTRIB_ID(AUDIO_VOLUME_CONTROL, AUDIO_REQUEST_GET_CUR, 0x0300):
if (cn < 2) {
if (cn < 2)
{
//uint16_t vol = (s->f.vol[cn] * 0x8800 + 127) / 255 + 0x8000;
uint16_t vol = (s->f.vol[cn] * 0x8800 + 127) / 255 + 0x8000;
data[0] = (uint8_t)(vol & 0xFF);
@ -336,7 +339,8 @@ static int usb_audio_get_control(SINGSTARMICState *s, uint8_t attrib,
}
break;
case ATTRIB_ID(AUDIO_VOLUME_CONTROL, AUDIO_REQUEST_GET_MIN, 0x0300):
if (cn < 2) {
if (cn < 2)
{
data[0] = 0x01;
data[1] = 0x80;
//data[0] = 0x00;
@ -345,7 +349,8 @@ static int usb_audio_get_control(SINGSTARMICState *s, uint8_t attrib,
}
break;
case ATTRIB_ID(AUDIO_VOLUME_CONTROL, AUDIO_REQUEST_GET_MAX, 0x0300):
if (cn < 2) {
if (cn < 2)
{
data[0] = 0x00;
data[1] = 0x08;
//data[0] = 0x00;
@ -354,7 +359,8 @@ static int usb_audio_get_control(SINGSTARMICState *s, uint8_t attrib,
}
break;
case ATTRIB_ID(AUDIO_VOLUME_CONTROL, AUDIO_REQUEST_GET_RES, 0x0300):
if (cn < 2) {
if (cn < 2)
{
data[0] = 0x88;
data[1] = 0x00;
//data[0] = 0x00;
@ -377,24 +383,28 @@ static int usb_audio_set_control(SINGSTARMICState *s, uint8_t attrib,
int ret = USB_RET_STALL;
bool set_vol = false;
switch (aid) {
switch (aid)
{
case ATTRIB_ID(AUDIO_MUTE_CONTROL, AUDIO_REQUEST_SET_CUR, 0x0300):
s->f.mute = data[0] & 1;
set_vol = true;
ret = 0;
break;
case ATTRIB_ID(AUDIO_VOLUME_CONTROL, AUDIO_REQUEST_SET_CUR, 0x0300):
if (cn < 2) {
if (cn < 2)
{
uint16_t vol = data[0] + (data[1] << 8);
//qemu usb audiocard formula, singstar has a bit different range
vol -= 0x8000;
vol = (vol * 255 + 0x4400) / 0x8800;
if (vol > 255) {
if (vol > 255)
{
vol = 255;
}
if (s->f.vol[cn] != vol) {
if (s->f.vol[cn] != vol)
{
s->f.vol[cn] = (uint8_t)vol;
set_vol = true;
}
@ -403,7 +413,8 @@ static int usb_audio_set_control(SINGSTARMICState *s, uint8_t attrib,
break;
}
if (set_vol) {
if (set_vol)
{
//if (s->debug) {
fprintf(stderr, "singstar: mute %d, lvol %3d, rvol %3d\n",
s->f.mute, s->f.vol[0], s->f.vol[1]);
@ -431,9 +442,11 @@ static int usb_audio_ep_control(SINGSTARMICState *s, uint8_t attrib,
fprintf(stderr, "%02X ", data[i]);
fprintf(stderr, "\n");*/
switch (aid) {
switch (aid)
{
case ATTRIB_ID(AUDIO_SAMPLING_FREQ_CONTROL, AUDIO_REQUEST_SET_CUR, 0x81):
if( cn == 0xFF) {
if (cn == 0xFF)
{
s->f.srate[0] = data[0] | (data[1] << 8) | (data[2] << 16);
s->f.srate[1] = s->f.srate[0];
@ -444,7 +457,9 @@ static int usb_audio_ep_control(SINGSTARMICState *s, uint8_t attrib,
s->audsrc[1]->SetResampling(s->f.srate[1]);
OSDebugOut(TEXT("singstar: set sampling to %d\n"), s->f.srate[0]);
} else if( cn < 2) {
}
else if (cn < 2)
{
s->f.srate[cn] = data[0] | (data[1] << 8) | (data[2] << 16);
OSDebugOut(TEXT("singstar: set cn %d sampling to %d\n"), cn, s->f.srate[cn]);
@ -472,7 +487,8 @@ static void singstar_mic_set_interface(USBDevice *dev, int intf,
OSDebugOut(TEXT("singstar: intf:%d alt:%d -> %d\n"), intf, alt_old, alt_new);
#if defined(_DEBUG)
/* close previous debug audio output file */
if (file && intf > 0 && alt_old != alt_new) {
if (file && intf > 0 && alt_old != alt_new)
{
fclose(file);
file = nullptr;
}
@ -488,11 +504,13 @@ static void singstar_mic_handle_control(USBDevice *dev, USBPacket *p, int reques
OSDebugOut(TEXT("singstar: req %04X val: %04X idx: %04X len: %d\n"), request, value, index, length);
ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
if (ret >= 0) {
if (ret >= 0)
{
return;
}
switch(request) {
switch (request)
{
/*
* Audio device specific request
*/
@ -502,7 +520,8 @@ static void singstar_mic_handle_control(USBDevice *dev, USBPacket *p, int reques
case ClassInterfaceRequest | AUDIO_REQUEST_GET_RES:
ret = usb_audio_get_control(s, request & 0xff, value, index,
length, data);
if (ret < 0) {
if (ret < 0)
{
//if (s->debug) {
fprintf(stderr, "singstar: fail: get control\n");
//}
@ -517,7 +536,8 @@ static void singstar_mic_handle_control(USBDevice *dev, USBPacket *p, int reques
case ClassInterfaceOutRequest | AUDIO_REQUEST_SET_RES:
ret = usb_audio_set_control(s, request & 0xff, value, index,
length, data);
if (ret < 0) {
if (ret < 0)
{
//if (s->debug) {
fprintf(stderr, "singstar: fail: set control\n data:");
//}
@ -535,7 +555,8 @@ static void singstar_mic_handle_control(USBDevice *dev, USBPacket *p, int reques
case ClassEndpointOutRequest | AUDIO_REQUEST_SET_RES:
ret = usb_audio_ep_control(s, request & 0xff, value, index,
length, data);
if (ret < 0) goto fail;
if (ret < 0)
goto fail;
break;
default:
fail:
@ -557,11 +578,13 @@ static void singstar_mic_handle_data(USBDevice *dev, USBPacket *p)
int ret = 0;
uint8_t devep = p->ep->nr;
switch(p->pid) {
switch (p->pid)
{
case USB_TOKEN_IN:
//fprintf(stderr, "token in ep: %d len: %zd\n", devep, p->iov.size);
//OSDebugOut(TEXT("token in ep: %d len: %zd\n"), devep, p->iov.size);
if (devep == 1) {
if (devep == 1)
{
//TODO
int outChns = s->f.intf == 1 ? 1 : 2;
@ -605,7 +628,8 @@ static void singstar_mic_handle_data(USBDevice *dev, USBPacket *p)
//TODO well, it is 16bit interleaved, right?
//Merge with MIC_MODE_SHARED case?
switch(s->f.mode) {
switch (s->f.mode)
{
case MIC_MODE_SINGLE:
{
int k = s->audsrc[0] ? 0 : 1;
@ -709,7 +733,8 @@ static void singstar_mic_handle_destroy(USBDevice *dev)
fclose(file);
file = NULL;
if (!s) return;
if (!s)
return;
for (int i = 0; i < 2; i++)
{
if (s->audsrc[i])
@ -730,7 +755,8 @@ static int singstar_mic_handle_open(USBDevice *dev)
if (s)
{
for (int i = 0; i < 2; i++)
if (s->audsrc[i]) s->audsrc[i]->Start();
if (s->audsrc[i])
s->audsrc[i]->Start();
}
return 0;
}
@ -741,7 +767,8 @@ static void singstar_mic_handle_close(USBDevice *dev)
if (s)
{
for (int i = 0; i < 2; i++)
if (s->audsrc[i]) s->audsrc[i]->Stop();
if (s->audsrc[i])
s->audsrc[i]->Stop();
}
}
@ -842,7 +869,8 @@ int SingstarDevice::Freeze(int mode, USBDevice *dev, void *data)
switch (mode)
{
case FREEZE_LOAD:
if (!s) return -1;
if (!s)
return -1;
s->f = *(SINGSTARMICState::freeze*)data;
if (s->audsrc[0])
s->audsrc[0]->SetResampling(s->f.srate[0]);
@ -850,7 +878,8 @@ int SingstarDevice::Freeze(int mode, USBDevice *dev, void *data)
s->audsrc[1]->SetResampling(s->f.srate[1]);
return sizeof(SINGSTARMICState::freeze);
case FREEZE_SAVE:
if (!s) return -1;
if (!s)
return -1;
*(SINGSTARMICState::freeze*)data = s->f;
return sizeof(SINGSTARMICState::freeze);
case FREEZE_SIZE:
@ -861,4 +890,4 @@ int SingstarDevice::Freeze(int mode, USBDevice *dev, void *data)
return -1;
}
}
} // namespace usb_mic

View File

@ -20,7 +20,8 @@
struct USBDevice;
namespace usb_mic {
namespace usb_mic
{
class SingstarDevice
{
public:
@ -65,5 +66,5 @@ public:
}
};
}
} // namespace usb_mic
#endif

View File

@ -18,7 +18,8 @@
#include "../configuration.h"
#include "../gtk.h"
namespace usb_msd {
namespace usb_msd
{
static void entryChanged(GtkWidget* widget, gpointer data)
{
@ -118,4 +119,4 @@ int MsdDevice::Configure(int port, const std::string& api, void *data)
return RESULT_CANCELED;
}
} //namespace
} // namespace usb_msd

View File

@ -17,14 +17,17 @@
#include "../Win32/Config.h"
#include "../Win32/resource.h"
namespace usb_msd {
namespace usb_msd
{
static OPENFILENAMEW ofn;
BOOL CALLBACK MsdDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
BOOL CALLBACK MsdDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int port;
static wchar_t buff[4096] = {0};
switch (uMsg) {
switch (uMsg)
{
case WM_INITDIALOG:
{
memset(buff, 0, sizeof(buff));
@ -42,8 +45,10 @@ BOOL CALLBACK MsdDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
break;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED) {
switch (LOWORD(wParam)) {
if (HIWORD(wParam) == BN_CLICKED)
{
switch (LOWORD(wParam))
{
case IDC_BUTTON1:
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
@ -58,7 +63,8 @@ BOOL CALLBACK MsdDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
if (GetOpenFileName(&ofn)) {
if (GetOpenFileName(&ofn))
{
SetWindowText(GetDlgItem(hW, IDC_EDIT1), ofn.lpstrFile);
}
break;
@ -91,4 +97,4 @@ int MsdDevice::Configure(int port, const std::string& api, void *data)
(DLGPROC)MsdDlgProc, port);
}
}
} // namespace usb_msd

View File

@ -17,9 +17,11 @@
#define le32_to_cpu(x) (x)
#define cpu_to_le32(x) (x)
namespace usb_msd {
namespace usb_msd
{
struct usb_msd_cbw {
struct usb_msd_cbw
{
uint32_t sig;
uint32_t tag;
uint32_t data_len;
@ -29,7 +31,8 @@ struct usb_msd_cbw {
uint8_t cmd[16];
};
struct usb_msd_csw {
struct usb_msd_csw
{
uint32_t sig;
uint32_t tag;
uint32_t residue;
@ -44,23 +47,27 @@ struct usb_msd_csw {
#define MassStorageReset 0xff
#define GetMaxLun 0xfe
enum USBMSDMode : int8_t {
enum USBMSDMode : int8_t
{
USB_MSDM_CBW, /* Command Block. */
USB_MSDM_DATAOUT, /* Tranfer data to device. */
USB_MSDM_DATAIN, /* Transfer data from device. */
USB_MSDM_CSW /* Command Status. */
};
typedef struct ReqState {
typedef struct ReqState
{
uint32_t tag;
//
bool valid;
} ReqState;
typedef struct MSDState {
typedef struct MSDState
{
USBDevice dev;
struct freeze {
struct freeze
{
struct usb_msd_csw csw;
enum USBMSDMode mode;
uint32_t data_len;
@ -155,7 +162,8 @@ static const uint8_t qemu_msd_config_descriptor[] = {
0x00 /* u8 ep_bInterval; */
};
enum {
enum
{
STR_MANUFACTURER = 1,
STR_PRODUCT,
STR_SERIALNUMBER,
@ -356,7 +364,8 @@ static const USBDescStrings desc_strings = {
#define COMMAND_FAILED 0x01
#define PHASE_ERROR 0x02
typedef struct SCSISense {
typedef struct SCSISense
{
uint8_t key;
uint8_t asc;
uint8_t ascq;
@ -370,42 +379,33 @@ typedef struct SCSISense {
/* No sense data available */
const struct SCSISense sense_code_NO_SENSE = {
NO_SENSE , 0x00 , 0x00
};
NO_SENSE, 0x00, 0x00};
/* LUN not ready, Manual intervention required */
const struct SCSISense sense_code_LUN_NOT_READY = {
NOT_READY, 0x04, 0x03
};
NOT_READY, 0x04, 0x03};
/* LUN not ready, Medium not present */
const struct SCSISense sense_code_NO_MEDIUM = {
NOT_READY, 0x3a, 0x00
};
NOT_READY, 0x3a, 0x00};
const struct SCSISense sense_code_UNKNOWN_ERROR = {
NOT_READY , 0xFF , 0xFF
};
NOT_READY, 0xFF, 0xFF};
const struct SCSISense sense_code_NO_SEEK_COMPLETE = {
MEDIUM_ERROR, 0x02, 0x00
};
MEDIUM_ERROR, 0x02, 0x00};
const struct SCSISense sense_code_WRITE_FAULT = {
MEDIUM_ERROR, 0x03, 0x00
};
MEDIUM_ERROR, 0x03, 0x00};
const struct SCSISense sense_code_UNRECOVERED_READ_ERROR = {
MEDIUM_ERROR, 0x11, 0x00
};
MEDIUM_ERROR, 0x11, 0x00};
const struct SCSISense sense_code_INVALID_OPCODE = {
ILLEGAL_REQUEST, 0x20, 0x00
};
ILLEGAL_REQUEST, 0x20, 0x00};
const struct SCSISense sense_code_OUT_OF_RANGE = {
ILLEGAL_REQUEST, 0x21, 0x00
};
ILLEGAL_REQUEST, 0x21, 0x00};
/* Illegal request, Invalid Transfer Tag */
//const struct SCSISense sense_code_INVALID_TAG = {
@ -431,7 +431,6 @@ static int64_t get_file_size(FILE *file)
#else
#error Unknown platform
#endif
}
static void usb_msd_handle_reset(USBDevice* dev)
@ -444,14 +443,10 @@ static void usb_msd_handle_reset(USBDevice *dev)
#ifndef bswap32
#define bswap32(x) ( \
(((x)>>24)&0xff)\
|\
(((x)>>8)&0xff00)\
|\
(((x)<<8)&0xff0000)\
|\
(((x)<<24)&0xff000000)\
)
(((x) >> 24) & 0xff) | \
(((x) >> 8) & 0xff00) | \
(((x) << 8) & 0xff0000) | \
(((x) << 24) & 0xff000000))
#define bswap16(x) ((((x) >> 8) & 0xff) | (((x) << 8) & 0xff00))
#endif
@ -529,28 +524,38 @@ static void usb_msd_command_complete(MSDState *req, uint32_t status)
s->f.csw.residue = cpu_to_le32(s->f.data_len);
s->f.csw.status = status != 0;
if (s->packet) {
if (s->f.data_len == 0 && s->f.mode == USB_MSDM_DATAOUT) {
if (s->packet)
{
if (s->f.data_len == 0 && s->f.mode == USB_MSDM_DATAOUT)
{
/* A deferred packet with no write data remaining must be
the status read packet. */
usb_msd_send_status(s, p);
s->f.mode = USB_MSDM_CBW;
} else if (s->f.mode == USB_MSDM_CSW) {
}
else if (s->f.mode == USB_MSDM_CSW)
{
usb_msd_send_status(s, p);
s->f.mode = USB_MSDM_CBW;
} else {
if (s->f.data_len) {
}
else
{
if (s->f.data_len)
{
int len = (p->iov.size - p->actual_length);
usb_packet_skip(p, len);
s->f.data_len -= len;
}
if (s->f.data_len == 0) {
if (s->f.data_len == 0)
{
s->f.mode = USB_MSDM_CSW;
}
}
p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
usb_msd_packet_complete(s);
} else if (s->f.data_len == 0) {
}
else if (s->f.data_len == 0)
{
s->f.mode = USB_MSDM_CSW;
}
s->f.req.valid = false;
@ -569,7 +574,8 @@ static void usb_msd_copy_data(MSDState *s, USBPacket *p)
//TODO No async reader/writer so do it right here
if (s->f.tag == s->f.file_op_tag)
{
switch (s->f.mode) {
switch (s->f.mode)
{
case USB_MSDM_DATAOUT:
usb_packet_copy(p, s->f.buf, len);
if (len > 0 && (file_ret = fwrite(s->f.buf, 1, len, s->file)) < len)
@ -581,7 +587,8 @@ static void usb_msd_copy_data(MSDState *s, USBPacket *p)
}
break;
case USB_MSDM_DATAIN:
if((file_ret = fread(s->f.buf, 1, p->iov.size, s->file)) < p->iov.size) {
if ((file_ret = fread(s->f.buf, 1, p->iov.size, s->file)) < p->iov.size)
{
s->f.result = COMMAND_FAILED;
set_sense(s, SENSE_CODE(UNRECOVERED_READ_ERROR));
goto fail;
@ -667,7 +674,8 @@ static void send_command(void *opaque, struct usb_msd_cbw *cbw)
*blk_len = LBA_BLOCK_SIZE; //descriptor is currently max 64 bytes for bulk though
lbas = fsize / LBA_BLOCK_SIZE;
if (lbas > 0xFFFFFFFF) {
if (lbas > 0xFFFFFFFF)
{
DPRINTF("Maximum LBA is out of range!\n");
s->f.result = COMMAND_FAILED;
set_sense(s, SENSE_CODE(OUT_OF_RANGE));
@ -698,7 +706,8 @@ static void send_command(void *opaque, struct usb_msd_cbw *cbw)
if (xfer_len == 0) // nothing to do
break;
if(fseeko64(s->file, lba * LBA_BLOCK_SIZE, SEEK_SET)) {
if (fseeko64(s->file, lba * LBA_BLOCK_SIZE, SEEK_SET))
{
s->f.result = COMMAND_FAILED;
//TODO use errno
int64_t fsize = get_file_size(s->file);
@ -732,7 +741,8 @@ static void send_command(void *opaque, struct usb_msd_cbw *cbw)
if (xfer_len == 0) //nothing to do
break;
if(fseeko64(s->file, lba * LBA_BLOCK_SIZE, SEEK_SET)) {
if (fseeko64(s->file, lba * LBA_BLOCK_SIZE, SEEK_SET))
{
s->f.result = COMMAND_FAILED;
//TODO use errno
int64_t fsize = get_file_size(s->file);
@ -761,13 +771,15 @@ static void usb_msd_handle_control(USBDevice *dev, USBPacket *p, int request, in
int ret = 0;
ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
if (ret >= 0) {
if (ret >= 0)
{
return;
}
OSDebugOut(TEXT("request %04x %04x %04x\n"), request, value, index);
switch (request) {
switch (request)
{
/* Class specific requests. */
case ClassInterfaceOutRequest | MassStorageReset:
/* Reset state ready for the next CBW. */
@ -792,7 +804,8 @@ static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p)
assert(s->packet == p);
s->packet = NULL;
if (s->f.req.valid) {
if (s->f.req.valid)
{
//scsi_req_cancel(s->req);
}
}
@ -809,35 +822,45 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
// 3.) USB_MSDM_CSW: return USB_RET_ASYNC status if command is still in progress
// or complete and set mode to USB_MSDM_CBW.
switch (p->pid) {
switch (p->pid)
{
case USB_TOKEN_OUT:
if (devep != 2)
goto fail;
switch (s->f.mode) {
switch (s->f.mode)
{
case USB_MSDM_CBW:
if (p->iov.size != 31) {
if (p->iov.size != 31)
{
fprintf(stderr, "usb-msd: Bad CBW size\n");
goto fail;
}
usb_packet_copy(p, &cbw, 31);
if (le32_to_cpu(cbw.sig) != 0x43425355) {
if (le32_to_cpu(cbw.sig) != 0x43425355)
{
fprintf(stderr, "usb-msd: Bad signature %08x\n",
le32_to_cpu(cbw.sig));
goto fail;
}
DPRINTF("Command on LUN %d\n", cbw.lun);
if (cbw.lun != 0) {
if (cbw.lun != 0)
{
fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun);
goto fail;
}
s->f.tag = le32_to_cpu(cbw.tag);
s->f.data_len = le32_to_cpu(cbw.data_len);
if (s->f.data_len == 0) {
if (s->f.data_len == 0)
{
s->f.mode = USB_MSDM_CSW;
} else if (cbw.flags & 0x80) {
}
else if (cbw.flags & 0x80)
{
s->f.mode = USB_MSDM_DATAIN;
} else {
}
else
{
s->f.mode = USB_MSDM_DATAOUT;
}
DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
@ -853,7 +876,8 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
DPRINTF("Data out: write %d bytes of %d remaining\n", p->iov.size, s->f.data_len);
//TODO check if CBW still falls into here on write error a.k.a s->f.mode is set wrong
DPRINTF("Data out %zd/%d\n", p->iov.size, s->f.data_len);
if (p->iov.size > s->f.data_len) {
if (p->iov.size > s->f.data_len)
{
goto fail;
}
@ -864,17 +888,21 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
{
usb_msd_copy_data(s, p);
}
if (le32_to_cpu(s->f.csw.residue)) {
if (le32_to_cpu(s->f.csw.residue))
{
int len = p->iov.size - p->actual_length;
if (len) {
if (len)
{
usb_packet_skip(p, len);
s->f.data_len -= len;
if (s->f.data_len == 0) {
if (s->f.data_len == 0)
{
s->f.mode = USB_MSDM_CSW;
}
}
}
if ((size_t)p->actual_length < p->iov.size) {
if ((size_t)p->actual_length < p->iov.size)
{
DPRINTF("Deferring packet %p [wait data-out]\n", p);
s->packet = p;
p->status = USB_RET_ASYNC;
@ -894,9 +922,11 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
if (devep != 1)
goto fail;
switch (s->f.mode) {
switch (s->f.mode)
{
case USB_MSDM_DATAOUT:
if (s->f.data_len != 0 || p->iov.size < 13) {
if (s->f.data_len != 0 || p->iov.size < 13)
{
goto fail;
}
/* Waiting for SCSI write to complete. */
@ -908,16 +938,20 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
send_csw:
DPRINTF("Command status %d tag 0x%x, len %d\n",
s->f.result, s->f.tag, p->iov.size);
if (p->iov.size < 13) {
if (p->iov.size < 13)
{
goto fail;
}
if (false && s->f.req.valid) { // If reading/writing using something asynchronous
if (false && s->f.req.valid)
{ // If reading/writing using something asynchronous
/* still in flight */
DPRINTF("Deferring packet %p [wait status]\n", p);
s->packet = p;
p->status = USB_RET_ASYNC;
} else {
}
else
{
//TODO primarily for setting csw.sig with correct value
usb_msd_command_complete(s, s->f.result);
@ -941,18 +975,22 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
{
usb_msd_copy_data(s, p);
}
if (le32_to_cpu(s->f.csw.residue)) {
if (le32_to_cpu(s->f.csw.residue))
{
int len = p->iov.size - p->actual_length;
if (len) {
if (len)
{
usb_packet_skip(p, len);
s->f.data_len -= len;
if (s->f.data_len == 0) {
if (s->f.data_len == 0)
{
s->f.mode = USB_MSDM_CSW;
}
}
}
if ((size_t)p->actual_length < p->iov.size) {
if ((size_t)p->actual_length < p->iov.size)
{
DPRINTF("Deferring packet %p [wait data-in]\n", p);
s->packet = p;
p->status = USB_RET_ASYNC;
@ -1003,7 +1041,8 @@ USBDevice *MsdDevice::CreateDevice(int port)
}
s->file = wfopen(var.c_str(), TEXT("r+b"));
if (!s->file) {
if (!s->file)
{
SysMessage(TEXT("usb-msd: Could not open image file '%s'\n"), var.c_str());
goto fail;
}
@ -1052,7 +1091,8 @@ int MsdDevice::Freeze(int mode, USBDevice *dev, void *data)
switch (mode)
{
case FREEZE_LOAD:
if (!s) return -1;
if (!s)
return -1;
//if (s->f.req) free (s->f.req);
tmp = (MSDState::freeze*)data;
@ -1067,7 +1107,8 @@ int MsdDevice::Freeze(int mode, USBDevice *dev, void *data)
return sizeof(MSDState::freeze); // + sizeof(ReqState);
case FREEZE_SAVE:
if (!s) return -1;
if (!s)
return -1;
tmp = (MSDState::freeze*)data;
*tmp = s->f;
return sizeof(MSDState::freeze);
@ -1081,4 +1122,4 @@ int MsdDevice::Freeze(int mode, USBDevice *dev, void *data)
}
#undef DPRINTF
} //namespace
} // namespace usb_msd

View File

@ -17,7 +17,8 @@
#define USBMSD_H
#include "../deviceproxy.h"
namespace usb_msd {
namespace usb_msd
{
static const char* APINAME = "cstdio";
@ -43,5 +44,5 @@ public:
static int Freeze(int mode, USBDevice* dev, void* data);
};
}
} // namespace usb_msd
#endif

View File

@ -24,20 +24,23 @@
//
#define PREPARE_FIRST_COPY() \
do { \
if (src_len >= (CHAR_BIT - dst_offset_modulo)) { \
do \
{ \
if (src_len >= (CHAR_BIT - dst_offset_modulo)) \
{ \
*dst &= reverse_mask[dst_offset_modulo]; \
src_len -= CHAR_BIT - dst_offset_modulo; \
} else { \
*dst &= reverse_mask[dst_offset_modulo] \
| reverse_mask_xor[dst_offset_modulo + src_len + 1];\
} \
else \
{ \
*dst &= reverse_mask[dst_offset_modulo] | reverse_mask_xor[dst_offset_modulo + src_len + 1]; \
c &= reverse_mask[dst_offset_modulo + src_len]; \
src_len = 0; \
} } while (0)
} \
} while (0)
//But copies bits in reverse?
void
bitarray_copy(const uint8_t*src_org, int src_offset, int src_len,
void bitarray_copy(const uint8_t* src_org, int src_offset, int src_len,
uint8_t* dst_org, int dst_offset)
{
static const unsigned char mask[] =
@ -47,7 +50,8 @@ bitarray_copy(const uint8_t*src_org, int src_offset, int src_len,
static const unsigned char reverse_mask_xor[] =
{0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00};
if (src_len) {
if (src_len)
{
const unsigned char* src;
unsigned char* dst;
int src_offset_modulo,
@ -59,10 +63,12 @@ bitarray_copy(const uint8_t*src_org, int src_offset, int src_len,
src_offset_modulo = src_offset % CHAR_BIT;
dst_offset_modulo = dst_offset % CHAR_BIT;
if (src_offset_modulo == dst_offset_modulo) {
if (src_offset_modulo == dst_offset_modulo)
{
int byte_len;
int src_len_modulo;
if (src_offset_modulo) {
if (src_offset_modulo)
{
unsigned char c;
c = reverse_mask_xor[dst_offset_modulo] & *src++;
@ -74,16 +80,20 @@ bitarray_copy(const uint8_t*src_org, int src_offset, int src_len,
byte_len = src_len / CHAR_BIT;
src_len_modulo = src_len % CHAR_BIT;
if (byte_len) {
if (byte_len)
{
memcpy(dst, src, byte_len);
src += byte_len;
dst += byte_len;
}
if (src_len_modulo) {
if (src_len_modulo)
{
*dst &= reverse_mask_xor[src_len_modulo];
*dst |= reverse_mask[src_len_modulo] & *src;
}
} else {
}
else
{
int bit_diff_ls,
bit_diff_rs;
int byte_len;
@ -92,14 +102,17 @@ bitarray_copy(const uint8_t*src_org, int src_offset, int src_len,
/*
* Begin: Line things up on destination.
*/
if (src_offset_modulo > dst_offset_modulo) {
if (src_offset_modulo > dst_offset_modulo)
{
bit_diff_ls = src_offset_modulo - dst_offset_modulo;
bit_diff_rs = CHAR_BIT - bit_diff_ls;
c = *src++ << bit_diff_ls;
c |= *src >> bit_diff_rs;
c &= reverse_mask_xor[dst_offset_modulo];
} else {
}
else
{
bit_diff_rs = dst_offset_modulo - src_offset_modulo;
bit_diff_ls = CHAR_BIT - bit_diff_rs;
@ -114,7 +127,8 @@ bitarray_copy(const uint8_t*src_org, int src_offset, int src_len,
*/
byte_len = src_len / CHAR_BIT;
while (--byte_len >= 0) {
while (--byte_len >= 0)
{
c = *src++ << bit_diff_ls;
c |= *src >> bit_diff_rs;
*dst++ = c;
@ -124,7 +138,8 @@ bitarray_copy(const uint8_t*src_org, int src_offset, int src_len,
* End: copy the remaing bits;
*/
src_len_modulo = src_len % CHAR_BIT;
if (src_len_modulo) {
if (src_len_modulo)
{
c = *src++ << bit_diff_ls;
c |= *src >> bit_diff_rs;
c &= reverse_mask[src_len_modulo];

View File

@ -27,7 +27,10 @@
#include "usb-pad-dx.h"
namespace usb_pad { namespace dx {
namespace usb_pad
{
namespace dx
{
static int32_t useRamp = 0;
@ -133,7 +136,8 @@ void SetControlLabel(int cid, const InputMapped& im)
//config only
void ListenUpdate()
{
for (size_t i=0; i<g_pJoysticks.size(); i++) {
for (size_t i = 0; i < g_pJoysticks.size(); i++)
{
jso[i] = g_pJoysticks[i]->GetDeviceState();
}
PollDevices();
@ -143,7 +147,8 @@ void ListenUpdate()
void ListenAxis()
{
PollDevices();
for (size_t i=0; i<g_pJoysticks.size(); i++) {
for (size_t i = 0; i < g_pJoysticks.size(); i++)
{
if (g_pJoysticks[i]->GetControlType() != CT_JOYSTICK)
continue;
jso[i] = g_pJoysticks[i]->GetDeviceState();
@ -169,16 +174,16 @@ bool AxisDown(size_t ijoy, InputMapped& im)
return false;
DIJOYSTATE2 js = g_pJoysticks[ijoy]->GetDeviceState();
std::cerr << __func__ << ": joystick[" << ijoy << "]: " <<
"\tlX " << js.lX << "\n" <<
"\tlY " << js.lY << "\n" <<
"\tlZ " << js.lZ << "\n" <<
"\tlRx " << js.lRx << "\n" <<
"\tlRy " << js.lRy << "\n" <<
"\tlRz " << js.lRz << "\n" <<
"\trglSlider0 " << js.rglSlider[0] << "\n" <<
"\trglSlider1 " << js.rglSlider[1] << "\n" <<
std::endl;
std::cerr << __func__ << ": joystick[" << ijoy << "]: "
<< "\tlX " << js.lX << "\n"
<< "\tlY " << js.lY << "\n"
<< "\tlZ " << js.lZ << "\n"
<< "\tlRx " << js.lRx << "\n"
<< "\tlRy " << js.lRy << "\n"
<< "\tlRz " << js.lRz << "\n"
<< "\trglSlider0 " << js.rglSlider[0] << "\n"
<< "\trglSlider1 " << js.rglSlider[1] << "\n"
<< std::endl;
LONG detectrange = 2000;
for (int32_t axisid = 0; axisid < DINPUT_AXES_COUNT; axisid++)
@ -190,13 +195,15 @@ bool AxisDown(size_t ijoy, InputMapped& im)
// TODO mind the POV axes, one axis for all directions?
diff = GetAxisValueFromOffset(axisid, js) - GetAxisValueFromOffset(axisid, jso[ijoy]);
if (diff > detectrange) {
if (diff > detectrange)
{
im.HALF = GetAxisValueFromOffset(axisid, jsi[ijoy]);
im.INVERTED = true;
im.type = MappingType::MT_AXIS;
return true;
}
if (diff < -detectrange) {
if (diff < -detectrange)
{
im.HALF = GetAxisValueFromOffset(axisid, jsi[ijoy]);
im.INVERTED = false;
im.type = MappingType::MT_AXIS;
@ -219,7 +226,8 @@ bool KeyDown(size_t ijoy, InputMapped& im)
int buttons = 0;
switch (joy->GetControlType()) {
switch (joy->GetControlType())
{
case CT_JOYSTICK:
buttons = ARRAY_SIZE(DIJOYSTATE2::rgbButtons) + 16 /* POV */;
break;
@ -233,8 +241,10 @@ bool KeyDown(size_t ijoy, InputMapped& im)
break;
}
for (int b = 0; b < buttons; b++) {
if (joy->GetButton(b)) {
for (int b = 0; b < buttons; b++)
{
if (joy->GetButton(b))
{
im.mapped = b;
im.type = MT_BUTTON;
return true;
@ -247,7 +257,8 @@ bool KeyDown(size_t ijoy, InputMapped& im)
//search all axis/buttons (config only)
bool FindControl(LONG port, ControlID cid, InputMapped& im)
{
if (listening==true) {
if (listening == true)
{
if (listenend > GetTickCount())
{
if (listennext < GetTickCount())
@ -255,23 +266,29 @@ bool FindControl(LONG port, ControlID cid, InputMapped& im)
listennext = listeninterval + GetTickCount();
ListenUpdate();
for (size_t i = 0; i<g_pJoysticks.size(); i++) {
if (AxisDown(i, im)) {
for (size_t i = 0; i < g_pJoysticks.size(); i++)
{
if (AxisDown(i, im))
{
listening = false;
if (CID_STEERING == cid) {
if (CID_STEERING == cid)
{
CreateFFB(port, g_pJoysticks[im.index]->GetDevice(), im.mapped);
}
AddInputMap(port, cid, im);
return true;
}
else if (KeyDown(i, im)) {
else if (KeyDown(i, im))
{
listening = false;
AddInputMap(port, cid, im);
return true;
}
}
}
}else{
}
else
{
GetInputMap(port, cid, im);
SetControlLabel(cid, im);
listening = false;
@ -285,7 +302,8 @@ void ApplyFilter(int port)
{
filtercontrol = SendMessage(GetDlgItem(hWnd, IDC_COMBO1), CB_GETCURSEL, 0, 0);
if(filtercontrol==-1)return;
if (filtercontrol == -1)
return;
//slider
LINEAR[port][filtercontrol] = SendMessage(GetDlgItem(hWnd, IDC_SLIDER1), TBM_GETPOS, 0, 0) - 50 * PRECMULTI;
OFFSET[port][filtercontrol] = SendMessage(GetDlgItem(hWnd, IDC_SLIDER2), TBM_GETPOS, 0, 0) - 50 * PRECMULTI;
@ -308,7 +326,8 @@ void ApplyFilter(int port)
void LoadFilter(int port)
{
filtercontrol = SendMessage(GetDlgItem(hWnd, IDC_COMBO1), CB_GETCURSEL, 0, 0);
if(filtercontrol==-1)return;
if (filtercontrol == -1)
return;
//InputMapped im = {};
//GetInputMap(port, (ControlID)filtercontrol, im);
//slider
@ -384,7 +403,9 @@ void ControlTest(int port) //thread: waits for window
MapWindowPoints(GetDlgItem(hWnd, IDC_PICTURE), hWnd, (POINT*)&rect, 2);
InvalidateRect(hWnd, &rect, TRUE);
}
}else{
}
else
{
TESTV = 0;
}
@ -397,7 +418,8 @@ void ListenForControl(int port)
if (FindControl(port, CID, im))
{
if (CID <= CID_BRAKE) {
if (CID <= CID_BRAKE)
{
LINEAR[port][CID] = im.LINEAR;
OFFSET[port][CID] = im.OFFSET;
DEADZONE[port][CID] = im.DEADZONE;
@ -406,7 +428,8 @@ void ListenForControl(int port)
AddInputMap(port, CID, im);
SetControlLabel(CID, im);
}
else if(listening) {
else if (listening)
{
swprintf_s(text, L"Listening... %u", GetListenTimeout() / 1000 + 1);
SetWindowText(GetDlgItem(hWnd, LABELS[CID]), text);
}
@ -414,10 +437,12 @@ void ListenForControl(int port)
void StartListen(ControlID controlid)
{
if(listening)return;
if (listening)
return;
CID = controlid;
swprintf_s(text, L"Listening...");SetWindowText(GetDlgItem(hWnd,LABELS[CID]),text);
swprintf_s(text, L"Listening...");
SetWindowText(GetDlgItem(hWnd, LABELS[CID]), text);
OSDebugOut(TEXT("Begin Listen %i\n"), -1);
ListenAxis();
}
@ -474,7 +499,8 @@ void CreateDrawing(int port, HDC hDrawingDC, int scale)
}
filtercontrol = SendMessage(GetDlgItem(hWnd, IDC_COMBO1), CB_GETCURSEL, 0, 0);
if(filtercontrol>=0){
if (filtercontrol >= 0)
{
//draw nonlinear line
SelectObject(hDrawingDC, bluepen);
@ -661,7 +687,8 @@ void OnPaint(int port)
int px = rect.left;
int py = rect.top;
if (px <= 0 || py <= 0) {
if (px <= 0 || py <= 0)
{
return;
}
int pwidth = rect.right - rect.left;
@ -829,7 +856,8 @@ INT_PTR CALLBACK DxDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
hWnd = hDlg;
SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam);
InitDialog(s->port, s->dev_type);
}break;
}
break;
case WM_CTLCOLORSTATIC:
{
if ((HWND)lParam == GetDlgItem(hWnd, IDC_GROUP1) || (HWND)lParam == GetDlgItem(hWnd, IDC_GROUP2) || (HWND)lParam == GetDlgItem(hWnd, IDC_GROUP3))
@ -838,42 +866,32 @@ INT_PTR CALLBACK DxDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
SetBkMode((HDC)wParam, TRANSPARENT);
return (INT_PTR)GetStockObject(NULL_BRUSH);
}
if ((HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL1_LBL1)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL2_LBL1)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL3_LBL1)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL4_LBL1)) {
if ((HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL1_LBL1) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL2_LBL1) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL3_LBL1) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL4_LBL1))
{
SetTextColor((HDC)wParam, RGB(255, 0, 0));
SetBkMode((HDC)wParam, TRANSPARENT);
return (INT_PTR)GetStockObject(NULL_BRUSH);
}
if ((HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL1_LBL2)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL2_LBL2)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL3_LBL2)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL4_LBL2)) {
if ((HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL1_LBL2) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL2_LBL2) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL3_LBL2) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL4_LBL2))
{
SetTextColor((HDC)wParam, RGB(0, 192, 255));
SetBkMode((HDC)wParam, TRANSPARENT);
return (INT_PTR)GetStockObject(NULL_BRUSH);
}
if ((HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL1_LBL3)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL2_LBL3)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL3_LBL3)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL4_LBL3)) {
if ((HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL1_LBL3) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL2_LBL3) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL3_LBL3) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL4_LBL3))
{
SetTextColor((HDC)wParam, RGB(255, 165, 0));
SetBkMode((HDC)wParam, TRANSPARENT);
return (INT_PTR)GetStockObject(NULL_BRUSH);
}
if ((HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL1_LBL4)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL2_LBL4)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL3_LBL4)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL4_LBL4)) {
if ((HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL1_LBL4) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL2_LBL4) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL3_LBL4) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL4_LBL4))
{
SetTextColor((HDC)wParam, RGB(0, 140, 0));
SetBkMode((HDC)wParam, TRANSPARENT);
return (INT_PTR)GetStockObject(NULL_BRUSH);
}
if ((HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL1_LBL5)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL2_LBL5)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL3_LBL5)
|| (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL4_LBL5)) {
if ((HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL1_LBL5) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL2_LBL5) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL3_LBL5) || (HWND)lParam == GetDlgItem(hWnd, IDC_BZ_CTL4_LBL5))
{
SetTextColor((HDC)wParam, RGB(204, 204, 0));
SetBkMode((HDC)wParam, TRANSPARENT);
return (INT_PTR)GetStockObject(NULL_BRUSH);
@ -889,11 +907,11 @@ INT_PTR CALLBACK DxDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
case 22:
{
s = (DXDlgSettings*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
if(listening) ListenForControl(s->port);
if (listening)
ListenForControl(s->port);
ControlTest(s->port);
break;
}
}
break;
}
@ -944,7 +962,6 @@ INT_PTR CALLBACK DxDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
FreeDirectInput();
EndDialog(hWnd, TRUE);
return TRUE;
}
//break; //Fall through
case IDCANCEL:
@ -955,7 +972,6 @@ INT_PTR CALLBACK DxDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
FreeDirectInput();
EndDialog(hWnd, FALSE);
return TRUE;
}
break;
case IDC_BUTTON1:
@ -965,51 +981,223 @@ INT_PTR CALLBACK DxDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
}
break;
case IDC_ASS0: { StartListen(CID_STEERING); break; }
case IDC_ASS1: { StartListen(CID_STEERING_R); break; }
case IDC_ASS2: { StartListen(CID_THROTTLE); break; }
case IDC_ASS3: { StartListen(CID_BRAKE); break; }
case IDC_ASS4: { StartListen(CID_HATUP); break; }
case IDC_ASS5: { StartListen(CID_HATDOWN); break; }
case IDC_ASS6: { StartListen(CID_HATLEFT); break; }
case IDC_ASS7: { StartListen(CID_HATRIGHT); break; }
case IDC_ASS8: { StartListen(CID_SQUARE); break; }
case IDC_ASS9: { StartListen(CID_TRIANGLE); break; }
case IDC_ASS10: { StartListen(CID_CROSS); break; }
case IDC_ASS11: { StartListen(CID_CIRCLE); break; }
case IDC_ASS12: { StartListen(CID_L1); break; }
case IDC_ASS13: { StartListen(CID_R1); break; }
case IDC_ASS14: { StartListen(CID_L2); break; }
case IDC_ASS15: { StartListen(CID_R2); break; }
case IDC_ASS16: { StartListen(CID_L3); break; }
case IDC_ASS17: { StartListen(CID_R3); break; }
case IDC_ASS18: { StartListen(CID_SELECT); break; }
case IDC_ASS19: { StartListen(CID_START); break; }
case IDC_DEL0: { DeleteControl(s->port, CID_STEERING); break; }
case IDC_DEL1: { DeleteControl(s->port, CID_STEERING_R); break; }
case IDC_DEL2: { DeleteControl(s->port, CID_THROTTLE); break; }
case IDC_DEL3: { DeleteControl(s->port, CID_BRAKE); break; }
case IDC_DEL4: { DeleteControl(s->port, CID_HATUP); break; }
case IDC_DEL5: { DeleteControl(s->port, CID_HATDOWN); break; }
case IDC_DEL6: { DeleteControl(s->port, CID_HATLEFT); break; }
case IDC_DEL7: { DeleteControl(s->port, CID_HATRIGHT); break; }
case IDC_DEL8: { DeleteControl(s->port, CID_SQUARE); break; }
case IDC_DEL9: { DeleteControl(s->port, CID_TRIANGLE); break; }
case IDC_DEL10: { DeleteControl(s->port, CID_CROSS); break; }
case IDC_DEL11: { DeleteControl(s->port, CID_CIRCLE); break; }
case IDC_DEL12: { DeleteControl(s->port, CID_L1); break; }
case IDC_DEL13: { DeleteControl(s->port, CID_R1); break; }
case IDC_DEL14: { DeleteControl(s->port, CID_L2); break; }
case IDC_DEL15: { DeleteControl(s->port, CID_R2); break; }
case IDC_DEL16: { DeleteControl(s->port, CID_L3); break; }
case IDC_DEL17: { DeleteControl(s->port, CID_R3); break; }
case IDC_DEL18: { DeleteControl(s->port, CID_SELECT); break; }
case IDC_DEL19: { DeleteControl(s->port, CID_START); break; }
case IDC_ASS0:
{
StartListen(CID_STEERING);
break;
}
case IDC_ASS1:
{
StartListen(CID_STEERING_R);
break;
}
case IDC_ASS2:
{
StartListen(CID_THROTTLE);
break;
}
case IDC_ASS3:
{
StartListen(CID_BRAKE);
break;
}
case IDC_ASS4:
{
StartListen(CID_HATUP);
break;
}
case IDC_ASS5:
{
StartListen(CID_HATDOWN);
break;
}
case IDC_ASS6:
{
StartListen(CID_HATLEFT);
break;
}
case IDC_ASS7:
{
StartListen(CID_HATRIGHT);
break;
}
case IDC_ASS8:
{
StartListen(CID_SQUARE);
break;
}
case IDC_ASS9:
{
StartListen(CID_TRIANGLE);
break;
}
case IDC_ASS10:
{
StartListen(CID_CROSS);
break;
}
case IDC_ASS11:
{
StartListen(CID_CIRCLE);
break;
}
case IDC_ASS12:
{
StartListen(CID_L1);
break;
}
case IDC_ASS13:
{
StartListen(CID_R1);
break;
}
case IDC_ASS14:
{
StartListen(CID_L2);
break;
}
case IDC_ASS15:
{
StartListen(CID_R2);
break;
}
case IDC_ASS16:
{
StartListen(CID_L3);
break;
}
case IDC_ASS17:
{
StartListen(CID_R3);
break;
}
case IDC_ASS18:
{
StartListen(CID_SELECT);
break;
}
case IDC_ASS19:
{
StartListen(CID_START);
break;
}
case IDC_DEL0:
{
DeleteControl(s->port, CID_STEERING);
break;
}
case IDC_DEL1:
{
DeleteControl(s->port, CID_STEERING_R);
break;
}
case IDC_DEL2:
{
DeleteControl(s->port, CID_THROTTLE);
break;
}
case IDC_DEL3:
{
DeleteControl(s->port, CID_BRAKE);
break;
}
case IDC_DEL4:
{
DeleteControl(s->port, CID_HATUP);
break;
}
case IDC_DEL5:
{
DeleteControl(s->port, CID_HATDOWN);
break;
}
case IDC_DEL6:
{
DeleteControl(s->port, CID_HATLEFT);
break;
}
case IDC_DEL7:
{
DeleteControl(s->port, CID_HATRIGHT);
break;
}
case IDC_DEL8:
{
DeleteControl(s->port, CID_SQUARE);
break;
}
case IDC_DEL9:
{
DeleteControl(s->port, CID_TRIANGLE);
break;
}
case IDC_DEL10:
{
DeleteControl(s->port, CID_CROSS);
break;
}
case IDC_DEL11:
{
DeleteControl(s->port, CID_CIRCLE);
break;
}
case IDC_DEL12:
{
DeleteControl(s->port, CID_L1);
break;
}
case IDC_DEL13:
{
DeleteControl(s->port, CID_R1);
break;
}
case IDC_DEL14:
{
DeleteControl(s->port, CID_L2);
break;
}
case IDC_DEL15:
{
DeleteControl(s->port, CID_R2);
break;
}
case IDC_DEL16:
{
DeleteControl(s->port, CID_L3);
break;
}
case IDC_DEL17:
{
DeleteControl(s->port, CID_R3);
break;
}
case IDC_DEL18:
{
DeleteControl(s->port, CID_SELECT);
break;
}
case IDC_DEL19:
{
DeleteControl(s->port, CID_START);
break;
}
case IDC_PICTURELINK1:{ShellExecuteA(NULL, "open", "http://www.ecsimhardware.com",NULL, NULL, SW_SHOWNORMAL);break;}
case IDC_PICTURELINK2:{ShellExecuteA(NULL, "open", "http://www.ecsimshop.com",NULL, NULL, SW_SHOWNORMAL);break;}
case IDC_PICTURELINK3:{ShellExecuteA(NULL, "open", "http://www.tocaedit.com",NULL, NULL, SW_SHOWNORMAL);break;}
case IDC_PICTURELINK1:
{
ShellExecuteA(NULL, "open", "http://www.ecsimhardware.com", NULL, NULL, SW_SHOWNORMAL);
break;
}
case IDC_PICTURELINK2:
{
ShellExecuteA(NULL, "open", "http://www.ecsimshop.com", NULL, NULL, SW_SHOWNORMAL);
break;
}
case IDC_PICTURELINK3:
{
ShellExecuteA(NULL, "open", "http://www.tocaedit.com", NULL, NULL, SW_SHOWNORMAL);
break;
}
}
break;
@ -1060,7 +1248,8 @@ void SaveDInputConfig(int port, const char *dev_type)
ss << joy->GetGUID() << "," << im.type << "," << im.mapped;
//SaveSetting(section, _T("ProductName"), joy->Product());
if (joy->GetControlType() == CT_JOYSTICK) {
if (joy->GetControlType() == CT_JOYSTICK)
{
ss << "," << im.INVERTED
<< "," << im.HALF
<< "," << im.LINEAR
@ -1110,10 +1299,12 @@ void LoadDInputConfig(int port, const char* dev_type)
ss << control;
std::getline(ss, guid, ',');
for (size_t i = 0; i < g_pJoysticks.size(); i++) {
for (size_t i = 0; i < g_pJoysticks.size(); i++)
{
std::stringstream ss_guid;
ss_guid << g_pJoysticks[i]->GetGUID();
if (ss_guid.str() == guid) {
if (ss_guid.str() == guid)
{
im.index = i;
found = true;
break;
@ -1126,7 +1317,8 @@ void LoadDInputConfig(int port, const char* dev_type)
std::getline(ss, value, ',');
im.type = (MappingType)std::stoi(value);
if (im.type == MT_NONE) {
if (im.type == MT_NONE)
{
OSDebugOut(_T("Skipping control %d (%s), mapping type is None\n"), cid, g_pJoysticks[im.index]->Product().c_str());
continue;
}
@ -1158,7 +1350,8 @@ void LoadDInputConfig(int port, const char* dev_type)
AddInputMap(port, (ControlID)cid, im);
}
}
catch (std::exception& err) {
catch (std::exception& err)
{
OSDebugOut(TEXT("%" SFMTs "\n"), err.what());
}
@ -1171,11 +1364,13 @@ int DInputPad::Configure(int port, const char* dev_type, void *data)
struct DXDlgSettings s;
s.port = port;
s.dev_type = dev_type;
if (strcmp(dev_type, "buzz_device") == 0) {
if (strcmp(dev_type, "buzz_device") == 0)
{
return DialogBoxParam(h.hInst, MAKEINTRESOURCE(IDD_DLG_BUZZ), h.hWnd, DxDialogProc, (LPARAM)&s);
}
return DialogBoxParam(h.hInst, MAKEINTRESOURCE(IDD_DIALOG1), h.hWnd, DxDialogProc, (LPARAM)&s);
}
}} //namespace
} // namespace dx
} // namespace usb_pad
#pragma warning(pop)

View File

@ -16,13 +16,30 @@
#include <math.h>
#include "dx.h"
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#define SAFE_DELETE(p) \
{ \
if (p) \
{ \
delete (p); \
(p) = NULL; \
} \
}
#define SAFE_RELEASE(p) \
{ \
if (p) \
{ \
(p)->Release(); \
(p) = NULL; \
} \
}
//dialog window stuff
extern HWND gsWnd;
namespace usb_pad { namespace dx {
namespace usb_pad
{
namespace dx
{
static std::atomic<int> refCount(0);
static bool useRamp = false;
@ -58,7 +75,8 @@ static DICONDITION cFriction;
static DIRAMPFORCE cRamp;
static DICONDITION cDamper;
std::ostream& operator<<(std::ostream& os, REFGUID guid) {
std::ostream& operator<<(std::ostream& os, REFGUID guid)
{
std::ios_base::fmtflags f(os.flags());
os << std::uppercase;
os.width(8);
@ -90,42 +108,106 @@ LONG GetAxisValueFromOffset(int axis, const DIJOYSTATE2& j)
#define LVX_OFFSET 8 // count POVs or not?
switch (axis)
{
case 0: return j.lX; break;
case 1: return j.lY; break;
case 2: return j.lZ; break;
case 3: return j.lRx; break;
case 4: return j.lRy; break;
case 5: return j.lRz; break;
case 6: return j.rglSlider[0]; break;
case 7: return j.rglSlider[1]; break;
case 0:
return j.lX;
break;
case 1:
return j.lY;
break;
case 2:
return j.lZ;
break;
case 3:
return j.lRx;
break;
case 4:
return j.lRy;
break;
case 5:
return j.lRz;
break;
case 6:
return j.rglSlider[0];
break;
case 7:
return j.rglSlider[1];
break;
//case 8: return j.rgdwPOV[0]; break;
//case 9: return j.rgdwPOV[1]; break;
//case 10: return j.rgdwPOV[2]; break;
//case 11: return j.rgdwPOV[3]; break;
case LVX_OFFSET + 0: return j.lVX; break; /* 'v' as in velocity */
case LVX_OFFSET + 1: return j.lVY; break;
case LVX_OFFSET + 2: return j.lVZ; break;
case LVX_OFFSET + 3: return j.lVRx; break;
case LVX_OFFSET + 4: return j.lVRy; break;
case LVX_OFFSET + 5: return j.lVRz; break;
case LVX_OFFSET + 6: return j.rglVSlider[0]; break;
case LVX_OFFSET + 7: return j.rglVSlider[1]; break;
case LVX_OFFSET + 8: return j.lAX; break; /* 'a' as in acceleration */
case LVX_OFFSET + 9: return j.lAY; break;
case LVX_OFFSET + 10: return j.lAZ; break;
case LVX_OFFSET + 11: return j.lARx; break;
case LVX_OFFSET + 12: return j.lARy; break;
case LVX_OFFSET + 13: return j.lARz; break;
case LVX_OFFSET + 14: return j.rglASlider[0]; break;
case LVX_OFFSET + 15: return j.rglASlider[1]; break;
case LVX_OFFSET + 16: return j.lFX; break; /* 'f' as in force */
case LVX_OFFSET + 17: return j.lFY; break;
case LVX_OFFSET + 18: return j.lFZ; break;
case LVX_OFFSET + 19: return j.lFRx; break; /* 'fr' as in rotational force aka torque */
case LVX_OFFSET + 20: return j.lFRy; break;
case LVX_OFFSET + 21: return j.lFRz; break;
case LVX_OFFSET + 22: return j.rglFSlider[0]; break;
case LVX_OFFSET + 23: return j.rglFSlider[1]; break;
case LVX_OFFSET + 0:
return j.lVX;
break; /* 'v' as in velocity */
case LVX_OFFSET + 1:
return j.lVY;
break;
case LVX_OFFSET + 2:
return j.lVZ;
break;
case LVX_OFFSET + 3:
return j.lVRx;
break;
case LVX_OFFSET + 4:
return j.lVRy;
break;
case LVX_OFFSET + 5:
return j.lVRz;
break;
case LVX_OFFSET + 6:
return j.rglVSlider[0];
break;
case LVX_OFFSET + 7:
return j.rglVSlider[1];
break;
case LVX_OFFSET + 8:
return j.lAX;
break; /* 'a' as in acceleration */
case LVX_OFFSET + 9:
return j.lAY;
break;
case LVX_OFFSET + 10:
return j.lAZ;
break;
case LVX_OFFSET + 11:
return j.lARx;
break;
case LVX_OFFSET + 12:
return j.lARy;
break;
case LVX_OFFSET + 13:
return j.lARz;
break;
case LVX_OFFSET + 14:
return j.rglASlider[0];
break;
case LVX_OFFSET + 15:
return j.rglASlider[1];
break;
case LVX_OFFSET + 16:
return j.lFX;
break; /* 'f' as in force */
case LVX_OFFSET + 17:
return j.lFY;
break;
case LVX_OFFSET + 18:
return j.lFZ;
break;
case LVX_OFFSET + 19:
return j.lFRx;
break; /* 'fr' as in rotational force aka torque */
case LVX_OFFSET + 20:
return j.lFRy;
break;
case LVX_OFFSET + 21:
return j.lFRz;
break;
case LVX_OFFSET + 22:
return j.rglFSlider[0];
break;
case LVX_OFFSET + 23:
return j.rglFSlider[1];
break;
}
#undef LVX_OFFSET
return 0;
@ -144,11 +226,16 @@ bool JoystickDevice::Poll()
}
else
{
if (m_type == CT_JOYSTICK) {
if (m_type == CT_JOYSTICK)
{
m_device->GetDeviceState(sizeof(DIJOYSTATE2), &m_controls);
} else if (m_type == CT_MOUSE) {
}
else if (m_type == CT_MOUSE)
{
m_device->GetDeviceState(sizeof(DIMOUSESTATE2), &m_controls);
} else if (m_type == CT_KEYBOARD) {
}
else if (m_type == CT_KEYBOARD)
{
m_device->GetDeviceState(sizeof(m_controls.kbd), &m_controls);
}
return true;
@ -159,7 +246,8 @@ bool JoystickDevice::Poll()
bool JoystickDevice::GetButton(int b)
{
if (m_type == CT_JOYSTICK) {
if (m_type == CT_JOYSTICK)
{
if (b < ARRAY_SIZE(DIJOYSTATE2::rgbButtons) && m_controls.js2.rgbButtons[b] & 0x80)
return true;
@ -171,31 +259,38 @@ bool JoystickDevice::GetButton(int b)
switch (b % 4)
{
case 0:
if ((m_controls.js2.rgdwPOV[i] <= 4500 || m_controls.js2.rgdwPOV[i] >= 31500) && m_controls.js2.rgdwPOV[i] != -1) {
if ((m_controls.js2.rgdwPOV[i] <= 4500 || m_controls.js2.rgdwPOV[i] >= 31500) && m_controls.js2.rgdwPOV[i] != -1)
{
return true;
}
break;
case 1:
if (m_controls.js2.rgdwPOV[i] >= 4500 && m_controls.js2.rgdwPOV[i] <= 13500) {
if (m_controls.js2.rgdwPOV[i] >= 4500 && m_controls.js2.rgdwPOV[i] <= 13500)
{
return true;
}
break;
case 2:
if (m_controls.js2.rgdwPOV[i] >= 13500 && m_controls.js2.rgdwPOV[i] <= 22500) {
if (m_controls.js2.rgdwPOV[i] >= 13500 && m_controls.js2.rgdwPOV[i] <= 22500)
{
return true;
}
break;
case 3:
if (m_controls.js2.rgdwPOV[i] >= 22500 && m_controls.js2.rgdwPOV[i] <= 31500) {
if (m_controls.js2.rgdwPOV[i] >= 22500 && m_controls.js2.rgdwPOV[i] <= 31500)
{
return true;
}
break;
}
}
}
else if (m_type == CT_KEYBOARD) {
else if (m_type == CT_KEYBOARD)
{
return (b < ARRAY_SIZE(m_controls.kbd) && m_controls.kbd[b] & 0x80);
} else if (m_type == CT_MOUSE) {
}
else if (m_type == CT_MOUSE)
{
return (b < ARRAY_SIZE(DIMOUSESTATE2::rgbButtons) && m_controls.ms2.rgbButtons[b] & 0x80);
}
return false;
@ -208,7 +303,8 @@ LONG JoystickDevice::GetAxis(int a)
JoystickDevice::~JoystickDevice()
{
if (m_device) {
if (m_device)
{
m_device->Unacquire();
m_device->Release();
}
@ -251,7 +347,8 @@ void RemoveInputMap(int port, int cid)
bool GetInputMap(int port, int cid, InputMapped& im)
{
auto it = g_Controls[port].find(cid);
if (it != g_Controls[port].end()) {
if (it != g_Controls[port].end())
{
im = it->second;
return true;
}
@ -266,7 +363,8 @@ void CreateFFB(int port, LPDIRECTINPUTDEVICE8 device, DWORD axis)
if (!device)
return;
try {
try
{
rgdwAxes[0] = axis;
//LPDIRECTINPUTDEVICE8 device = joy->GetDevice();
//create the constant force effect
@ -324,7 +422,9 @@ void CreateFFB(int port, LPDIRECTINPUTDEVICE8 device, DWORD axis)
FFB[port] = true;
}
catch (...) {};
catch (...)
{
};
//start the effect
if (g_pEffectConstant[port])
@ -394,7 +494,8 @@ BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
//read all joystick states
void PollDevices()
{
for (auto& joy : g_pJoysticks) {
for (auto& joy : g_pJoysticks)
{
joy->Poll();
}
}
@ -420,12 +521,15 @@ float FilterControl(float input, LONG linear, LONG offset, LONG dead)
v = (v * (1.0f + (d * 2.0f))) - d;
//clamp
if (v < 0.0f) v = 0.0f;
if (v > 1.0f) v = 1.0f;
if (v < 0.0f)
v = 0.0f;
if (v > 1.0f)
v = 1.0f;
//clamp negdead
//if (v == -d) v = 0.0;
if (fabs(v + d) < FLT_EPSILON) v = 0.0f;
if (fabs(v + d) < FLT_EPSILON)
v = 0.0f;
//possibilities
float c1 = v - (1.0f - (pow((1.0f - v), (1.0f / hs))));
@ -434,9 +538,12 @@ float FilterControl(float input, LONG linear, LONG offset, LONG dead)
float c4 = ((v - pow(v, (1.0f / hs))));
float res = 0;
if (linear < 0) {
if (linear < 0)
{
res = v - (((1.0f - hs2) * c3) + (hs2 * c4)); //get negative result
} else {
}
else
{
res = v - (((1.0f - hs2) * c1) + (hs2 * c2)); //get positive result
}
@ -477,7 +584,8 @@ float ReadAxis(const InputMapped& im)
retval = value * (1.0f / 65535);
}
if (retval < 0.0f) retval = 0.0f;
if (retval < 0.0f)
retval = 0.0f;
return retval;
}
@ -501,7 +609,8 @@ float ReadAxisFiltered(int port, int cid)
void AutoCenter(LPDIRECTINPUTDEVICE8 device, bool onoff)
{
if (!device) return;
if (!device)
return;
//disable the auto-centering spring.
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
@ -519,7 +628,8 @@ void SetRamp(int port, const ramp& var)
void SetRampVariable(int port, int forceids, const variable& var)
{
if (!FFB[port]) return;
if (!FFB[port])
return;
// one main loop is 2ms, too erratic
effRamp.dwDuration = 2000 * (var.t1 + 1) * 25;
@ -534,7 +644,8 @@ void SetRampVariable(int port, int forceids, const variable& var)
{
cRamp.lStart = (127 - force) * DI_FFNOMINALMAX / 127;
int sign = 1;
if (cRamp.lStart < 0) sign = -1; // pull to force's direction?
if (cRamp.lStart < 0)
sign = -1; // pull to force's direction?
cRamp.lEnd = sign * DI_FFNOMINALMAX * dir;
}
else
@ -585,7 +696,8 @@ void JoystickDeviceFF::SetConstantForce(int level)
if (FFMULTI[m_port][0] > 0)
cfw.lMagnitude *= 1 + FFMULTI[m_port][0];
if(g_pEffectConstant[m_port]) {
if (g_pEffectConstant[m_port])
{
g_pEffectConstant[m_port]->SetParameters(&eff, DIEP_TYPESPECIFICPARAMS | DIEP_START);
//DWORD flags;
@ -690,7 +802,8 @@ void JoystickDeviceFF::SetAutoCenter(int value)
void FreeDirectInput()
{
if (!refCount || --refCount > 0) return;
if (!refCount || --refCount > 0)
return;
ReleaseFFB(0);
ReleaseFFB(1);
@ -750,7 +863,8 @@ HRESULT InitDirectInput( HWND hWindow, int port )
g_pDI->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY);
//loop through all attached joysticks
for (size_t i = 0; i < g_pJoysticks.size(); i++) {
for (size_t i = 0; i < g_pJoysticks.size(); i++)
{
auto joy = g_pJoysticks[i];
auto device = joy->GetDevice();
OSDebugOut(_T("DINPUT: SetDataFormat Joystick %s\n"), joy->Product().c_str());
@ -760,7 +874,8 @@ HRESULT InitDirectInput( HWND hWindow, int port )
diCaps.dwSize = sizeof(DIDEVCAPS);
device->GetCapabilities(&diCaps);
if (diCaps.dwFlags & DIDC_FORCEFEEDBACK) {
if (diCaps.dwFlags & DIDC_FORCEFEEDBACK)
{
OSDebugOut(_T("DINPUT: SetCooperativeLevel Joystick %s\n"), joy->Product().c_str());
//Exclusive
device->SetCooperativeLevel(hWindow, DISCL_EXCLUSIVE | DISCL_BACKGROUND);
@ -786,7 +901,6 @@ HRESULT InitDirectInput( HWND hWindow, int port )
didDIinit = true;
return S_OK;
}
HWND GetWindowHandle(DWORD tPID)
@ -825,7 +939,8 @@ bool FindFFDevice(int port)
device->GetCapabilities(&diCaps);
//has ffb?
if (!FFB[port] && (diCaps.dwFlags & DIDC_FORCEFEEDBACK)) {
if (!FFB[port] && (diCaps.dwFlags & DIDC_FORCEFEEDBACK))
{
//FIXME im.mapped is offset to GetAxisValueFromOffset, compatibility with DIEFFECT::rgdwAxes is questionable after DIJOYSTATE2::rglSlider
CreateFFB(port, device, im.mapped);
@ -845,11 +960,17 @@ bool FindFFDevice(int port)
//use direct input
void InitDI(int port, const char* dev_type)
{
if(gsWnd) {
if (gsWnd)
{
hWin = gsWnd;
} else {
}
else
{
pid = GetCurrentProcessId();
while(hWin == 0){ hWin = GetWindowHandle(pid);}
while (hWin == 0)
{
hWin = GetWindowHandle(pid);
}
}
InitDirectInput(hWin, port);
@ -869,10 +990,12 @@ bool GetControl(int port, int id)
auto joy = g_pJoysticks[im.index];
if (im.type == MT_AXIS) {
if (im.type == MT_AXIS)
{
return ReadAxisFiltered(port, id) >= 0.5f;
}
else if (im.type == MT_BUTTON) {
else if (im.type == MT_BUTTON)
{
return joy->GetButton(im.mapped);
}
return false;
@ -883,12 +1006,18 @@ float GetAxisControl(int port, ControlID id)
if (id == CID_STEERING)
{
//apply steering, single axis is split to two for filtering
if (ReadAxisFiltered(port, CID_STEERING) > 0.0) {
if (ReadAxisFiltered(port, CID_STEERING) > 0.0)
{
return -ReadAxisFiltered(port, CID_STEERING);
} else {
if (ReadAxisFiltered(port, CID_STEERING_R) > 0.0) {
}
else
{
if (ReadAxisFiltered(port, CID_STEERING_R) > 0.0)
{
return ReadAxisFiltered(port, CID_STEERING_R);
} else {
}
else
{
return 0;
}
}
@ -901,7 +1030,8 @@ float GetAxisControl(int port, ControlID id)
void SetConstantForce(int port, LONG magnitude)
{
OSDebugOut(TEXT("constant force: %d\n"), magnitude);
if (!FFB[port]) return;
if (!FFB[port])
return;
if (INVERTFORCES[port])
cfw.lMagnitude = -magnitude;
@ -931,12 +1061,13 @@ void TestForce(int port)
Sleep(500);
SetConstantForce(port, 0);
if (dev) { //FIXME actually center, maybe
if (dev)
{ //FIXME actually center, maybe
AutoCenter(dev, true);
Sleep(1500);
AutoCenter(dev, false);
}
}
}} //namespace
} // namespace dx
} // namespace usb_pad

View File

@ -33,7 +33,10 @@
#define DINPUT_AXES_COUNT 32
namespace usb_pad { namespace dx {
namespace usb_pad
{
namespace dx
{
extern int32_t BYPASSCAL;
@ -78,7 +81,10 @@ enum ControlID
class JoystickDeviceFF : public FFDevice
{
public:
JoystickDeviceFF(int port): m_port(port) {}
JoystickDeviceFF(int port)
: m_port(port)
{
}
~JoystickDeviceFF() {}
void SetConstantForce(int level);
@ -170,12 +176,14 @@ public:
ControlType GetControlType() { return m_type; }
~JoystickDevice();
private:
GUID m_guid;
TSTDSTRING m_product;
LPDIRECTINPUTDEVICE8 m_device;
ControlType m_type = CT_NONE;
union {
union
{
DIJOYSTATE2 js2;
DIMOUSESTATE2 ms2;
BYTE kbd[256];
@ -207,4 +215,5 @@ void AddInputMap(int port, int cid, const InputMapped& im);
void RemoveInputMap(int port, int cid);
bool GetInputMap(int port, int cid, InputMapped& im);
}} //namespace
} // namespace dx
} // namespace usb_pad

View File

@ -17,7 +17,10 @@
#include "dx.h"
#include <cmath>
namespace usb_pad { namespace dx {
namespace usb_pad
{
namespace dx
{
static bool bdown = false;
static DWORD calibrationtime = 0;
@ -41,9 +44,12 @@ int DInputPad::TokenIn(uint8_t *buf, int len)
PollDevices();
if (mType == WT_BUZZ_CONTROLLER) {
for (int i = 0; i < 20; i++) {
if (GetControl(mPort, i)) {
if (mType == WT_BUZZ_CONTROLLER)
{
for (int i = 0; i < 20; i++)
{
if (GetControl(mPort, i))
{
mWheelData.buttons |= 1 << i;
}
}
@ -55,40 +61,59 @@ int DInputPad::TokenIn(uint8_t *buf, int len)
//if(idx == 0){
//mWheelData.steering = 8191 + (int)(GetControl(STEERING, false)* 8191.0f) ;
if(calibrating){
if (calibrating)
{
//Alternate full extents
if (alternate)calidata--;
else calidata++;
if (alternate)
calidata--;
else
calidata++;
if(calidata>range-1 || calidata < 1) alternate = !alternate; //invert
if (calidata > range - 1 || calidata < 1)
alternate = !alternate; //invert
mWheelData.steering = calidata; //pass fake
//breakout after 11 seconds
if(GetTickCount()-calibrationtime > 11000){
if (GetTickCount() - calibrationtime > 11000)
{
calibrating = false;
mWheelData.steering = range >> 1;
}
}else{
}
else
{
mWheelData.steering = (range >> 1) + std::lround(GetAxisControl(mPort, CID_STEERING) * (float)(range >> 1));
}
mWheelData.throttle = std::lround(255.f - (GetAxisControl(mPort, CID_THROTTLE) * 255.0f));
mWheelData.brake = std::lround(255.f - (GetAxisControl(mPort, CID_BRAKE) * 255.0f));
if(GetControl(mPort, CID_CROSS)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_CROSS);
if(GetControl(mPort, CID_SQUARE)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_SQUARE);
if(GetControl(mPort, CID_CIRCLE)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_CIRCLE);
if(GetControl(mPort, CID_TRIANGLE)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_TRIANGLE);
if(GetControl(mPort, CID_R1)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_R1);
if(GetControl(mPort, CID_L1)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_L1);
if(GetControl(mPort, CID_R2)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_R2);
if(GetControl(mPort, CID_L2)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_L2);
if (GetControl(mPort, CID_CROSS))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_CROSS);
if (GetControl(mPort, CID_SQUARE))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_SQUARE);
if (GetControl(mPort, CID_CIRCLE))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_CIRCLE);
if (GetControl(mPort, CID_TRIANGLE))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_TRIANGLE);
if (GetControl(mPort, CID_R1))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_R1);
if (GetControl(mPort, CID_L1))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_L1);
if (GetControl(mPort, CID_R2))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_R2);
if (GetControl(mPort, CID_L2))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_L2);
if(GetControl(mPort, CID_SELECT)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_SELECT);
if(GetControl(mPort, CID_START)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_START);
if(GetControl(mPort, CID_R3)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_R3);
if(GetControl(mPort, CID_L3)) mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_L3);
if (GetControl(mPort, CID_SELECT))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_SELECT);
if (GetControl(mPort, CID_START))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_START);
if (GetControl(mPort, CID_R3))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_R3);
if (GetControl(mPort, CID_L3))
mWheelData.buttons |= 1 << convert_wt_btn(mType, PAD_L3);
//diagonal
if (GetControl(mPort, CID_HATUP) && GetControl(mPort, CID_HATRIGHT))
@ -101,7 +126,8 @@ int DInputPad::TokenIn(uint8_t *buf, int len)
mWheelData.hatswitch = 7;
//regular
if(mWheelData.hatswitch==0x8){
if (mWheelData.hatswitch == 0x8)
{
if (GetControl(mPort, CID_HATUP))
mWheelData.hatswitch = 0;
if (GetControl(mPort, CID_HATRIGHT))
@ -141,4 +167,5 @@ int DInputPad::Close()
return 0;
}
}} //namespace
} // namespace dx
} // namespace usb_pad

View File

@ -16,14 +16,21 @@
#include "../padproxy.h"
#include "../../Win32/Config.h"
namespace usb_pad { namespace dx {
namespace usb_pad
{
namespace dx
{
static const char* APINAME = "dinput";
class DInputPad : public Pad
{
public:
DInputPad(int port, const char* dev_type) : Pad(port, dev_type), mUseRamp(0){}
DInputPad(int port, const char* dev_type)
: Pad(port, dev_type)
, mUseRamp(0)
{
}
~DInputPad();
int Open();
int Close();
@ -37,8 +44,10 @@ public:
}
static int Configure(int port, const char* dev_type, void* data);
private:
int32_t mUseRamp;
};
}} //namespace
} // namespace dx
} // namespace usb_pad

View File

@ -20,43 +20,55 @@
#include <cerrno>
#include <cstring>
namespace usb_pad { namespace evdev {
namespace usb_pad
{
namespace evdev
{
#define BITS_TO_UCHAR(x) \
(((x) + 8 * sizeof(unsigned char) - 1) / (8 * sizeof(unsigned char)))
#define testBit(bit, array) ((((uint8_t*)(array))[(bit) / 8] >> ((bit) % 8)) & 1)
EvdevFF::EvdevFF(int fd): mHandle(fd), mUseRumble(false)
EvdevFF::EvdevFF(int fd)
: mHandle(fd)
, mUseRumble(false)
{
unsigned char features[BITS_TO_UCHAR(FF_MAX)];
if (ioctl(mHandle, EVIOCGBIT(EV_FF, sizeof(features)), features) < 0) {
if (ioctl(mHandle, EVIOCGBIT(EV_FF, sizeof(features)), features) < 0)
{
OSDebugOut("Get features failed: %s\n", strerror(errno));
}
int effects = 0;
if (ioctl(mHandle, EVIOCGEFFECTS, &effects) < 0) {
if (ioctl(mHandle, EVIOCGEFFECTS, &effects) < 0)
{
OSDebugOut("Get effects failed: %s\n", strerror(errno));
}
if (!testBit(FF_CONSTANT, features)) {
if (!testBit(FF_CONSTANT, features))
{
OSDebugOut("device does not support FF_CONSTANT\n");
if (testBit(FF_RUMBLE, features))
mUseRumble = true;
}
if (!testBit(FF_SPRING, features)) {
if (!testBit(FF_SPRING, features))
{
OSDebugOut("device does not support FF_SPRING\n");
}
if (!testBit(FF_DAMPER, features)) {
if (!testBit(FF_DAMPER, features))
{
OSDebugOut("device does not support FF_DAMPER\n");
}
if (!testBit(FF_GAIN, features)) {
if (!testBit(FF_GAIN, features))
{
OSDebugOut("device does not support FF_GAIN\n");
}
if (!testBit(FF_AUTOCENTER, features)) {
if (!testBit(FF_AUTOCENTER, features))
{
OSDebugOut("device does not support FF_AUTOCENTER\n");
}
@ -85,7 +97,8 @@ EvdevFF::~EvdevFF()
{
for (int i = 0; i < countof(mEffIds); i++)
{
if (mEffIds[i] != -1 && ioctl(mHandle, EVIOCRMFF, mEffIds[i]) == -1) {
if (mEffIds[i] != -1 && ioctl(mHandle, EVIOCRMFF, mEffIds[i]) == -1)
{
OSDebugOut("Failed to unload EffectID(%d) effect.\n", i);
}
}
@ -97,7 +110,8 @@ void EvdevFF::DisableForce(EffectID force)
play.type = EV_FF;
play.code = mEffIds[force];
play.value = 0;
if (write(mHandle, (const void*) &play, sizeof(play)) == -1) {
if (write(mHandle, (const void*)&play, sizeof(play)) == -1)
{
OSDebugOut("Stop effect failed: %s\n", strerror(errno));
}
}
@ -109,19 +123,23 @@ void EvdevFF::SetConstantForce(/*const parsed_ff_data& ff*/ int level)
play.value = 1;
mEffect.u = {};
if (!mUseRumble) {
if (!mUseRumble)
{
mEffect.type = FF_CONSTANT;
mEffect.id = mEffIds[EFF_CONSTANT];
mEffect.u.constant.level = /*ff.u.constant.*/ level;
OSDebugOut("Constant force: %d\n", level);
if (ioctl(mHandle, EVIOCSFF, &(mEffect)) < 0) {
if (ioctl(mHandle, EVIOCSFF, &(mEffect)) < 0)
{
OSDebugOut("Failed to upload constant effect: %s\n", strerror(errno));
return;
}
play.code = mEffect.id;
mEffIds[EFF_CONSTANT] = mEffect.id;
} else {
}
else
{
mEffect.type = FF_RUMBLE;
mEffect.id = mEffIds[EFF_RUMBLE];
@ -142,7 +160,8 @@ void EvdevFF::SetConstantForce(/*const parsed_ff_data& ff*/ int level)
mLastValue = mag;
if (ioctl(mHandle, EVIOCSFF, &(mEffect)) < 0) {
if (ioctl(mHandle, EVIOCSFF, &(mEffect)) < 0)
{
OSDebugOut("Failed to upload constant effect: %s\n", strerror(errno));
return;
}
@ -150,10 +169,10 @@ void EvdevFF::SetConstantForce(/*const parsed_ff_data& ff*/ int level)
mEffIds[EFF_RUMBLE] = mEffect.id;
}
if (write(mHandle, (const void*) &play, sizeof(play)) == -1) {
if (write(mHandle, (const void*)&play, sizeof(play)) == -1)
{
OSDebugOut("Play effect failed: %s\n", strerror(errno));
}
}
void EvdevFF::SetSpringForce(const parsed_ff_data& ff)
@ -176,7 +195,8 @@ void EvdevFF::SetSpringForce(const parsed_ff_data& ff)
mEffect.u.condition[0].left_coeff, mEffect.u.condition[0].right_coeff,
mEffect.u.condition[0].left_saturation, mEffect.u.condition[0].right_saturation);
if (ioctl(mHandle, EVIOCSFF, &(mEffect)) < 0) {
if (ioctl(mHandle, EVIOCSFF, &(mEffect)) < 0)
{
OSDebugOut("Failed to upload spring effect: %s\n", strerror(errno));
return;
}
@ -184,7 +204,8 @@ void EvdevFF::SetSpringForce(const parsed_ff_data& ff)
play.code = mEffect.id;
mEffIds[EFF_SPRING] = mEffect.id;
if (write(mHandle, (const void*) &play, sizeof(play)) == -1) {
if (write(mHandle, (const void*)&play, sizeof(play)) == -1)
{
OSDebugOut("Play effect failed: %s\n", strerror(errno));
}
}
@ -207,7 +228,8 @@ void EvdevFF::SetDamperForce(const parsed_ff_data& ff)
OSDebugOut("Damper force: %d/%d\n", mEffect.u.condition[0].left_coeff, mEffect.u.condition[0].right_coeff);
if (ioctl(mHandle, EVIOCSFF, &(mEffect)) < 0) {
if (ioctl(mHandle, EVIOCSFF, &(mEffect)) < 0)
{
OSDebugOut("Failed to upload damper effect: %s\n", strerror(errno));
return;
}
@ -215,7 +237,8 @@ void EvdevFF::SetDamperForce(const parsed_ff_data& ff)
play.code = mEffect.id;
mEffIds[EFF_DAMPER] = mEffect.id;
if (write(mHandle, (const void*) &play, sizeof(play)) == -1) {
if (write(mHandle, (const void*)&play, sizeof(play)) == -1)
{
OSDebugOut("Play effect failed: %s\n", strerror(errno));
}
}
@ -237,7 +260,8 @@ void EvdevFF::SetFrictionForce(const parsed_ff_data& ff)
mEffect.u.condition[0].deadband = ff.u.condition.deadband;
OSDebugOut("Friction force: %d/%d\n", mEffect.u.condition[0].left_coeff, mEffect.u.condition[0].right_coeff);
if (ioctl(mHandle, EVIOCSFF, &(mEffect)) < 0) {
if (ioctl(mHandle, EVIOCSFF, &(mEffect)) < 0)
{
OSDebugOut("Failed to upload friction effect: %s\n", strerror(errno));
return;
}
@ -245,7 +269,8 @@ void EvdevFF::SetFrictionForce(const parsed_ff_data& ff)
play.code = mEffect.id;
mEffIds[EFF_FRICTION] = mEffect.id;
if (write(mHandle, (const void*) &play, sizeof(play)) == -1) {
if (write(mHandle, (const void*)&play, sizeof(play)) == -1)
{
OSDebugOut("Play effect failed: %s\n", strerror(errno));
}
}
@ -276,4 +301,5 @@ void EvdevFF::SetGain(int gain /* between 0 and 100 */)
OSDebugOut("Failed to set gain: %s\n", strerror(errno));
}
}} //namespace
} // namespace evdev
} // namespace usb_pad

View File

@ -19,7 +19,10 @@
#include <linux/input.h>
#include "../usb-pad.h"
namespace usb_pad { namespace evdev {
namespace usb_pad
{
namespace evdev
{
class EvdevFF : public FFDevice
{
@ -44,5 +47,6 @@ private:
int mLastValue;
};
}} //namespace
} // namespace evdev
} // namespace usb_pad
#endif

View File

@ -22,7 +22,10 @@
#include <sstream>
#include "../../gtk.h"
namespace usb_pad { namespace evdev {
namespace usb_pad
{
namespace evdev
{
using sys_clock = std::chrono::system_clock;
using ms = std::chrono::milliseconds;
@ -562,8 +565,10 @@ static bool GetEventName(const char *dev_type, int map, int event, const char **
if (!name)
return false;
if (map < JOY_STEERING || !strcmp(dev_type, BuzzDevice::TypeName())) {
if (event < key_to_str.size()) {
if (map < JOY_STEERING || !strcmp(dev_type, BuzzDevice::TypeName()))
{
if (event < key_to_str.size())
{
*name = key_to_str[event];
return true;
}
@ -582,7 +587,11 @@ static bool PollInput(const std::vector<std::pair<std::string, ConfigMapping> >&
int event_fd = -1, t;
ssize_t len;
input_event event;
struct AxisValue { int16_t value; bool initial; };
struct AxisValue
{
int16_t value;
bool initial;
};
AxisValue axisVal[ABS_MAX + 1]{};
unsigned long absbit[NBITS(ABS_MAX)]{};
struct axis_correct abs_correct[ABS_MAX]{};
@ -593,9 +602,11 @@ static bool PollInput(const std::vector<std::pair<std::string, ConfigMapping> >&
int maxfd = -1;
FD_ZERO(&fdset);
for (const auto& js: fds) {
for (const auto& js : fds)
{
FD_SET(js.second.fd, &fdset);
if (maxfd < js.second.fd) maxfd = js.second.fd;
if (maxfd < js.second.fd)
maxfd = js.second.fd;
}
// wait to avoid some false positives like mouse movement
@ -603,22 +614,27 @@ static bool PollInput(const std::vector<std::pair<std::string, ConfigMapping> >&
// empty event queues
for (const auto& js : fds)
while ((len = read(js.second.fd, &event, sizeof(event))) > 0);
while ((len = read(js.second.fd, &event, sizeof(event))) > 0)
;
struct timeval timeout {};
struct timeval timeout
{
};
timeout.tv_sec = 5;
int result = select(maxfd + 1, &fdset, NULL, NULL, &timeout);
if (!result)
return false;
if (result == -1) {
if (result == -1)
{
return false;
}
for (const auto& js : fds)
{
if (FD_ISSET(js.second.fd, &fdset)) {
if (FD_ISSET(js.second.fd, &fdset))
{
event_fd = js.second.fd;
dev_name = js.first;
break;
@ -628,12 +644,16 @@ static bool PollInput(const std::vector<std::pair<std::string, ConfigMapping> >&
if (event_fd == -1)
return false;
if (isaxis && ioctl(event_fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) {
for (int i = 0; i < ABS_MAX; ++i) {
if (test_bit(i, absbit)) {
if (isaxis && ioctl(event_fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0)
{
for (int i = 0; i < ABS_MAX; ++i)
{
if (test_bit(i, absbit))
{
struct input_absinfo absinfo;
if (ioctl(event_fd, EVIOCGABS(i), &absinfo) < 0) {
if (ioctl(event_fd, EVIOCGABS(i), &absinfo) < 0)
{
continue;
}
@ -649,13 +669,16 @@ static bool PollInput(const std::vector<std::pair<std::string, ConfigMapping> >&
while (true)
{
auto dur = std::chrono::duration_cast<ms>(sys_clock::now() - last).count();
if (dur > 5000) goto error;
if (dur > 5000)
goto error;
if (!isaxis) {
if (!isaxis)
{
event_fd = -1;
for (const auto& js : fds)
{
if (FD_ISSET(js.second.fd, &fdset)) {
if (FD_ISSET(js.second.fd, &fdset))
{
event_fd = js.second.fd;
dev_name = js.first;
@ -733,4 +756,5 @@ int EvDevPad::Configure(int port, const char* dev_type, void *data)
}
#undef EVDEV_DIR
}} //namespace
} // namespace evdev
} // namespace usb_pad

View File

@ -20,7 +20,10 @@
#include <linux/hidraw.h>
#include "../../linux/util.h"
namespace usb_pad { namespace evdev {
namespace usb_pad
{
namespace evdev
{
// hidraw* to input/event*:
// /sys/class/hidraw/hidraw*/device/input/input*/event*/uevent
@ -52,22 +55,26 @@ bool FindHidraw(const std::string &evphys, std::string& hid_dev, int *vid, int *
struct dirent* dp;
DIR* dirp = opendir("/dev/");
if (!dirp) {
if (!dirp)
{
perror("Error opening /dev/");
return false;
}
while ((dp = readdir(dirp)))
{
if(strncmp(dp->d_name, "hidraw", 6) == 0) {
if (strncmp(dp->d_name, "hidraw", 6) == 0)
{
OSDebugOut("%s\n", dp->d_name);
str.clear(); str.str("");
str.clear();
str.str("");
str << "/dev/" << dp->d_name;
std::string path = str.str();
fd = open(path.c_str(), O_RDWR | O_NONBLOCK);
if (fd < 0) {
if (fd < 0)
{
perror("Unable to open device");
continue;
}
@ -84,15 +91,21 @@ bool FindHidraw(const std::string &evphys, std::string& hid_dev, int *vid, int *
struct hidraw_devinfo info;
memset(&info, 0x0, sizeof(info));
if (ioctl(fd, HIDIOCGRAWINFO, &info) < 0) {
if (ioctl(fd, HIDIOCGRAWINFO, &info) < 0)
{
perror("HIDIOCGRAWINFO");
} else {
if (vid) *vid = info.vendor;
if (pid) *pid = info.product;
}
else
{
if (vid)
*vid = info.vendor;
if (pid)
*pid = info.product;
}
close(fd);
if (evphys == buf) {
if (evphys == buf)
{
closedir(dirp);
hid_dev = path;
return true;
@ -118,13 +131,15 @@ void EnumerateDevices(vstring& list)
static vstring list_cache;
DIR* dirp = opendir(EVDEV_DIR);
if (!dirp) {
if (!dirp)
{
perror("Error opening " EVDEV_DIR);
return;
}
// get rid of unplugged devices
for (int i=0; i < list_cache.size(); ) {
for (int i = 0; i < list_cache.size();)
{
if (!file_exists(list_cache[i].second))
list_cache.erase(list_cache.begin() + i);
else
@ -134,13 +149,12 @@ void EnumerateDevices(vstring& list)
while ((dp = readdir(dirp)))
{
//if (strncmp(dp->d_name, "event", 5) == 0) {
if (str_ends_with(dp->d_name, "event-kbd")
|| str_ends_with(dp->d_name, "event-mouse")
|| str_ends_with(dp->d_name, "event-joystick"))
if (str_ends_with(dp->d_name, "event-kbd") || str_ends_with(dp->d_name, "event-mouse") || str_ends_with(dp->d_name, "event-joystick"))
{
OSDebugOut(EVDEV_DIR "%s\n", dp->d_name);
str.clear(); str.str("");
str.clear();
str.str("");
str << EVDEV_DIR << dp->d_name;
std::string path = str.str();
@ -153,7 +167,8 @@ void EnumerateDevices(vstring& list)
fd = open(path.c_str(), O_RDWR | O_NONBLOCK);
if (fd < 0) {
if (fd < 0)
{
perror("Unable to open device");
continue;
}
@ -183,11 +198,13 @@ void EvDevPad::PollAxesValues(const device_data& device)
struct input_absinfo absinfo;
/* Poll all axis */
for (int i = ABS_X; i < ABS_MAX; i++) {
for (int i = ABS_X; i < ABS_MAX; i++)
{
absinfo = {};
if ((ioctl(device.cfg.fd, EVIOCGABS(i), &absinfo) >= 0) &&
device.abs_correct[i].used) {
device.abs_correct[i].used)
{
absinfo.value = AxisCorrect(device.abs_correct[i], absinfo.value);
}
SetAxis(device, i, absinfo.value);
@ -203,7 +220,9 @@ void EvDevPad::SetAxis(const device_data& device, int event_code, int value)
switch (code)
{
case 0x80 | JOY_STEERING:
case ABS_X: mWheelData.steering = device.cfg.inverted[0] ? range - NORM(value, range) : NORM(value, range); break;
case ABS_X:
mWheelData.steering = device.cfg.inverted[0] ? range - NORM(value, range) : NORM(value, range);
break;
//case ABS_Y: mWheelData.clutch = NORM(value, 0xFF); break; //no wheel on PS2 has one, afaik
//case ABS_RX: mWheelData.axis_rx = NORM(event.value, 0xFF); break;
case ABS_RY:
@ -255,7 +274,8 @@ void EvDevPad::SetAxis(const device_data& device, int event_code, int value)
else
mWheelData.hat_vert = PAD_HAT_COUNT;
break;
default: break;
default:
break;
}
}
@ -270,22 +290,26 @@ int EvDevPad::TokenIn(uint8_t *buf, int buflen)
FD_ZERO(&fds);
maxfd = -1;
for (auto& device: mDevices) {
for (auto& device : mDevices)
{
FD_SET(device.cfg.fd, &fds);
if (maxfd < device.cfg.fd) maxfd = device.cfg.fd;
if (maxfd < device.cfg.fd)
maxfd = device.cfg.fd;
}
struct timeval timeout;
timeout.tv_usec = timeout.tv_sec = 0; // 0 - return from select immediately
int result = select(maxfd + 1, &fds, NULL, NULL, &timeout);
if (result <= 0) {
if (result <= 0)
{
return USB_RET_NAK; // If no new data, NAK it
}
for (auto& device : mDevices)
{
if (!FD_ISSET(device.cfg.fd, &fds)) {
if (!FD_ISSET(device.cfg.fd, &fds))
{
continue;
}
@ -318,9 +342,11 @@ int EvDevPad::TokenIn(uint8_t *buf, int buflen)
OSDebugOut("%s Button: 0x%02x, mapped: 0x%02x, val: %d\n",
device.name.c_str(), event.code, device.btn_map[event.code], event.value);
if (mType == WT_BUZZ_CONTROLLER) {
if (mType == WT_BUZZ_CONTROLLER)
{
OSDebugOut("evdev buzz: code: %d, map: %08x\n", event.code, device.btn_map[event.code]);
if (device.btn_map[event.code] != (uint16_t)-1) {
if (device.btn_map[event.code] != (uint16_t)-1)
{
if (event.value)
mWheelData.buttons |= 1 << (code & ~0x8000); //on
else
@ -358,16 +384,36 @@ int EvDevPad::TokenIn(uint8_t *buf, int buflen)
case 0x8000 | JOY_DOWN:
mWheelData.hat_vert = (!event.value ? PAD_HAT_COUNT : PAD_HAT_S);
break;
case BTN_WEST: button = PAD_SQUARE; break;
case BTN_NORTH: button = PAD_TRIANGLE; break;
case BTN_EAST: button = PAD_CIRCLE; break;
case BTN_SOUTH: button = PAD_CROSS; break;
case BTN_SELECT: button = PAD_SELECT; break;
case BTN_START: button = PAD_START; break;
case BTN_TR: button = PAD_R1; break;
case BTN_TL: button = PAD_L1; break;
case BTN_THUMBR: button = PAD_R2; break;
case BTN_THUMBL: button = PAD_L2; break;
case BTN_WEST:
button = PAD_SQUARE;
break;
case BTN_NORTH:
button = PAD_TRIANGLE;
break;
case BTN_EAST:
button = PAD_CIRCLE;
break;
case BTN_SOUTH:
button = PAD_CROSS;
break;
case BTN_SELECT:
button = PAD_SELECT;
break;
case BTN_START:
button = PAD_START;
break;
case BTN_TR:
button = PAD_R1;
break;
case BTN_TL:
button = PAD_L1;
break;
case BTN_THUMBR:
button = PAD_R2;
break;
case BTN_THUMBL:
button = PAD_L2;
break;
default:
OSDebugOut("Unmapped Button: %d, %d\n", code, event.value);
break;
@ -385,7 +431,8 @@ int EvDevPad::TokenIn(uint8_t *buf, int buflen)
break;
case EV_SYN: //TODO useful?
{
switch(event.code) {
switch (event.code)
{
case SYN_DROPPED:
//restore last good state
mWheelData = {};
@ -412,17 +459,29 @@ int EvDevPad::TokenIn(uint8_t *buf, int buflen)
case PAD_HAT_N:
switch (mWheelData.hat_horz)
{
case PAD_HAT_W: mWheelData.hatswitch = PAD_HAT_NW; break;
case PAD_HAT_E: mWheelData.hatswitch = PAD_HAT_NE; break;
default: mWheelData.hatswitch = PAD_HAT_N; break;
case PAD_HAT_W:
mWheelData.hatswitch = PAD_HAT_NW;
break;
case PAD_HAT_E:
mWheelData.hatswitch = PAD_HAT_NE;
break;
default:
mWheelData.hatswitch = PAD_HAT_N;
break;
}
break;
case PAD_HAT_S:
switch (mWheelData.hat_horz)
{
case PAD_HAT_W: mWheelData.hatswitch = PAD_HAT_SW; break;
case PAD_HAT_E: mWheelData.hatswitch = PAD_HAT_SE; break;
default: mWheelData.hatswitch = PAD_HAT_S; break;
case PAD_HAT_W:
mWheelData.hatswitch = PAD_HAT_SW;
break;
case PAD_HAT_E:
mWheelData.hatswitch = PAD_HAT_SE;
break;
default:
mWheelData.hatswitch = PAD_HAT_S;
break;
}
break;
default:
@ -436,12 +495,14 @@ int EvDevPad::TokenIn(uint8_t *buf, int buflen)
int EvDevPad::TokenOut(const uint8_t* data, int len)
{
if (mUseRawFF) {
if (mUseRawFF)
{
OSDebugOut("FF: %02x %02x %02x %02x %02x %02x %02x\n",
data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
if (data[0] == 0x8 || data[0] == 0xB) return len;
if (data[0] == 0x8 || data[0] == 0xB)
return len;
if (data[0] == 0xF8 &&
/* Allow range changes */
!(data[1] == 0x81 || data[1] == 0x02 || data[1] == 0x03))
@ -451,7 +512,8 @@ int EvDevPad::TokenOut(const uint8_t *data, int len)
memcpy(report.data() + 1, data, report.size() - 1);
if (!mFFData.enqueue(report)) {
if (!mFFData.enqueue(report))
{
OSDebugOut("Failed to enqueue ffb command\n");
return 0;
}
@ -494,7 +556,8 @@ int EvDevPad::Open()
std::string evphys, hid_dev;
switch(mType) {
switch (mType)
{
case WT_GENERIC:
case WT_GT_FORCE:
case WT_DRIVING_FORCE_PRO:
@ -507,10 +570,12 @@ int EvDevPad::Open()
break;
}
if (mUseRawFF) {
if (mUseRawFF)
{
// TODO could just use device fd below whose axis is mapped to steering
std::string joypath;
if (!LoadSetting(mDevType, mPort, APINAME, N_JOYSTICK, joypath)) {
if (!LoadSetting(mDevType, mPort, APINAME, N_JOYSTICK, joypath))
{
OSDebugOut("Cannot load device setting: %s\n", N_JOYSTICK);
return 1;
}
@ -526,18 +591,21 @@ int EvDevPad::Open()
}
memset(buf, 0, sizeof(buf));
if (ioctl(fd, EVIOCGPHYS(sizeof(buf) - 1), buf) > 0) {
if (ioctl(fd, EVIOCGPHYS(sizeof(buf) - 1), buf) > 0)
{
evphys = buf;
OSDebugOut("Evdev Phys: %s\n", evphys.c_str());
int pid, vid;
if ((mUseRawFF = FindHidraw(evphys, hid_dev, &vid, &pid))) {
if ((mUseRawFF = FindHidraw(evphys, hid_dev, &vid, &pid)))
{
// For safety, only allow Logitech (classic ffb) devices
if (vid != 0x046D /* Logitech */ /*|| info.bustype != BUS_USB*/
|| pid == 0xc262 /* G920 hid mode */
|| pid == 0xc261 /* G920 xbox mode */
) {
)
{
mUseRawFF = 0;
}
@ -549,7 +617,9 @@ int EvDevPad::Open()
mWriterThread = std::thread(EvDevPad::WriterThread, this);
}
}
} else {
}
else
{
perror("EVIOCGPHYS failed");
}
close(fd);
@ -576,7 +646,8 @@ int EvDevPad::Open()
memset(device.axis_map, 0xFF, sizeof(device.axis_map));
memset(device.btn_map, 0xFF, sizeof(device.btn_map));
if ((ret_abs < 0) && (ret_key < 0)) {
if ((ret_abs < 0) && (ret_key < 0))
{
// Probably isn't a evdev joystick
SysMessage("%s: Getting atleast some of the bits failed: %s\n", APINAME, strerror(errno));
continue;
@ -590,7 +661,8 @@ int EvDevPad::Open()
}*/
int max_buttons = JOY_STEERING;
switch(mType) {
switch (mType)
{
case WT_BUZZ_CONTROLLER:
LoadBuzzMappings(mDevType, mPort, device.name, device.cfg);
max_buttons = 20;
@ -602,16 +674,20 @@ int EvDevPad::Open()
// Map hatswitches automatically
//FIXME has_mappings is gonna ignore hatsw only devices
for (int i = ABS_HAT0X; i <= ABS_HAT3Y; ++i) {
for (int i = ABS_HAT0X; i <= ABS_HAT3Y; ++i)
{
device.axis_map[i] = i;
}
// SDL2
for (int i = 0; i < ABS_MAX; ++i) {
if (test_bit(i, absbit)) {
for (int i = 0; i < ABS_MAX; ++i)
{
if (test_bit(i, absbit))
{
struct input_absinfo absinfo;
if (ioctl(device.cfg.fd, EVIOCGABS(i), &absinfo) < 0) {
if (ioctl(device.cfg.fd, EVIOCGABS(i), &absinfo) < 0)
{
continue;
}
@ -623,7 +699,8 @@ int EvDevPad::Open()
CalcAxisCorr(device.abs_correct[i], absinfo);
//TODO joystick/gamepad is dual analog?
if (i == ABS_RZ) {
if (i == ABS_RZ)
{
//absinfo.value = AxisCorrect(mAbsCorrect[i], absinfo.value);
if (std::abs(absinfo.value) < 200) /* 200 is random, allows for some dead zone */
device.is_dualanalog = true;
@ -632,7 +709,8 @@ int EvDevPad::Open()
// FIXME axes as buttons
for (int k = max_buttons /*JOY_STEERING*/; k < JOY_MAPS_COUNT; k++)
{
if (i == device.cfg.controls[k]) {
if (i == device.cfg.controls[k])
{
has_mappings = true;
device.axis_map[i] = 0x80 | k;
// TODO Instead of single FF instance, create for every device with X-axis???
@ -645,22 +723,28 @@ int EvDevPad::Open()
}
#ifndef NDEBUG
for(int i = 0; i < ABS_MAX; ++i) {
for (int i = 0; i < ABS_MAX; ++i)
{
if (device.axis_map[i] != (uint8_t)-1 && (device.axis_map[i] & 0x80))
OSDebugOut("Axis: 0x%02x -> %s\n", i, JoystickMapNames[device.axis_map[i] & ~0x80]);
}
#endif
for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
if (test_bit(i, keybit)) {
for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i)
{
if (test_bit(i, keybit))
{
//OSDebugOut("Device has button: 0x%x\n", i);
device.btn_map[i] = -1; //device.buttons;
if (i == BTN_GAMEPAD) {
if (i == BTN_GAMEPAD)
{
device.is_gamepad = true;
OSDebugOut("Device is a gamepad\n");
}
for (int k = 0; k < max_buttons; k++) {
if (i == device.cfg.controls[k]) {
for (int k = 0; k < max_buttons; k++)
{
if (i == device.cfg.controls[k])
{
has_mappings = true;
device.btn_map[i] = 0x8000 | k;
OSDebugOut("Remap button: 0x%x -> %s\n", i, JoystickMapNames[k]);
@ -668,19 +752,24 @@ int EvDevPad::Open()
}
}
}
for (int i = 0; i < BTN_JOYSTICK; ++i) {
if (test_bit(i, keybit)) {
for (int i = 0; i < BTN_JOYSTICK; ++i)
{
if (test_bit(i, keybit))
{
OSDebugOut("Device has button: 0x%x\n", i);
device.btn_map[i] = -1; //device.buttons;
for (int k = 0; k < max_buttons; k++) {
if (i == device.cfg.controls[k]) {
for (int k = 0; k < max_buttons; k++)
{
if (i == device.cfg.controls[k])
{
has_mappings = true;
device.btn_map[i] = 0x8000 | k;
}
}
}
}
if (!has_mappings) {
if (!has_mappings)
{
OSDebugOut("Device %s [%s] has no mappings, discarding\n", device.name.c_str(), ""); //it.second.c_str());
close(device.cfg.fd);
mDevices.pop_back();
@ -699,7 +788,8 @@ int EvDevPad::Close()
delete mFFdev;
mFFdev = nullptr;
if (mHidHandle != -1) {
if (mHidHandle != -1)
{
uint8_t reset[7] = {0};
reset[0] = 0xF3; //stop forces
write(mHidHandle, reset, sizeof(reset));
@ -707,7 +797,8 @@ int EvDevPad::Close()
}
mHidHandle = -1;
for (auto& it : mDevices) {
for (auto& it : mDevices)
{
close(it.cfg.fd);
it.cfg.fd = -1;
}
@ -728,11 +819,14 @@ void EvDevPad::WriterThread(void *ptr)
if (pad->mFFData.try_dequeue(buf))
{
res = write(pad->mHidHandle, buf.data(), buf.size());
if (res < 0) {
if (res < 0)
{
printf("Error: %d\n", errno);
perror("write");
}
} else { // TODO skip sleep for few while cycles?
}
else
{ // TODO skip sleep for few while cycles?
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
@ -741,4 +835,5 @@ void EvDevPad::WriterThread(void *ptr)
pad->mWriterThreadIsRunning = false;
}
}} //namespace
} // namespace evdev
} // namespace usb_pad

View File

@ -23,7 +23,10 @@
#include "shared.h"
#include "../../readerwriterqueue/readerwriterqueue.h"
namespace usb_pad { namespace evdev {
namespace usb_pad
{
namespace evdev
{
#define test_bit(nr, addr) \
(((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
@ -36,7 +39,8 @@ static const char* APINAME = "evdev";
class EvDevPad : public Pad
{
public:
EvDevPad(int port, const char* dev_type): Pad(port, dev_type)
EvDevPad(int port, const char* dev_type)
: Pad(port, dev_type)
, mUseRawFF(0)
, mHidHandle(-1)
, mWriterThreadIsRunning(false)
@ -56,6 +60,7 @@ public:
}
static int Configure(int port, const char* dev_type, void* data);
protected:
void PollAxesValues(const device_data& device);
void SetAxis(const device_data& device, int code, int value);
@ -97,19 +102,25 @@ static void CalcAxisCorr(axis_correct& abs_correct, struct input_absinfo absinfo
{
int t;
// convert values into 16 bit range
if (absinfo.minimum == absinfo.maximum) {
if (absinfo.minimum == absinfo.maximum)
{
abs_correct.used = 0;
} else {
}
else
{
abs_correct.used = 1;
abs_correct.coef[0] =
(absinfo.maximum + absinfo.minimum) - 2 * absinfo.flat;
abs_correct.coef[1] =
(absinfo.maximum + absinfo.minimum) + 2 * absinfo.flat;
t = ((absinfo.maximum - absinfo.minimum) - 4 * absinfo.flat);
if (t != 0) {
if (t != 0)
{
abs_correct.coef[2] =
(1 << 28) / t;
} else {
}
else
{
abs_correct.coef[2] = 0;
}
}
@ -119,14 +130,19 @@ static void CalcAxisCorr(axis_correct& abs_correct, struct input_absinfo absinfo
// convert values into 16 bit range
static int AxisCorrect(const axis_correct& correct, int value)
{
if (correct.used) {
if (correct.used)
{
value *= 2;
if (value > correct.coef[0]) {
if (value < correct.coef[1]) {
if (value > correct.coef[0])
{
if (value < correct.coef[1])
{
return 0;
}
value -= correct.coef[1];
} else {
}
else
{
value -= correct.coef[0];
}
value *= correct.coef[2];
@ -142,4 +158,5 @@ static int AxisCorrect(const axis_correct& correct, int value)
return value;
}
}} //namespace
} // namespace evdev
} // namespace usb_pad

View File

@ -22,7 +22,10 @@
#include <stdio.h>
#include <sstream>
namespace usb_pad { namespace evdev {
namespace usb_pad
{
namespace evdev
{
using sys_clock = std::chrono::system_clock;
using ms = std::chrono::milliseconds;
@ -55,7 +58,8 @@ bool LoadMappings(const char *dev_type, int port, const std::string& joyname, Co
for (int i = 0; i < 3; i++)
{
str.clear(); str.str("");
str.clear();
str.str("");
str << "inverted_" << JoystickMapNames[JOY_STEERING + i];
{
const std::string& name = str.str();
@ -63,7 +67,8 @@ bool LoadMappings(const char *dev_type, int port, const std::string& joyname, Co
cfg.inverted[i] = 0;
}
str.clear(); str.str("");
str.clear();
str.str("");
str << "initial_" << JoystickMapNames[JOY_STEERING + i];
{
const std::string& name = str.str();
@ -93,7 +98,8 @@ bool SaveMappings(const char *dev_type, int port, const std::string& joyname, co
for (int i = 0; i < 3; i++)
{
str.clear(); str.str("");
str.clear();
str.str("");
str << "inverted_" << JoystickMapNames[JOY_STEERING + i];
{
const std::string& name = str.str();
@ -101,7 +107,8 @@ bool SaveMappings(const char *dev_type, int port, const std::string& joyname, co
return false;
}
str.clear(); str.str("");
str.clear();
str.str("");
str << "initial_" << JoystickMapNames[JOY_STEERING + i];
{
const std::string& name = str.str();
@ -175,7 +182,8 @@ static void refresh_store(ConfigData *cfg)
gtk_list_store_append(cfg->store, &iter);
if (!strcmp(cfg->dev_type, BuzzDevice::TypeName())) {
if (!strcmp(cfg->dev_type, BuzzDevice::TypeName()))
{
std::stringstream ss;
ss << (1 + i / countof(buzz_map_names));
@ -191,7 +199,9 @@ static void refresh_store(ConfigData *cfg)
COL_COLUMN_WIDTH, 50,
COL_BINDING, i,
-1);
} else {
}
else
{
gtk_list_store_set(cfg->store, &iter,
COL_NAME, it.first.c_str(),
COL_PS2, JoystickMapNames[i],
@ -213,7 +223,8 @@ static void joystick_changed (GtkComboBox *widget, gpointer data)
if (!cfg)
return;
if (idx > -1) {
if (idx > -1)
{
std::string name = (cfg->joysticks.begin() + idx)->first;
cfg->js_iter = (cfg->joysticks.begin() + idx);
OSDebugOut("Selected player %d idx: %d dev: '%s'\n", 2 - port, idx, name.c_str());
@ -250,7 +261,8 @@ static void button_clicked (GtkComboBox *widget, gpointer data)
if (it != cfg->jsconf.end() && type < it->second.controls.size())
{
it->second.controls[type] = value;
if (is_axis) {
if (is_axis)
{
it->second.inverted[type - JOY_STEERING] = inverted;
it->second.initial[type - JOY_STEERING] = initial;
}
@ -324,7 +336,8 @@ static void view_remove_binding (GtkTreeModel *model,
[&dev_name](auto i) {
return i.first == dev_name;
});
if (it != js.end()) {
if (it != js.end())
{
it->second.controls[binding] = (uint16_t)-1;
OSDebugOut("Delete binding '%d' for '%s'\n", binding, it->first.c_str());
}
@ -354,7 +367,8 @@ static void clear_binding_clicked (GtkWidget *widget, gpointer data)
GList* list = gtk_tree_selection_get_selected_rows(sel, &model);
// remove rows from store pointed to by row references
for (node = g_list_first(rr_list); node != nullptr; node = node->next) {
for (node = g_list_first(rr_list); node != nullptr; node = node->next)
{
GtkTreePath* path = gtk_tree_row_reference_get_path((GtkTreeRowReference*)node->data);
if (path)
{
@ -384,7 +398,8 @@ static void hidraw_toggled (GtkToggleButton *widget, gpointer data)
{
int port = reinterpret_cast<uintptr_t>(data);
ConfigData* cfg = (ConfigData*)g_object_get_data(G_OBJECT(widget), CFG);
if (cfg) {
if (cfg)
{
cfg->use_hidraw_ff_pt = (bool)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
}
}
@ -407,14 +422,16 @@ int GtkPadConfigure(int port, const char* dev_type, const char *apititle, const
cfg.cb = &apicbs;
cfg.dev_type = dev_type;
for (const auto& it: cfg.joysticks) {
for (const auto& it : cfg.joysticks)
{
if ((fd = open(it.second.c_str(), O_RDONLY | O_NONBLOCK)) < 0)
{
OSDebugOut("Cannot open device: %s\n", it.second.c_str());
continue;
}
ConfigMapping c; c.fd = fd;
ConfigMapping c;
c.fd = fd;
LoadMappings(cfg.dev_type, port, it.first, c);
cfg.jsconf.push_back(std::make_pair(it.first, c));
OSDebugOut("mappings for '%s': %zu\n", it.first.c_str(), c.controls.size());
@ -509,10 +526,20 @@ int GtkPadConfigure(int port, const char* dev_type, const char *apititle, const
GtkAttachOptions opt = (GtkAttachOptions)(GTK_FILL);
const char* button_labels[] = {
"L2", "L1 / L", "R2", "R1 / R / Orange",
"Left", "Up", "Right", "Down",
"Square / X / Green", "Cross / A / Blue", "Circle / B / Red", "Triangle / Y / Yellow",
"Select", "Start",
"L2",
"L1 / L",
"R2",
"R1 / R / Orange",
"Left",
"Up",
"Right",
"Down",
"Square / X / Green",
"Cross / A / Blue",
"Circle / B / Red",
"Triangle / Y / Yellow",
"Select",
"Start",
};
const Point button_pos[] = {
@ -611,7 +638,8 @@ int GtkPadConfigure(int port, const char* dev_type, const char *apititle, const
int ret = RESULT_OK;
if (result == GTK_RESPONSE_OK)
{
if (cfg.js_iter != cfg.joysticks.end()) {
if (cfg.js_iter != cfg.joysticks.end())
{
if (!SaveSetting(dev_type, port, apiname, N_JOYSTICK, cfg.js_iter->second))
ret = RESULT_FAILED;
}
@ -619,7 +647,8 @@ int GtkPadConfigure(int port, const char* dev_type, const char *apititle, const
for (auto& it : cfg.jsconf)
SaveMappings(dev_type, port, it.first, it.second);
if (is_evdev) {
if (is_evdev)
{
SaveSetting(dev_type, port, apiname, N_HIDRAW_FF_PT, cfg.use_hidraw_ff_pt);
}
}
@ -638,7 +667,8 @@ GtkWidget * make_color_icon(uint32_t rgb)
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 24, 24);
guchar* data = gdk_pixbuf_get_pixels(pixbuf);
for (size_t i=0; i<24*24; i++) {
for (size_t i = 0; i < 24 * 24; i++)
{
data[i * 4 + 0] = rgb & 0xFF;
data[i * 4 + 1] = (rgb >> 8) & 0xFF;
data[i * 4 + 2] = (rgb >> 16) & 0xFF;
@ -667,14 +697,16 @@ int GtkBuzzConfigure(int port, const char* dev_type, const char *apititle, const
cfg.cb = &apicbs;
cfg.dev_type = dev_type;
for (const auto& it: cfg.joysticks) {
for (const auto& it : cfg.joysticks)
{
if ((fd = open(it.second.c_str(), O_RDONLY | O_NONBLOCK)) < 0)
{
OSDebugOut("Cannot open device: %s\n", it.second.c_str());
continue;
}
ConfigMapping c; c.fd = fd;
ConfigMapping c;
c.fd = fd;
LoadBuzzMappings(cfg.dev_type, port, it.first, c);
cfg.jsconf.push_back(std::make_pair(it.first, c));
OSDebugOut("mappings for '%s': %lu\n", it.first.c_str(), c.controls.size());
@ -779,7 +811,8 @@ int GtkBuzzConfigure(int port, const char* dev_type, const char *apititle, const
0x00FFFF,
};
for (int j=0; j < 4; j++) {
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < countof(button_labels); i++)
{
GtkWidget* button = gtk_button_new_with_label(button_labels[i]);
@ -817,7 +850,6 @@ int GtkBuzzConfigure(int port, const char* dev_type, const char *apititle, const
2, 3, 0, 1, opt, opt, 5, 1);
gtk_table_attach(GTK_TABLE(table), gtk_label_new("Player 4"),
3, 4, 0, 1, opt, opt, 5, 1);
}
GtkWidget* hbox = gtk_hbox_new(false, 5);
@ -833,14 +865,14 @@ int GtkBuzzConfigure(int port, const char* dev_type, const char *apititle, const
int ret = RESULT_OK;
if (result == GTK_RESPONSE_OK)
{
if (cfg.js_iter != cfg.joysticks.end()) {
if (cfg.js_iter != cfg.joysticks.end())
{
if (!SaveSetting(dev_type, port, apiname, N_JOYSTICK, cfg.js_iter->second))
ret = RESULT_FAILED;
}
for (auto& it : cfg.jsconf)
SaveBuzzMappings(dev_type, port, it.first, it.second);
}
else
ret = RESULT_CANCELED;
@ -852,4 +884,5 @@ int GtkBuzzConfigure(int port, const char* dev_type, const char *apititle, const
return ret;
}
}} //namespace
} // namespace evdev
} // namespace usb_pad

View File

@ -25,7 +25,10 @@
typedef std::vector<std::pair<std::string, std::string>> vstring;
GtkWidget* new_combobox(const char* label, GtkWidget* vbox);
namespace usb_pad { namespace evdev {
namespace usb_pad
{
namespace evdev
{
enum
{
@ -50,7 +53,8 @@ enum JoystickMap
JOY_L2,
JOY_SELECT,
JOY_START,
JOY_R3, JOY_L3, //order, afaik not used on any PS2 wheel anyway
JOY_R3,
JOY_L3, //order, afaik not used on any PS2 wheel anyway
JOY_DOWN,
JOY_LEFT,
JOY_UP,
@ -80,8 +84,7 @@ static const char* JoystickMapNames [] = {
"right",
"steering",
"throttle",
"brake"
};
"brake"};
static const char* buzz_map_names[] = {
"red",
@ -91,7 +94,12 @@ static const char* buzz_map_names[] = {
"blue",
};
struct Point { int x; int y; JoystickMap type; };
struct Point
{
int x;
int y;
JoystickMap type;
};
struct ConfigMapping
{
@ -137,7 +145,6 @@ struct device_data
bool is_gamepad; //xboxish gamepad
bool is_dualanalog; // tricky, have to read the AXIS_RZ somehow and
// determine if its unpressed value is zero
};
int GtkPadConfigure(int port, const char* dev_type, const char* title, const char* apiname, GtkWindow* parent, ApiCallbacks& apicbs);
@ -146,4 +153,5 @@ bool LoadMappings(const char *dev_type, int port, const std::string& joyname, Co
bool SaveMappings(const char* dev_type, int port, const std::string& joyname, const ConfigMapping& cfg);
bool LoadBuzzMappings(const char* dev_type, int port, const std::string& joyname, ConfigMapping& cfg);
bool SaveBuzzMappings(const char* dev_type, int port, const std::string& joyname, const ConfigMapping& cfg);
}} //namespace
} // namespace evdev
} // namespace usb_pad

View File

@ -22,7 +22,10 @@
#include <sstream>
#include "../../gtk.h"
namespace usb_pad { namespace joydev {
namespace usb_pad
{
namespace joydev
{
using sys_clock = std::chrono::system_clock;
using ms = std::chrono::milliseconds;
@ -33,9 +36,12 @@ using ms = std::chrono::milliseconds;
static bool GetEventName(const char* dev_type, int map, int event, const char** name)
{
static char buf[256] = {0};
if (map < evdev::JOY_STEERING) {
if (map < evdev::JOY_STEERING)
{
snprintf(buf, sizeof(buf), "Button %d", event);
} else {
}
else
{
// assuming that PS2 axes are always mapped to PC axes
snprintf(buf, sizeof(buf), "Axis %d", event);
}
@ -53,34 +59,45 @@ static bool PollInput(const std::vector<std::pair<std::string, usb_pad::evdev::C
int maxfd = -1;
FD_ZERO(&fdset);
for (const auto& js: fds) {
for (const auto& js : fds)
{
FD_SET(js.second.fd, &fdset);
if (maxfd < js.second.fd) maxfd = js.second.fd;
if (maxfd < js.second.fd)
maxfd = js.second.fd;
}
inverted = false;
// empty event queues
for (const auto& js : fds)
while ((len = read(js.second.fd, &event, sizeof(event))) > 0);
while ((len = read(js.second.fd, &event, sizeof(event))) > 0)
;
struct axis_value { int16_t value; bool initial; };
struct axis_value
{
int16_t value;
bool initial;
};
axis_value axisVal[ABS_MAX + 1] = {0};
struct timeval timeout {};
struct timeval timeout
{
};
timeout.tv_sec = 5;
int result = select(maxfd + 1, &fdset, NULL, NULL, &timeout);
if (!result)
return false;
if (result == -1) {
if (result == -1)
{
return false;
}
for (const auto& js : fds)
{
if (FD_ISSET(js.second.fd, &fdset)) {
if (FD_ISSET(js.second.fd, &fdset))
{
event_fd = js.second.fd;
dev_name = js.first;
break;
@ -95,7 +112,8 @@ static bool PollInput(const std::vector<std::pair<std::string, usb_pad::evdev::C
while (true)
{
auto dur = std::chrono::duration_cast<ms>(sys_clock::now() - last).count();
if (dur > 5000) goto error;
if (dur > 5000)
goto error;
if ((len = read(event_fd, &event, sizeof(event))) > -1 && (len == sizeof(event)))
{
@ -112,7 +130,8 @@ static bool PollInput(const std::vector<std::pair<std::string, usb_pad::evdev::C
{
int diff = event.value - val.value;
OSDebugOut("Axis %d value: %d, difference: %d\n", event.number, event.value, diff);
if (std::abs(diff) > 2047) {
if (std::abs(diff) > 2047)
{
value = event.number;
inverted = (diff < 0);
initial = val.value;
@ -158,4 +177,5 @@ int JoyDevPad::Configure(int port, const char* dev_type, void *data)
return ret;
}
}} //namespace
} // namespace joydev
} // namespace usb_pad

View File

@ -19,7 +19,10 @@
#include <sstream>
#include "../../linux/util.h"
namespace usb_pad { namespace joydev {
namespace usb_pad
{
namespace joydev
{
using namespace evdev;
@ -36,22 +39,26 @@ void EnumerateDevices(vstring& list)
struct dirent* dp;
DIR* dirp = opendir("/dev/input/");
if (!dirp) {
if (!dirp)
{
perror("Error opening /dev/input/");
return;
}
while ((dp = readdir(dirp)))
{
if (strncmp(dp->d_name, "js", 2) == 0) {
if (strncmp(dp->d_name, "js", 2) == 0)
{
OSDebugOut("%s\n", dp->d_name);
str.clear(); str.str("");
str.clear();
str.str("");
str << "/dev/input/" << dp->d_name;
const std::string& path = str.str();
fd = open(path.c_str(), O_RDONLY | O_NONBLOCK);
if (fd < 0) {
if (fd < 0)
{
perror("Unable to open device");
continue;
}
@ -84,22 +91,26 @@ int JoyDevPad::TokenIn(uint8_t *buf, int buflen)
FD_ZERO(&fds);
maxfd = -1;
for (auto& device: mDevices) {
for (auto& device : mDevices)
{
FD_SET(device.cfg.fd, &fds);
if (maxfd < device.cfg.fd) maxfd = device.cfg.fd;
if (maxfd < device.cfg.fd)
maxfd = device.cfg.fd;
}
struct timeval timeout;
timeout.tv_usec = timeout.tv_sec = 0; // 0 - return from select immediately
int result = select(maxfd + 1, &fds, NULL, NULL, &timeout);
if (result <= 0) {
if (result <= 0)
{
return USB_RET_NAK; // If no new data, NAK it
}
for (auto& device : mDevices)
{
if (!FD_ISSET(device.cfg.fd, &fds)) {
if (!FD_ISSET(device.cfg.fd, &fds))
{
continue;
}
@ -117,8 +128,12 @@ int JoyDevPad::TokenIn(uint8_t *buf, int buflen)
switch (device.axis_map[event.number])
{
case 0x80 | JOY_STEERING:
case ABS_X: mWheelData.steering = device.cfg.inverted[0] ? range - NORM(event.value, range) : NORM(event.value, range); break;
case ABS_Y: mWheelData.clutch = NORM(event.value, 0xFF); break;
case ABS_X:
mWheelData.steering = device.cfg.inverted[0] ? range - NORM(event.value, range) : NORM(event.value, range);
break;
case ABS_Y:
mWheelData.clutch = NORM(event.value, 0xFF);
break;
//case ABS_RX: mWheelData.axis_rx = NORM(event.value, 0xFF); break;
case ABS_RY:
treat_me_like_ABS_RY:
@ -169,7 +184,8 @@ int JoyDevPad::TokenIn(uint8_t *buf, int buflen)
else
mWheelData.hat_vert = PAD_HAT_COUNT;
break;
default: break;
default:
break;
}
}
else if ((event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON)
@ -205,16 +221,36 @@ int JoyDevPad::TokenIn(uint8_t *buf, int buflen)
case 0x8000 | JOY_DOWN:
mWheelData.hat_vert = PAD_HAT_S;
break;
case BTN_WEST: button = PAD_SQUARE; break;
case BTN_NORTH: button = PAD_TRIANGLE; break;
case BTN_EAST: button = PAD_CIRCLE; break;
case BTN_SOUTH: button = PAD_CROSS; break;
case BTN_SELECT: button = PAD_SELECT; break;
case BTN_START: button = PAD_START; break;
case BTN_TR: button = PAD_R1; break;
case BTN_TL: button = PAD_L1; break;
case BTN_THUMBR: button = PAD_R2; break;
case BTN_THUMBL: button = PAD_L2; break;
case BTN_WEST:
button = PAD_SQUARE;
break;
case BTN_NORTH:
button = PAD_TRIANGLE;
break;
case BTN_EAST:
button = PAD_CIRCLE;
break;
case BTN_SOUTH:
button = PAD_CROSS;
break;
case BTN_SELECT:
button = PAD_SELECT;
break;
case BTN_START:
button = PAD_START;
break;
case BTN_TR:
button = PAD_R1;
break;
case BTN_TL:
button = PAD_L1;
break;
case BTN_THUMBR:
button = PAD_R2;
break;
case BTN_THUMBL:
button = PAD_L2;
break;
default:
OSDebugOut("Unmapped Button: %d, %d\n", event.number, event.value);
break;
@ -244,17 +280,29 @@ int JoyDevPad::TokenIn(uint8_t *buf, int buflen)
case PAD_HAT_N:
switch (mWheelData.hat_horz)
{
case PAD_HAT_W: mWheelData.hatswitch = PAD_HAT_NW; break;
case PAD_HAT_E: mWheelData.hatswitch = PAD_HAT_NE; break;
default: mWheelData.hatswitch = PAD_HAT_N; break;
case PAD_HAT_W:
mWheelData.hatswitch = PAD_HAT_NW;
break;
case PAD_HAT_E:
mWheelData.hatswitch = PAD_HAT_NE;
break;
default:
mWheelData.hatswitch = PAD_HAT_N;
break;
}
break;
case PAD_HAT_S:
switch (mWheelData.hat_horz)
{
case PAD_HAT_W: mWheelData.hatswitch = PAD_HAT_SW; break;
case PAD_HAT_E: mWheelData.hatswitch = PAD_HAT_SE; break;
default: mWheelData.hatswitch = PAD_HAT_S; break;
case PAD_HAT_W:
mWheelData.hatswitch = PAD_HAT_SW;
break;
case PAD_HAT_E:
mWheelData.hatswitch = PAD_HAT_SE;
break;
default:
mWheelData.hatswitch = PAD_HAT_S;
break;
}
break;
default:
@ -342,13 +390,17 @@ int JoyDevPad::Open()
}
else
{
if (ioctl(device.cfg.fd, JSIOCGAXES, &(count)) >= 0) {
if (ioctl(device.cfg.fd, JSIOCGAXES, &(count)) >= 0)
{
for (int i = 0; i < count; ++i)
OSDebugOut("Axis: %d -> %d\n", i, device.axis_map[i]);
for (int k = 0; k < count; k++) {
for (int i = JOY_STEERING; i < JOY_MAPS_COUNT; i++) {
if (k == device.cfg.controls[i]) {
for (int k = 0; k < count; k++)
{
for (int i = JOY_STEERING; i < JOY_MAPS_COUNT; i++)
{
if (k == device.cfg.controls[i])
{
device.axis_map[k] = 0x80 | i;
if (i == JOY_STEERING)
has_steering = true;
@ -366,7 +418,8 @@ int JoyDevPad::Open()
}
else
{
if (ioctl(device.cfg.fd, JSIOCGBUTTONS, &(count)) >= 0) {
if (ioctl(device.cfg.fd, JSIOCGBUTTONS, &(count)) >= 0)
{
for (int i = 0; i < count; ++i)
{
OSDebugOut("Button: %d -> %d BTN_[GAMEPAD|SOUTH]: %d\n", i, device.btn_map[i], device.btn_map[i] == BTN_GAMEPAD);
@ -375,8 +428,10 @@ int JoyDevPad::Open()
}
if (!device.is_gamepad) //TODO Don't remap if gamepad?
for (int k = 0; k < count; k++) {
for (int i = 0; i < JOY_STEERING; i++) {
for (int k = 0; k < count; k++)
{
for (int i = 0; i < JOY_STEERING; i++)
{
if (k == device.cfg.controls[i])
device.btn_map[k] = 0x8000 | i;
}
@ -396,18 +451,22 @@ int JoyDevPad::Open()
//TODO kernel limit is 32?
for (int j = 0; j <= 99; j++)
{
event.clear(); event.str(std::string());
event.clear();
event.str(std::string());
/* Try to discover the corresponding event number */
event << "/sys/class/input/js" << index << "/device/event" << j;
if (dir_exists(event.str())){
if (dir_exists(event.str()))
{
event.clear(); event.str(std::string());
event.clear();
event.str(std::string());
event << "/dev/input/event" << j;
break;
}
}
if (!mFFdev && has_steering) {
if (!mFFdev && has_steering)
{
if ((mHandleFF = open(event.str().c_str(), /*O_WRONLY*/ O_RDWR)) < 0)
{
OSDebugOut("%s: Cannot open '%s'\n", APINAME, event.str().c_str());
@ -433,11 +492,13 @@ int JoyDevPad::Close()
close(mHandleFF);
mHandleFF = -1;
for (auto& it : mDevices) {
for (auto& it : mDevices)
{
close(it.cfg.fd);
it.cfg.fd = -1;
}
return 0;
}
}} //namespace
} // namespace joydev
} // namespace usb_pad

View File

@ -18,7 +18,10 @@
#include "../evdev/evdev-ff.h"
#include "../evdev/shared.h"
namespace usb_pad { namespace joydev {
namespace usb_pad
{
namespace joydev
{
void EnumerateDevices(vstring& list);
@ -27,7 +30,8 @@ static const char *APINAME = "joydev";
class JoyDevPad : public Pad
{
public:
JoyDevPad(int port, const char* dev_type): Pad(port, dev_type)
JoyDevPad(int port, const char* dev_type)
: Pad(port, dev_type)
{
}
@ -44,6 +48,7 @@ public:
}
static int Configure(int port, const char* dev_type, void* data);
protected:
int mHandleFF;
struct wheel_data_t mWheelData;
@ -72,4 +77,5 @@ bool GetJoystickName(const std::string& path, char (&name)[_Size])
return false;
}
}} //namespace
} // namespace joydev
} // namespace usb_pad

View File

@ -5,7 +5,8 @@
#include "lg_ff.h"
typedef struct {
typedef struct
{
unsigned char num;
unsigned char den;
} s_coef;
@ -18,18 +19,25 @@ typedef struct {
*
* \return the force coefficient
*/
static s_coef ff_lg_get_force_coefficient(uint8_t caps, unsigned char k) {
static s_coef ff_lg_get_force_coefficient(uint8_t caps, unsigned char k)
{
s_coef coef;
if (caps & FF_LG_CAPS_HIGH_RES_COEF) {
if (caps & FF_LG_CAPS_HIGH_RES_COEF)
{
coef.num = k;
coef.den = 0x0F;
} else {
if (caps & FF_LG_CAPS_OLD_LOW_RES_COEF) {
}
else
{
if (caps & FF_LG_CAPS_OLD_LOW_RES_COEF)
{
static const s_coef old_coefs[] = {{1, 16}, {1, 8}, {3, 16}, {1, 4}, {3, 8}, {3, 4}, {2, 4}, {4, 4}};
coef = old_coefs[k];
} else {
}
else
{
static const s_coef coefs[] = {{1, 16}, {1, 8}, {3, 16}, {1, 4}, {3, 8}, {2, 4}, {3, 4}, {4, 4}};
coef = coefs[k];
}
@ -37,30 +45,39 @@ static s_coef ff_lg_get_force_coefficient(uint8_t caps, unsigned char k) {
return coef;
}
int16_t ff_lg_get_condition_coef(uint8_t caps, unsigned char k, unsigned char s, int16_t max /*= SHRT_MAX*/) {
int16_t ff_lg_get_condition_coef(uint8_t caps, unsigned char k, unsigned char s, int16_t max /*= SHRT_MAX*/)
{
s_coef coef = ff_lg_get_force_coefficient(caps, k);
int value = (s ? -max : max) * coef.num / coef.den;
return value;
}
uint16_t ff_lg_get_spring_deadband(uint8_t caps, unsigned char d, unsigned char dL, uint16_t max /*= USHRT_MAX*/) {
uint16_t ff_lg_get_spring_deadband(uint8_t caps, unsigned char d, unsigned char dL, uint16_t max /*= USHRT_MAX*/)
{
uint16_t deadband;
if (caps & FF_LG_CAPS_HIGH_RES_DEADBAND) {
if (caps & FF_LG_CAPS_HIGH_RES_DEADBAND)
{
deadband = ((d << 3) | dL) * max / 0x7FF;
} else {
}
else
{
deadband = d * max / UCHAR_MAX;
}
return deadband;
}
uint16_t ff_lg_get_damper_clip(uint8_t caps, unsigned char c) {
uint16_t ff_lg_get_damper_clip(uint8_t caps, unsigned char c)
{
uint16_t clip;
if (caps & FF_LG_CAPS_DAMPER_CLIP) {
if (caps & FF_LG_CAPS_DAMPER_CLIP)
{
clip = c * USHRT_MAX / UCHAR_MAX;
} else {
}
else
{
clip = USHRT_MAX;
}
return clip;

View File

@ -18,23 +18,28 @@
*
* input values 127 and 128 are center positions and are translated to output value 0
*/
static inline int16_t ff_lg_u8_to_s16(uint8_t c, int16_t max = SHRT_MAX) {
static inline int16_t ff_lg_u8_to_s16(uint8_t c, int16_t max = SHRT_MAX)
{
// 127 and 128 are center positions
if (c < 128) {
if (c < 128)
{
++c;
}
int value = (c - 128) * max / 127;
return value;
}
static inline uint16_t ff_lg_u8_to_u16(uint8_t c, uint16_t max = USHRT_MAX) {
static inline uint16_t ff_lg_u8_to_u16(uint8_t c, uint16_t max = USHRT_MAX)
{
return c * max / UCHAR_MAX;
}
static inline int16_t ff_lg_u16_to_s16(uint16_t s) {
static inline int16_t ff_lg_u16_to_s16(uint16_t s)
{
// 32767 and 32768 are center positions
int value = s - 32768;
if (value < 0) {
if (value < 0)
{
++value;
}
return value;

View File

@ -25,12 +25,16 @@
#include "../helpers.h"
#include "../deviceproxy.h"
namespace usb_pad {
namespace usb_pad
{
class PadError : public std::runtime_error
{
public:
PadError(const char* msg) : std::runtime_error(msg) {}
PadError(const char* msg)
: std::runtime_error(msg)
{
}
virtual ~PadError() {}
};
@ -80,5 +84,5 @@ class RegisterPad : public RegisterProxy<PadProxyBase>
static void Register();
};
} //namespace
} // namespace usb_pad
#endif

View File

@ -30,7 +30,10 @@
extern HINSTANCE hInst;
#define MSG_PRESS_ESC(wnd) SendDlgItemMessageW(wnd, IDC_STATIC_CAP, WM_SETTEXT, 0, (LPARAM)L"Capturing, press ESC to cancel")
namespace usb_pad { namespace raw {
namespace usb_pad
{
namespace raw
{
inline bool MapExists(const MapVector& maps, const std::wstring& hid)
{
@ -51,8 +54,7 @@ void LoadMappings(const char *dev_type, MapVector& maps)
std::wstring hid, tmp;
//swprintf_s(sec, TEXT("%S RAW DEVICE %d"), dev_type, j++);
if(LoadSetting(dev_type, j, "RAW DEVICE", _T("HID"), hid)
&& !hid.empty() && !MapExists(maps, hid))
if (LoadSetting(dev_type, j, "RAW DEVICE", _T("HID"), hid) && !hid.empty() && !MapExists(maps, hid))
{
Mappings m;
ZeroMemory(&m, sizeof(Mappings));
@ -145,8 +147,7 @@ const char *BTN2TXT[] = {
"Select",
"Start",
"R3",
"L3"
};
"L3"};
const char* AXIS2TXT[] = {
"Axis X",
@ -155,8 +156,7 @@ const char *AXIS2TXT[] = {
//"Axis RX",
//"Axis RY",
"Axis RZ",
"Hat Switch"
};
"Hat Switch"};
void resetState(HWND hW);
HWND dgHwnd = NULL;
@ -170,7 +170,8 @@ typedef struct _DevInfo
int ply;
RID_DEVICE_INFO_HID hid;
bool operator==(const _DevInfo &t) const{
bool operator==(const _DevInfo& t) const
{
if (ply == t.ply && hid.dwProductId == t.hid.dwProductId &&
hid.dwVendorId == t.hid.dwVendorId &&
hid.dwVersionNumber == t.hid.dwVersionNumber &&
@ -180,11 +181,16 @@ typedef struct _DevInfo
return false;
}
bool operator<(const _DevInfo &t) const{
if(ply < t.ply) return true;
if(hid.dwProductId < t.hid.dwProductId) return true;
if(hid.dwVendorId < t.hid.dwVendorId) return true;
if(hid.dwVersionNumber < t.hid.dwVersionNumber) return true;
bool operator<(const _DevInfo& t) const
{
if (ply < t.ply)
return true;
if (hid.dwProductId < t.hid.dwProductId)
return true;
if (hid.dwVendorId < t.hid.dwVendorId)
return true;
if (hid.dwVersionNumber < t.hid.dwVersionNumber)
return true;
return false;
}
@ -230,7 +236,8 @@ void populate(HWND hW, RawDlgConfig *cfg)
HidD_GetHidGuid(&guid);
devInfo = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_DEVICEINTERFACE);
if(!devInfo) return;
if (!devInfo)
return;
diData.cbSize = sizeof(diData);
@ -268,7 +275,8 @@ void populate(HWND hW, RawDlgConfig *cfg)
SendDlgItemMessageA(hW, IDC_COMBO_FFB, CB_ADDSTRING, 0, (LPARAM) "None");
SendDlgItemMessage(hW, IDC_COMBO_FFB, CB_SETCURSEL, 0, 0);
while(SetupDiEnumDeviceInterfaces(devInfo, 0, &guid, i, &diData)){
while (SetupDiEnumDeviceInterfaces(devInfo, 0, &guid, i, &diData))
{
if (usbHandle != INVALID_HANDLE_VALUE)
CloseHandle(usbHandle);
@ -278,7 +286,8 @@ void populate(HWND hW, RawDlgConfig *cfg)
if (!didData)
break;
didData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if(!SetupDiGetDeviceInterfaceDetail(devInfo, &diData, didData, needed, 0, 0)){
if (!SetupDiGetDeviceInterfaceDetail(devInfo, &diData, didData, needed, 0, 0))
{
free(didData);
break;
}
@ -286,7 +295,8 @@ void populate(HWND hW, RawDlgConfig *cfg)
usbHandle = CreateFile(didData->DevicePath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if(usbHandle == INVALID_HANDLE_VALUE){
if (usbHandle == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Could not open device %i\n", i);
free(didData);
i++;
@ -432,7 +442,6 @@ void populateMappings(HWND hW)
}
}
}
}
static void ParseRawInput(PRAWINPUT pRawInput, HWND hW)
@ -497,13 +506,16 @@ static void ParseRawInput(PRAWINPUT pRawInput, HWND hW)
mapping->hidPath = devName;
}
//TODO get real dev name, probably from registry (see lilypad)
if(!mapping->devName.length()) mapping->devName = devName;
if (!mapping->devName.length())
mapping->devName = devName;
if (devInfo.dwType == RIM_TYPEKEYBOARD &&
(pRawInput->data.keyboard.Flags & RI_KEY_BREAK) != RI_KEY_BREAK)
{
if(pRawInput->data.keyboard.VKey == 0xff) return; //TODO
if(pRawInput->data.keyboard.VKey == VK_ESCAPE) {
if (pRawInput->data.keyboard.VKey == 0xff)
return; //TODO
if (pRawInput->data.keyboard.VKey == VK_ESCAPE)
{
resetState(hW);
return;
}
@ -549,8 +561,7 @@ static void ParseRawInput(PRAWINPUT pRawInput, HWND hW)
CHECK(
HidP_GetUsages(
HidP_Input, pButtonCaps->UsagePage, 0, usage, &usageLength, pPreparsedData,
(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid
) == HIDP_STATUS_SUCCESS );
(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid) == HIDP_STATUS_SUCCESS);
if (usageLength > 0) //Using first button only though
{
@ -578,8 +589,7 @@ static void ParseRawInput(PRAWINPUT pRawInput, HWND hW)
CHECK(
HidP_GetUsageValue(
HidP_Input, pValueCaps[i].UsagePage, 0, pValueCaps[i].Range.UsageMin, &value, pPreparsedData,
(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid
) == HIDP_STATUS_SUCCESS );
(PCHAR)pRawInput->data.hid.bRawData, pRawInput->data.hid.dwSizeHid) == HIDP_STATUS_SUCCESS);
uint32_t logical = pValueCaps[i].LogicalMax - pValueCaps[i].LogicalMin;
@ -610,7 +620,8 @@ static void ParseRawInput(PRAWINPUT pRawInput, HWND hW)
break;
case 0x39: // Hat Switch
if (value < 0x8) {
if (value < 0x8)
{
mapping->axisMap[6] = PLY_SET_MAPPED(plyCapturing, axisCapturing);
axisPass2 = false;
OSDebugOut(TEXT("Selected hat switch\n"));
@ -665,18 +676,21 @@ static void Register(HWND hW)
rid[2].dwFlags = hW ? RIDEV_INPUTSINK /*| RIDEV_NOLEGACY*/ : RIDEV_REMOVE; // adds HID keyboard and also ignores legacy keyboard messages
rid[2].hwndTarget = hW;
if (!RegisterRawInputDevices(rid, 3, sizeof(rid[0]))) {
if (!RegisterRawInputDevices(rid, 3, sizeof(rid[0])))
{
SendDlgItemMessage(hW, IDC_STATIC_CAP, WM_SETTEXT, 0, (LPARAM)TEXT("Could not register raw input devices."));
}
}
INT_PTR CALLBACK ConfigureRawDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
INT_PTR CALLBACK ConfigureRawDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TCHAR buf[256];
LVITEM lv;
RawDlgConfig* cfg = (RawDlgConfig*)GetWindowLongPtr(hW, GWLP_USERDATA);
int ret = 0;
switch(uMsg) {
switch (uMsg)
{
case WM_INITDIALOG:
if (!InitHid())
return FALSE;
@ -795,7 +809,8 @@ INT_PTR CALLBACK ConfigureRawDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM l
LOWORD(wParam) >= IDC_BUTTON13 &&
LOWORD(wParam) <= IDC_BUTTON16)
{
switch (LOWORD(wParam)) {
switch (LOWORD(wParam))
{
case IDC_BUTTON13:
hatCapturing = PAD_HAT_N;
break;
@ -813,7 +828,8 @@ INT_PTR CALLBACK ConfigureRawDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM l
SetTimer(hW, 1, 5000, nullptr);
}
switch(LOWORD(wParam)) {
switch (LOWORD(wParam))
{
case IDC_DFP_PASS:
cfg->pt[plyCapturing] = IsDlgButtonChecked(hW, IDC_DFP_PASS) > 0;
break;
@ -821,10 +837,12 @@ INT_PTR CALLBACK ConfigureRawDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM l
int sel;
HWND lhW;
lhW = GetDlgItem(hW, IDC_LIST1);
while (1) {
while (1)
{
ZeroMemory(&lv, sizeof(LVITEM));
sel = ListView_GetNextItem(lhW, -1, LVNI_SELECTED);
if (sel < 0) break;
if (sel < 0)
break;
lv.iItem = sel;
lv.mask = LVIF_PARAM;
ListView_GetItem(lhW, &lv);
@ -850,7 +868,8 @@ INT_PTR CALLBACK ConfigureRawDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM l
case IDC_BUTTON11: //L3
case IDC_BUTTON12: //R3
if (axisCapturing == PAD_AXIS_COUNT &&
hatCapturing == PAD_HAT_COUNT) {
hatCapturing == PAD_HAT_COUNT)
{
btnCapturing = (PS2Buttons)(LOWORD(wParam) - IDC_BUTTON1);
MSG_PRESS_ESC(hW);
SetTimer(hW, 1, 5000, nullptr);
@ -862,7 +881,8 @@ INT_PTR CALLBACK ConfigureRawDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM l
case IDC_BUTTON20: //rz
case IDC_BUTTON21: //hat
if (btnCapturing == PAD_BUTTON_COUNT &&
hatCapturing == PAD_HAT_COUNT) {
hatCapturing == PAD_HAT_COUNT)
{
axisCapturing = (PS2Axis)(LOWORD(wParam) - IDC_BUTTON17);
swprintf_s(buf, TEXT("Capturing for axis %u, press ESC to cancel"), axisCapturing);
SendDlgItemMessage(hW, IDC_STATIC_CAP, WM_SETTEXT, 0, (LPARAM)buf);
@ -901,10 +921,10 @@ INT_PTR CALLBACK ConfigureRawDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM l
return TRUE;
}
}
}
return S_OK; //DefWindowProc(hW, uMsg, wParam, lParam);
}
}} //namespace
} // namespace raw
} // namespace usb_pad

Some files were not shown because too many files have changed in this diff Show More